-
Notifications
You must be signed in to change notification settings - Fork 1
New capabilities endpoint spec #133
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
✅ Deploy Preview for openpodcastapi ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
| capabilities: | ||
| type: object | ||
| description: | | ||
| The features supported by the server. The first object MUST be "urn:opa:core". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: "first object" reads strangely. "urn:opa:core" is a string, not an object. Furthermore, capabilities is an object, not a list. I've never seen a JSON api which makes any promises/requirements about the order of keys in an object. I wouldn't be surprised if there are programming languages with popular JSON libraries which do not preserve the order of keys in a JSON object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfly Good point, it'll be directly destructured either way so position isn't important. I'll update that.
|
|
||
| ## Backwards compatibility | ||
|
|
||
| To maintain backwards compatibility between **minor** versions, no parameters nor endpoints may be removed without a **major** version change. Fields may be deprecated in favor of new behaviors, but when queried by an older client the server MUST respond with a compatible response. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
when queried by an older client
Sorry, I have not read the existing spec. Is there a mechanism for servers to know if they're dealing with an older client? That would be nice so people developing new clients don't accidebtally use deprecated request/response fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jfly In general, the idea is that server developers should scope their implementation to a specific root. This means that if they support version 1.0.0 and version 2.0.0, they should put these on different roots (e.g. /api/v1 for 1.0.0 and /api/v2 for 2.0.0). This endpoint should then inform the client where the root is for the supported version.
The current approach doesn't programatically filter anything out, and I'm wondering if HATEOAS would be a good approach here for exposing this information in a more structured way. We could update this endpoint to require support for query parameters indicating the maximum and minimum versions of the core spec a client supports. That way, the client can ask the server if its capabilities are supported and use the latest supported version if so, but if not the client can report back. For example:
-
A client supporting v1.0.0 to v1.5.0 reaches out to a server and requests capabilities with a
minandmaxparameter. For exampleGET https://openpodcastapi.org/api/capabilities?min=1.0.0&max=1.5.0. -
The server responds with a payload showing ONLY supported core versions within that range. Extra features would still be listed in full because the core is the only thing we care about.
{ "urn:opa:core": { "1.0.0": { "status": "STABLE", "root": "/api/v1" } }, "urn:opa:extra:playcount": { "0.0.1": { "status": "DEPRECATED", "root": "/api/v0/playcount" }, "1.0.0": { "status": "STABLE", "root": "/api/v1/playcount" }, "2.0.0": { "status": "UNSTABLE", "root": "/api/v2/playcount" } } } -
The client then knows to only use the
/v1endpoint and to make use of methods available in the v1.0.0 specification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My initial reaction is that this is puts complexity in 2 places:
- The server needs to parse the
min+maxparamterers, and filter the supported versions in itsurn:opa:coreresponse - The client still needs to pick a core version from the capabilities response, and versions from any extra features it supports as well.
Would it be better to put all the logic in the client: just request /capabilities, and leave it up to the client to decide which version of the core + extra versions to use? It seems to me like clients will still have the same amount of logic, but this simplifies the api and the server side a bit.
Following discussions with @keunes and lots of RFC reading, I've put together an updated and simplified approach for exposing server capabilities to clients.
This spec largely follows the examples set out by the JMAP RFC. It enables us to easily communicate:
The latter enables us to help client developers choose whether to expose functionality to users. For example, users might opt in to using
UNSTABLEfeatures, or they may not. If the server exposes this information, the client can easily choose the feature based on this field.The
statusfield is currently the only field that is exposed, but this can be extended in future if more metadata needs to be revealed for different features. The specification should only require thestatusfield to prevent backwards incompatibility.All features should be scoped to a URN. This enables us to separated the core features of OPA (
urn:opa:core) and any extra features such asurn:opa:extra:playcount. External features can be scoped to their own namespace and added accordingly.