Consistent API response type
supahgreg opened this issue · 7 comments
As an API consumer I'd like for all messages returned from the API to be predictable and valid JSON in order to have consistent interactions and minimize special handling of responses.
This would be a great enhancement. It's hard to integrate with an API that doesn't give you back a consistent response format.
@supahgreg and @bdw429s Can you try the latest API and see if you're happy with the consistency? If not we'd like to track specific edge cases
@supahgreg and @bdw429s Can you try the latest API and see if you're happy with the consistency? If not we'd like to track specific edge cases
Scratch that - this still needs to be done.
Correct, this is not done. In fact, I was just talking about it on Slack:
It's actually an annoyance of mine that tripped me up when using the API that the resource representation changed when you added
?release=latest
to the URL
That never made any sense.
For a REST API, the JSON representation of the resource should be consistent. Adding a query string filter should never change the format of the JSON coming back.
Yet
https://api.adoptopenjdk.net/v2/info/releases/openjdk11?&openjdk_impl=hotspot&os=windows&arch=x64&type=jre
gives me an array of objects and
https://api.adoptopenjdk.net/v2/info/releases/openjdk11?&openjdk_impl=hotspot&os=windows&arch=x64&type=jre&release=latest
gives me an object without an array.
I've run into this while working on #165 after adding support for multiple release
query values.
The current API behavior is to return a single release object for the query ?release=latest
, and an array of release objects otherwise. From a RESTful standpoint, changing the response format based on magic query params seems incorrect, so this could be corrected by returning an array containing the single release object.
However, it seems as though any valid release query should only match against a single release (please correct me if that's not the case). This begs the question as to whether release
should even be queryable, since it appears to be more of a unique identifier that describes a single release object. It cannot be used to filter or search for resources, since the identifier must be known beforehand.
It's also the only query option that filters on top-level release properties, whereas the other query options filter by properties of nested binary objects.
Hence, it would likely make more sense to replace the release
query functionality with an optional path variable that returns either the release object itself or a 404. For example:
GET /info/releases/openjdk8/latest
200 OK
{
"release_name": "jdk8u3000", ...
}
GET /info/releases/openjdk8/jdk8u3000
200 OK
{
"release_name": "jdk8u3000", ...
}
In this case latest
is essentially an alias that resolves to the most recent release name a la Docker, NPM, etc.
GET /info/releases/openjdk8/jaydeekay8u3000
404 Not Found
{
"error": "Release 'jaydeekay8u3000' not found", ...
}
If the identifier is invalid, a 404 is returned. Any error messages would ideally be represented as properties in a JSON object as well, removing additional complexity for consumers that wish to parse and handle those errors (i.e. having to route messages to different handlers depending on their Content-type
).
These examples are based on the structure of the current v2 API so there may still be some redundancy in /info/releases/{jdkVersion}/{release}
assuming that a release name will only ever belong to a single major JDK version. It almost seems as though a "proper" solution would treat jdkVersion
as a queryable param and release
as a unique identifier for a single release
resource.
For example:
/info/releases
returns all known release resources (presumably paged in some way).
/info/releases/openjdk8
becomes /info/releases?jdkVersion=8
, and has a schema identical to the one described above (i.e. query params may not influence the response format).
/info/releases/openjdk8/jdk8u3000
becomes /info/releases/jdk8u3000
and returns a single resource based on the given unique identifier.
Not sure where latest
would go in this case, but I figure I've typed enough noise in here for now 😃.
However, it seems as though any valid release query should only match against a single release (please correct me if that's not the case).
@ParkerM Personally, I'd love to be able to filter on partial releases. It would probably make more sense to filter directly on the semantic version using something common such as the npm flavor semver library, but an example would be asking for JDK 11.x
which would be a semver range matching the latest stable release starting with the major version of 11
. Right now I basically have to query all possible releases and then do this filtering on my end of the API, which works but it's a lot more over the wire.
Here's a link of all the amazing things you can do with semver ranges to filter out the exact versions you want.
https://devhints.io/semver
v3 should be returning consistent results.