Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide mechanisms for users to register own types and format #364

Closed
msavy opened this issue Jul 17, 2019 · 17 comments · Fixed by #403
Closed

Provide mechanisms for users to register own types and format #364

msavy opened this issue Jul 17, 2019 · 17 comments · Fixed by #403

Comments

@msavy
Copy link

msavy commented Jul 17, 2019

As discussed in the latest hangout (and related to smallrye/smallrye-open-api#147)

It would be useful to have a mechanism that allows users to:

For example, this could be as simple as:
mp.openapi.extensions.type-format.FQCN=SchemaType,DataFormat

So you could map your custom date type to the correct SchemaType and DataFormat.

  • As suggested by @EricWittmann in the the meeting was that we may also want to consider a more advanced mechanism that allows a schema to be mapped to a particular object (i.e. for cases where it's not simply about primitives). Eric mentioned the recent SmallRye Custom Schema Registry (https://github.com/smallrye/smallrye-open-api/pull/126/files) as a possible model.

  • I suggested that (in addition to config-driven), a programmatic interface might be beneficial, in allowing runtimes to inject certain mapping information they already know about (e.g. for some type that a framework commonly provides).

There are some parallels here with the way that Jackson works -- they have a large number of converters OOTB that take (e.g. Map, Simple Java Bean, List, Date) and convert it into something sensible in JSON. However, if you provide your own complex data structure you need to provide your own converter and/or mapping.

@msavy
Copy link
Author

msavy commented Jul 17, 2019

Creating this ticket to open up the discussion and facilitate some possible "pre-standardisation" if we go for a config-based approach (i.e. let's use the same format!)

@MikeEdgar
Copy link
Member

Besides configuration, another way this could be supported was discussed in smallrye/smallrye-open-api#125 (where a programmatic SPI approach was adopted).

Where the following MP config property could be used to customize a date format:
mp.openapi.extensions.type-format.java.util.Date=STRING,DATE_TIME

The equivalent annotation-based approach could be as follows:

@OpenAPIDefinition(
    info = @Info(
        title = "My API",
        version = "1.0"),
    components = @Components(
        schemas = {
            @Schema(
                name = "Date",
                type = SchemaType.STRING,
                format = DataFormat.DATE_TIME,
                implementation = java.util.Date.class)
        }
    )
)
class MyApplication extends Application { ... }

It may or may not be intuitive that all instances of java.util.Date are affected, unless overridden with their own @Schema annotations.

@arthurdm
Copy link
Member

Would it be a bad approach to say that at a spec level the OASFilter interface (in particular, the method that takes a Schema obj) could be used for this sort of customization?

My fear is that implementations could already have a way to customize the Java types that they process, perhaps by virtue of the frameworks they're leveraging to carry out the processing, so we could get into impl vs spec conflicts.

@MikeEdgar
Copy link
Member

My thought on this is that using the OASFilter pushes a pretty large amount of work into the application. To use the example from smallrye/smallrye-open-api#147, if an application needs to indicate that java.util.Date is generally serialized as an integer (epoch seconds), there would potentially need to be a fair amount of configuration to know where all the instances are located and Schema tree walking logic to replace them.

@arthurdm
Copy link
Member

That's a good point @MikeEdgar. I am fine with the mp.openapi.extensions.type-format.FQCN=SchemaType,DataFormat approach.

@arthurdm
Copy link
Member

arthurdm commented Oct 7, 2019

I propose that we move forward with the mp.openapi.extensions.type-format.FQCN=SchemaType,DataFormat approach that @msavy first suggested. Any objections?

@msavy
Copy link
Author

msavy commented Oct 7, 2019 via email

@EricWittmann
Copy link
Contributor

No objections.

@MikeEdgar
Copy link
Member

No objections, +1

@arthurdm
Copy link
Member

arthurdm commented Oct 8, 2019

thanks guys. this is now in plan, so ready to be picked up by anyone looking to help. =)

@MikeEdgar
Copy link
Member

I want to put out an alternate approach that only recently came up from smallrye/smallrye-open-api#193. @EricWittmann suggested that the enhancement support schema properties in addition to just the type. What are the everyone's thoughts on having the property discussed here support a full schema in JSON format as a way to specify any schema attribute and not just the type and format.

mp.openapi.schema.FQCN=<JSON schema>

mp.openapi.schema.java.util.UUID={"type":"string", "format":"uuid", "pattern":"<...regex for UUID...>"}

I realize this might be overkill for most situations, but it seems like a very powerful approach. Thoughts?

@MikeEdgar
Copy link
Member

Here's one more concept for this based on annotations (in case anyone still wants to discuss :-). This one allows the developer to specify the schema and indicate to the scanner which classes it should applyTo when encountered in the scan. This is similar to the previous comment allowing the full JSON in configuration but would be less repetitive.

@Schema (
   name = "custom_date",
   type = "integer",
   format = "int32",
   description = "Epoch seconds",
   applyTo = { java.util.Date.class, java.sql.Date.class, LocalDate.class })

@arthurdm
Copy link
Member

hey @MikeEdgar - I am cool with using the approach of mp.openapi.schema.FQCN=<JSON schema>.

Since that's an MP Config key it feels like the correct pattern to use for a global setting. I would prefer that over the applyTo pattern.

@MikeEdgar
Copy link
Member

If everyone is in agreement with the latest part of the discussion, I can work on updating the spec document and adding a test.

@msavy
Copy link
Author

msavy commented Dec 3, 2019 via email

@MikeEdgar
Copy link
Member

The changes for this are complete, with one idea we had not discussed yet. If a user provides a "name" property in the config JSON, the implementations should place the schema under components.schemas using the value of "name" property as the schema's key. This would provide a portable way for users to use a $ref to a schema defined in the config file.

If there is no negative feedback on that point, I'll open the PR.

@arthurdm
Copy link
Member

that's a really good idea Mike. It groups nicely all of the definitions in the OAS3 doc.

@arthurdm arthurdm added this to the MP OpenAPI 2.0 milestone Apr 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants