Our team has some past experience using the OpenAPI document and code generation tools (https://openapi-generator.tech/) to generate Tessitura API clients. Upon beginning to test v16 and the OpenAPI 3.0 document, I noticed the following issues that I'm hoping can be addressed in the near future:
Existing issues present in both 2.0/v15.x and 3.0/v16
1. In the request body and response body of all API operations, all object properties are PascalCase. However, the OpenAPI document has all of the object schemas defining all properties as camelCase instead. Because of this, currently additional work must be done to correct this, either in the document itself at generation time or at runtime in an object translation layer.
2. Most object properties are defined as optional, even though in practice all response bodies will include all properties even if they are null or empty. Because the object schemas define most properties as optional, the generated interfaces are more difficult to work with because even basic properties like entity IDs need to null-protected with a default (i.e "return performance.id ?? 0") to pass type validation. I realize this may be challenging to solve, since some objects are used both as a response object where all properties are present and also as a request object where partial data is acceptable. I might be able to find a workaround in our cases by wrapping all of the response objects in a utility type that recursively requires all members, but it would still be better if the schema objects were more explicit in their definition.
New issues in 3.0/v16
1. While the 2.0 document correctly began all paths with the beginning of the unique resource (i.e. /CRM/ElectronicAddresses), the 3.0 document begins all paths with "/api" (i.e /api/CRM/ElectronicAddresses). This causes generation tools to add "api" to all the generated function names in the client.
2. The 3.0 document does not yet include the "operationId" property of any paths, as the 2.0 document did. The operationId is important to generating meaningful but concise function names in the client. For example, the 2.0 generated function name for /CRM/ElectronicAddresses/{electronicAddressId} would be "electronicAddressesGet()" because the operation Id was "ElectronicAddresses_Get". In 3.0, without that property, that same path will generate a name based purely on the path itself: "apiCrmElectronicAddressesElectronicAddressId()". Although sometimes the operationIds in 2.0 were not ideal names, in general it was consistent and readable.