Repository navigation
Integer enum with named items #681
Description
Activity
Parent-Issue: json-schema-org/json-schema-spec#579, related: json-schema-org/json-schema-spec#348.
It's not related to json-schema-org/json-schema-spec#348, it's a duplicate for it.
@webron
json-schema-org/json-schema-spec#348 is talking about documenting each enum items, rather than assigning names to enum items (this issues topic).
So I think this issue is not a duplicate.Fair point, missed that.
Reacted by Kenji Tayama and Julie NikitinaI like this, combined with json-schema-org/json-schema-spec#348:
type: integer format: int32 enum: - value: 1 name: Sunny description: Blue sky - value: 2 name: Cloudy description: Slightly overcast - value: 3 name: Rainy description: Take an umbrella with you
If the names should be unique (probably a prerequisite for code generation) a hashmap would be more appropriate:
type: integer format: int32 enum: Sunny: value: 1 description: Blue sky Cloudy: value: 2 description: Slightly overcast Rainy: value: 3 description: Take an umbrella with you
So
enumcould either have an array value with just the list of values, or an object value with named and potentially further annotated values.Reacted by Paŭlo Ebermann, Arnaud Lauret, alan blount, jin yung, grosch, Johannes Stickel, Lucas Santos, binglin, Max Landborn, mofelee and 81 moreReacted by Peter Tiedemann, Martin Thurn, Sandor, Fu, David Johann Moser, Vladimir Rogozhin, Augusto Santos, ǃшɒʞɒH ǃǀɄ, crazyk2, David ALEXANDRE and 9 moreReacted by Marcus Ilgner, SUMIT SHARMA, Damir Nafikov, Jovino Guerrero, Sergei Unshchikov, NonhlanhlaPrudence and Montasir AsairaWell, either the
nameor thevaluehas to be unique, doesn't matter which one as long as the intent is clear.However, where does it end? Just a single value? Technically in Java (referenced in the original comment) allows setting any number of properties for enum values. What about types? There's no indication it's an int, it could be a string a string as well. Should that be inferred? Are we supposed to introduce a big construct to support all these options? Also, I have no idea what other languages support and how it would affect them.
And last but not least, if I just want to define a basic enough, would I have to end up with something like:
enum: Sunny: {} Cloudy: {} Rainy: {}
That's...
This feels like a leaking of implementation details in the API, seemingly no different then describing every possible combination of values for a proper object's properties. I suspect it is the result of attempting to use the standard to automatically create an sdk for functional calls, in which enums are being semantically defined and maintained here. To me, enums are an object-type not a value-type and thus shouldn't get any special treatment.
Now I think @ralfhandl's former format is best.
- ralfhandl's former fomat
valueandnamewritten together makes it more understandable.- Looks good together with How to do inheritance? json-schema-org/json-schema-spec#348
- ralfhandl's latter format
- This makes assigning a name a requirement, which may be too much of a breaking change?
- I think the uniqueness of names doesn't have to be baked in to the format. The OAI spec can specify that.
For webron's comments…
Well, either the name or the value has to be unique, doesn't matter which one as long as the intent is clear.
I think both should be unique and should be written in the specs.
However, where does it end?
I don't feel the number needs to be limited.
What about types?
Value types of enums are specified since Swagger 2.0, like this:
type: integer format: int32 enum: :(Looks like only strings were allowed in 1.0)
For wparad's comments…
I consider "naming enum items" is a missing spec in Swagger 2.0. In general, for an enum to be an enum, each item should have an name.
According to wikipedia:In computer programming, an enumerated type (also called enumeration or enum, or factor in the R programming language, and a categorical variable in statistics) is a data type consisting of a set of named values called elements, members, enumeral, or enumerators of the type.
- ralfhandl's former fomat
@webron The name (if there is one) needs to be unique in the target programming language. The value needs to be unique "on the wire". But the value is not necessarily a string, it can be anything (string, number, boolean, object, array). Therefore using the value as a keys in a map / property names in an object doesn't really work.
I wasn't advocating the map option, just picked one of the two.
I'd like to clarify that the limitations for the enum declarations are derived from JSON Schema - we did not introduce any special restriction there.
Also, unlike what @kenjitayama mentioned, the type is not derived from the type mentioned in the encompassing definition - again, that's the way JSON Schema works.
For example:type: string enum: - 1 - 2 - 3
doesn't mean that
"1"is the valid value - it means that nothing will validate against that schema, because none of the enum values are strings.
Regardless, I was referring to the types of additional values for names enums, not the 'root' values. For simplicity, if we do provide a solution we may limit it to just one value.There are two problems to breaking away from the current structure:
- None of the existing JSON Schema validator could handle it, so customized tooling is required - this may hinder adoption.
- The constraint to require both the names and values to be unique couldn't be enforced by the (meta) JSON Schema and will require external validation.
I'm not sure I understood what webron said about types, but I found that Swagger 2.0 uses JSON Schema Draft 4 (the latest) and enum spec is derived from it.
Looks like it's for validation rather than for supplementing description of data type(so this issue's use case is out of the scope).Next, I found these proposals for JSON Scheme v5
- choices (v5 proposal to enhance enum)
- enumNames (v5 proposal)
- Just what I proposed in this issue (although I prefer ralfhandl's former format now).
I wonder if one of this would be accepted, and if OpenAPI v3 will support JSON Schema v5. And when it would happen.
Other reference:
While we've yet to reach that point, it's unlikely draft 5 will be supported because it's not finalized. Even if finalized before finalization of 3.0, it's unlikely they'd be enough tooling around it for us to claim support of it. That said, if it's finalized before, it's easier to derive the structure from it and use it as well.
I see there's a long way to go.
But at least, now it is clear what is necessary to support this.20 remaining items
Face with same issue on NSwag client generation.
@BlackGad @Kevweir @rlabrecque @peol etc.
OpenAPI 3.1 is likely to move to JSON Schema draft 2019-09 (formerly known as draft-08) per PR #1977. That would allow the solution I showed above and allows for creating new re-usable JSON Schema vocabularies (sets of keywords) for specific purposes such as code generation. These can be formally identified so that different implementations can recognize and implement them (which was previously not possible in JSON Schema, or at least not in any practical way). So:
Here's an example with a totally fictional
codeGenkeyword that provides guidance on how to interpret the Schema Object in which it appears (see also Appendix E of the current JSON Schema Core specification for another example of how code generation keywords could be defined).codeGen: namedEnum oneOf: - const: 1 title: Sunny description: Blue sky - const: 2 title: Cloudy description: Slightly overcast - const: 3 title: Rainy description: Take an umbrella with you
In this example, the
codeGenkeyword informs the generator that the Schema Object should be interpreted as a named enum. Presumably, the definition of how this keyword works would say something like "thenamedEnumvalue, when it appears alongside of aoneOfwhere each branch of theoneOfcontains aconstand atitle, indicates that theoneOfshould be treated as a named enumeration, whereconstgives the value andtitlegives the name."This way, we do not need to add more keywords that have an identical validation effect, which adds to the burden of validator implementations. Validators can safely ignore the unknown-to-them
codeGenkeyword and treat the other keywords as usual for validation purposes, while code generators get the additional information they need from the specialized keyword.This is just one of many ways this (and other code generation problems) could be solved. Hopefully once OAS 3.1 is out (assuming draft 2019-09 JSON Schema support is indeed included) the OpenAPI community will use the new features to try out different ideas and converge on a standard code generation vocabulary. The advantage of OAS 3.1 + 2019-09 JSON Schema is that this process of producing a new vocabulary can happen independent of both the JSON Schema and OAS specification processes.
Reacted by Alexander Holbreich, DanielHabenicht, Maayan Hanin, Warren Parad, LEE HYEONU, Vadzim Kapichenka and Matias Hermanrud Fjeld@MikeRalphson @webron @darrelmiller OAS 3.1 was released,any update on this issue?
should we use
codeGen: namedEnum?@xiaoxiangmoe I made up
codeGen: namedEnumon the spot when writing that comment. A more likely approach would be a code generation vocabulary of keywords rather than a singlecodeGenkeyword which would get very overloaded very quickly. I'm not aware of any such vocabulary, but now that OAS 3.1 is out and fully compatible with JSON Schema 2020-12, anyone (such as a tooling vendor) can create a vocabulary and work to get it supported in implementation without having to wait for a new version of OAS or JSON Schema.It will obviously take a bit for JSON Schema vendors to add support for vocabularies (meaning, add the annotation output support and enable folks to write plugins to handle previously unknown vocabularies rather than just hardcoding all keyword support) and for OAS vendors to make use of that (meaning make use of annotations from JSON Schema to recognize codegen use cases).
So the solution is now possible in theory, but there are several things that need to be done before it's usable in practice.
Note that if you take the json of an OpenAPI modal directly, without any modifications, and use it as the basis of your JSON Schema Form, you instantly have a nice looking form using all the information from the OpenAPI (title, description, format etc.) where the user can submit data. This way I make the latest developments of an API quickly available to my colleagues.
If this proposal is accepted, that would enable dropdowns where the enumNames are displayed but the underlying enums are in the payload.
My point is that the JSON Schema Form specification is exactly the same as OpenAPI except for this one thing and therefore, I fully support this proposal.
@MarkRosemaker parallel arrays are horribly error-prone which is why the proposal as initially shown here has never drawn serious support within JSON Schema. The
oneOf+ some keyword that signifies to a generator tool (form, code, docs, whatever) to interpret thatoneOfas a named/titled/whatever enumeration based on theconstvalue in each branch avoids the parallel array problem and is in general much more flexible as you can include additional information, such as a help string to be extracted and associated with the value somehow.This is similar. I have several linked fields that could be each in a separate enum, but they go together (OK, system could be static, but code and display need to be linked):
coding: type: array items: enum: - {system: http://terminology.hl7.org/CodeSystem/v3-RoleCode,code: _DedicatedServiceDeliveryLocationRoleType,display: DedicatedServiceDeliveryLocationRoleType} - {system: http://terminology.hl7.org/CodeSystem/v3-RoleCode,code: _DedicatedClinicalLocationRoleType,display: DedicatedClinicalLocationRoleType} - {system: http://terminology.hl7.org/CodeSystem/v3-RoleCode,code: DX,display: Diagnostics or therapeutics unit} - {system: http://terminology.hl7.org/CodeSystem/v3-RoleCode,code: CVDX,display: Cardiovascular diagnostics or therapeutics unit}Is there a way to link two or more enum values like this? It doesn't give an error, but the enum values don't render in schema output. Also, the field names are fixed, I can't use "title" and "description".
I've tried the following, but the enum still doesn't render:
coding: type: array items: type: object properties: system: type: string default: http://terminology.hl7.org/CodeSystem/v3-RoleCode code: type: string display: type: string enum: - {code: _DedicatedServiceDeliveryLocationRoleType,display: DedicatedServiceDeliveryLocationRoleType} - {code: _DedicatedClinicalLocationRoleType,display: DedicatedClinicalLocationRoleType} - {code: DX,display: Diagnostics or therapeutics unit} - {code: CVDX,display: Cardiovascular diagnostics or therapeutics unit}Yes, I know you could say this is an implementation issue with the tools, but I would just like to know how to link two or more value sets so that they are consistent rather than having separate enum sets for "code" and "display" strings.
Reacted by Warren Parad@Tasselhoff the answer is still the same as in earlier comments. Since this is fundamentally a JSON Schema concern, there is a JSON Schema issue tracking the
codegen: namedEnumapproach (although the example there usesdocHint: enum- I doubt either of those will be the actual name). It is also possible for a 3rd-party to implement this as a JSON Schema extension vocabulary. See also #2542. Anything about anything "rendering" is definitely a tooling issue and not a spec issue.Reacted by DarrelI've made a suggestiion in swagger-ui that integrates both linked fields and parent-child relationships, but it straddles the rendering and the OpenAPI Specification implementation swagger-api/swagger-ui#7260
Edit: as you can no doubt see, I'm pretty new at this and my desire for certain functionality far exceeds my technical domain knowledge...
We've decided to close this issue, following @handrews's proposal.
For reference:
codeGen: namedEnum oneOf: - const: 1 title: Sunny description: Blue sky - const: 2 title: Cloudy description: Slightly overcast - const: 3 title: Rainy description: Take an umbrella with you
The
oneOfdifferentconstvalues allows you to define an extended enum structure with any additional information required, ending with an equivalent result.Regarding the concerns about code-generation - we feel code generators can detect such structure and convert it to enum stucts if needed. As proposed by @handrews, there can be a codegen vocabulary that adds annotations to give hints to such tools (see:
codeGen: namedEnum). If anyone is interested in working on such a vocabulary, please join the discussion at https://github.com/json-schema-org/vocab-idl.Since now we're fully aligned with JSON Schema, any changes to how schemas are defined in OpenAPI would be addressed by the JSON Schema team and not the OpenAPI.
Reacted by Riley Labrecque, Álvaro Larumbe and ZHAO Jin-XiangReacted by Riley Labrecque, Karl Hiramoto and ZHAO Jin-Xiang@webron I can't find any documentation for the
codeGenfield in JSON Schema Standard. Could you please provide the corresponding documentation? Thank you a lot.@xiaoxiangmoe
codeGenwas an example proposal. It and other code generation ideas need to be fleshed out.
I would like to propose a new field called
enumNames.Example:
This information is necessary for generating the following Java enum.
Some web APIs require clients to send/retrieve integer enum items while knowing what they mean. So it is useful to be able to generate this kind of enum.
I had been seeking advice in the following swagger-codegen issue, and got a conclusion that we need a vendor extension (which corresponds to this proposal) using Swagger 2.0 spec.
swagger-api/swagger-codegen#2690