-
Notifications
You must be signed in to change notification settings - Fork 9.1k
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
long datatype is unusable with JavaScript and potentially other languages #704
Comments
I don't think we should restrict API's data types by what is easily possible in some programming languages. You can always map your JSON number into a string in your programming language, if necessary (or a big number type, if you have something like that). If something is semantically a number (even if a large one), it stays a number, thus it should be a number in JSON (and declared as a number in OpenAPI). Numbers in JSON have no upper limit on size or precision. On the other hand, I think formats like |
This seems like a problem with |
@auspicacious - you're taking it into a slightly wrong direction, IMHO, and I say this as someone who encountered this issue before with other users. The key problem here is the API design and not the documentation. Large numeric values would have issues with several languages, not just javascript. In Java, for example, I'd say that type Now, it is true that javascript cannot (at least by default) process unbounded numbers. However, by using |
I'm afraid that I disagree with that. I'm in a similar position to you in that I have spent much of the past three years trying to educate people about the difficulties in authoring HTTP/JSON/REST APIs that will consistently work across platforms. Another important focus has been on making it easier to determine backwards-compatibility in APIs; you'll see how those two intertwine in a moment. I take it as an assumption that since you are developing a specification for HTTP/JSON APIs you are interested in building APIs that can be consumed by the widest variety of programming languages possible; I know that was the driver behind my company's switch from SOAP and binary format. And it goes without saying that you want to help API designers do the right thing. Further, if you've encountered this problem before, you know that most people don't understand that this problem exists. Even the fact that RFC 7159 explicitly encourages developers never to use values greater than 2^53 isn't widely known. I'd say it's even worse: most developers I know don't even think about cross-platform compatibility; they just never have had to before. I've had people tell me that because jsonschema2pojo generates a 32-bit integer in Java when you pass So, if you have a new developer, and they read an OpenAPI specification that encourages them to design an API that will break in one of the most commonly used Web languages, who is responsible? I believe that you are. You also commented that Java should generate Unless, of course, you are not actually interested in people consuming APIs specified by OpenAPI. I'm sure that people don't enjoy being told that they shouldn't have actually used the tools that are provided to them by the specification; it does not engender confidence, and you need to realize that 99% of your users do not come to OpenAPI with the knowledge they need to make this "API design choice" on their own. Moreover, it does no harm to use I said that backwards compatibility plays into this as well, and here's how. I think that your proposal to use OpenAPI APIs contain a version number, so I assume that there is some level of concern about backwards-compatibility. For example, let's say that someone defines an API with an ID field. This ID field is initially represented by a 32-bit integer. They never really mention this to their clients, and many of their clients, without better guidance available, create database columns to store that ID that can contain a 32-bit integer. The API designers realize they're running out of IDs and move to a 64-bit integer, causing massive errors and downtime in their clients, who have to scramble to redefine databases that are now quite large. I could present similar scenarios for But this is easy to avoid, and simultaneously solve the primary problem we're discussing. I mentioned this solution in my initial post. If OpenAPI required items of type Moreover, it becomes possible for OpenAPI to specify absolute maximums and minimums, for example, those that correspond to a signed 32-bit integer. It allows OpenAPI to explain to its users why they should do this, in order to protect themselves. It allows tool implementers to make the right choices for their languages. In the absence of positive information about these restrictions, people will make the wrong choices. Boundaries must be explicit, or people will fail to consider them. It is not possible to make design choices without being informed. As it stands, the OpenAPI specification provides the tools for people to make the wrong design choices, but doesn't even provide a hint that they might be wrong. This is setting people up for failure. That's not responsible. |
Tackling PR: #741 |
This appears related to #1439 |
I noticed you're arguing about sticking to spec. Have you ever heard of "Postel's Law" or the "Robustness Principle" (https://en.wikipedia.org/wiki/Robustness_principle)? The big idea is this. The code that accepts JSON should be humble in what it accepts to ensure interoperability across all systems. The server can be be as pedantic as it wants to be when it produces JSON. |
I recommend that you consider the draft RFC entitled The Harmful Consequences of the Robustness Principle. What would happen if we applied your interpretation of Postel's Law here? If we are to be "pedantic" in what we produce, then our server would have to emit numeric values that conform to the OpenAPI specification -- in other words, numeric values that could not be parsed by a naive JavaScript client. I don't really see how that solves the problem. |
In the years since this was last active, we've added a formats registry that defines many formats for more specific, controllable numeric representations. I'm marking this as resolved, although if there's a use case not covered by existing formats, feel free to propose a new one. |
Hi,
I started reading the 2.0 specification and immediately encountered a serious cross-language compatibility problem.
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
The datatype "long" is defined as a JSON Schema
integer
with a format keyword ofint64
.JSON Schema
integer
s are of course implemented in JSON using the JSON number type. As RFC 7159 points out, although the JSON specification defines numbers as unbounded, the reality is that languages can and do refuse to deserialize numbers outside of certain ranges; most notably in JavaScript, where all JSON numbers are deserialized into the sole JavaScript number type, which is 64-bit floating point and therefore cannot handle integers larger than about 2^53.https://tools.ietf.org/html/rfc7159#section-6
The Google Discovery Document format, which Swagger drew a lot of inspiration from, recognized this problem and defined an
int64
format that is backed by a JSON Schemastring
, not aninteger
. It seems that Swagger/OpenAPI changed this. If you were to actually use the datatype as defined in OpenAPI, you would be locking out all JavaScript clients from using your API.A real-world example of this is Twitter's APIs, which initially provided tweet IDs as a JSON number, and then discovered that JavaScript clients weren't going to be able to handle that, so they had to add a second, string-based field containing the same value.
I have two proposals to address this issue.
The first is simpler, but does not address the larger problem of unbounded numbers in JSON: redefine the "long" datatype as a
string
.The second is to drop the
int32
andint64
formats entirely. Instead, mandate that all instances ofinteger
andnumber
types must provide explicit values formaximum
andminimum
to be considered valid. Additionally, do not allowmaximum
andminimum
to exceed(2^31)-1
or be smaller than-(2^31)
. This would ensure that JSON numbers are used in the most cross-language compatible way possible.Additional formats or perhaps common schemas could be added to support larger values via the
string
type.The text was updated successfully, but these errors were encountered: