-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(crd-generator): introduce @JSONSchema
annotation
#7000
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
base: main
Are you sure you want to change the base?
Conversation
Still a work-in-progress, needs lots of testing and feedback/comments on whether this seems generally viable :) |
dc3d254
to
cc7a039
Compare
Thanks @MikeEdgar this looks promising. It does seem highly related to SchemaSwap - at least for the usage of implemenation or type. SchemaSwap could be altered to work at a field level, but one of the usage models it supports is for Keycloak, and maybe other projects, where the classes are defined in some other module and don't need or want CRD related annotations - so you are forced to define the swaps at a higher level than directly on the intended fields. cc @andreaTP I know you have mentioned in the past wanted to see a general schema option - did you think of it working vis SchemaSwap or a separate annotation? |
Yes, I think the |
That is correct, you can't specify an arbitrary type in string form. I also forgot to mention SchemaFrom (the localized limited form of SchemaSwap). So instead of:
You could do either:
or
With a similar comparison for implementation. |
Signed-off-by: Michael Edgar <medgar@redhat.com>
Signed-off-by: Michael Edgar <medgar@redhat.com>
Signed-off-by: Michael Edgar <medgar@redhat.com>
Signed-off-by: Michael Edgar <medgar@redhat.com>
Signed-off-by: Michael Edgar <medgar@redhat.com>
Signed-off-by: Michael Edgar <medgar@redhat.com>
|
Hi @MikeEdgar ! Sorry I completely missed the notification on this one 😓 This proposal is highly related to
I'd be interested in a "general schema option" where we can swap in plain json or yaml without limiting the user to a fully typed interface to be as forward compatible as possible. |
I have not. Ultimately the problem with those annotations is that they redirect to another class/type to perform the same scanning logic, so there is no way to specify the schema attributes not already supported.
I think allowing a JSON or YAML string in the annotation would be a nice feature, but it still needs to be parsed into
Exactly, the intent with the annotation is to hand the control (big hammer) entirely to the user, with the "exit" of incorporating the default scanning using the |
Probably better to have a new annotation if a field is going to change the semantics.
Thanks for explaining! Makes sense!
That said, the proposal and overall design makes sense, maybe let's try to fish for feedback on @manusa |
Correct me if I'm wrong, but is being proposed (and what is already supported) emcompasses:
If the overlay behavior is distinct to swapping to a class / implementation, then it would make the most sense to me to put the overlay behavior in the existing SchemaSwap annotation, and add a new annotation(s) only for the swapping to text. I would be good with allowing SchemaSwap to be applied at the field level as well so that the new functionality does not have to also be added to SchemaFrom. |
The plain text option isn't part of the PR yet, so it might be better handled separately as another enhancement.
It is supplemental to the class/implementation mode. This should feel familiar to those using the Swagger
It is only applied transitively to the extent that the class(es) provided for the
It could be declared separately, but thinking about the
Splitting out the |
Yes SchemaFrom and SchemaSwap do the same thing as what JSONSchema.implementation does via the type and targetType properties respectively. The difference between them is that SchemaFrom is applicable to fields, while SchemaSwap is used at the class level. However I think with additional logic / validation they could be a single annotation.
That seems fine too as a separate annotation. Ideally it would be applicable to both the field level and the class level (using originalType / fieldName like SchemaSwap). |
Overall, I’m a bit hesitant to follow the OpenAPI/Swagger model too closely in this context. Because of that, I’d be cautious about offering a high-level, “nice to use” Java API that tries to generate these complex constructs as it may promise more than the underlying platform can reliably deliver.
I see things a bit differently here. To me, the raw representation,i.e. without strong typing, just pure JSON/YAML interfaces, is actually the most valuable part of this proposal. If we split it out and handle it separately, I worry that the added complexity and overlap in functionality could end up blocking progress rather than helping us move forward. |
I agree completely that the underlying "OpenAPI" implementation in Kube is limiting and even surprising to those familiar with OpenAPI/JSON schema. That being said, the intent with the new annotation is to anyway give control to the user and let them express what they need in the schema. It is up to them to understand those limitations and annotate accordingly. The only place the annotation attempts to be friendly to helping deal with the peculiarities of the Kube requirements is with the Ultimately, the CRD schema will either be rejected or it will not validate as expected - something that an operator developer should discover in testing :-)
It's a valuable option, but it is still constrained by type checking when parsed into the model during CRD generation. |
I like it, as the code to handle it is fully generated, I'm happy to handle the trade-off. |
As far as I can tell, in this repo, we have always attempted to give ppl directly usable APIs, dealing with the complexity ourselves when possible. |
It's the same whether using a literal JSON/YAML schema in an annotation or typed properties, no? In other words, if the string literal is favored over the individual properties, it still exposes the users to the complexities directly and delegates the validation to Kube. |
That's accurate, it boils down to the expectations we settle, this is my reasoning:
@MikeEdgar have you attempted to work(e.g. generate clients for different languages etc.) with a CRD that contains those advanced constructs? (I mean |
Fair enough!
From what I've seen, Application model <--> OpenAPI is simply not a lossless process in non-trivial cases. It's much easier to express the constraints of an application model in OpenAPI than it is to generate reasonable code from OpenAPI (particularly the schema part). That effectively boils down to the fact that Json schema is a constraint representation and not necessarily an object model. |
Description
Closes #6999
This is a POC to demonstrate the idea behind #6999 (it may also close several other issues related to the CRD generator's capabilities). The new
@JSONSchema
annotation may be used on a class or property to short-circuit other schema scanning for the target. The exception is when the annotation'simplementation
is used. In that case, theimplementation
class will be scanned as normal, then the@JSONSchema
annotation attributes will be used to override those from the scan.The annotation also includes a
structural
boolean attribute that enables certain handling for structural schemas. This includes copying properties fromallOf
,anyOf
,oneOf
, andnot
to the schema with the annotation, and also removing the restricted attributes without those sub-schemas.Several of the attributes of the annotation may not actually be valid for a Kube CRD schema. However, the intent here is simply to expose the CRD schema model entirely to give that control to the user.
Type of change
test, version modification, documentation, etc.)
Checklist