Generate OpenAPISchema objects from C# POCOs
Can we create a mechanism to generate Schemas from C# classes?
https://github.com/dotnet/aspnetcore/issues/41246
@JamesNK and I talked schema generation today and he shared some helpful insights on this domain. Notes from the discussion below:
- In the context of OpenAPI, schemas exist outside the scope of a particular operation. The same Type/Schema can be used in different operations. As we reason through this, we should consider that the schema generation will need to happen independent of the operation model.
- Schema generation is impacted by runtime behavior, particularly how JSON serializers are configured in the user application. For example, the user might leverage the
JsonSerializerOptions.PropertyNamingPolicyto indicate whether property keys should be camel-cased or pascal-cased or insert-whatever-modification-here. The generator will need to be able to introspect these settings and respect them when generating property keys in the OpenAPI schema. - Users can also define custom JSON converters for a given type. For example, a
Todotype that would typically serialized as an object can be overridden to serialize to just a string. The generator will need to respect these overrides.
We also discussed some features that might be helpful for the work that James is doing around gRPC + REST APIs + OpenAPI, particularly being able to provide global overrides for how different JSON schema types (primitives, objects, arrays, etc.) should have their serializations configured.
Let me know if I missed anything key, @JamesNK...
In the context of OpenAPI, schemas exist outside the scope of a particular operation. The same Type/Schema can be used in different operations. As we reason through this, we should consider that the schema generation will need to happen independent of the operation model.
Another key thing here is schemas aren't isolated. Schemas are reused and they reference each other. OpenApiSchema SchemaGenerator.Generate(Type type) isn't sufficient.
For this to work I imagine:
- You would need a higher-level view of a model, which has a collection of
System.Typeinstances an operation will use (in and out). - These types are then registered with a schema generator.
- Once all types are registered then generation happens. Internally the generation will probably have mapping between type and generated model, e.g.
Dictionary<Type, OpenApiSchema>. - Something then instructs the schema generate to adds the generated schemas to the OpenAPI doc (is
components.schemasa standard place?) and then goes through the operations and adds references to the schemas incomponents.schemasbased on the type.
Our plans to support OpenAPI 3.1 currently involve changing our OpenAPISchema object to use a third-party JSONSchema library. We should not do this work until we have added OpenAPI 3.1 support or we will have to do the work twice.