Skip to content

Discuss rules for api deprecation and our stability guarantees #1105

Closed
@jtgeibel

Description

@jtgeibel

In #1102 we recently touched on the concept of deprecation of unused api endpoints. I'm not necessarily advocating for the removal of these routes, but I think they help provide concrete examples for discussing our stability guarantees when it comes to the api.

First, a few questions to consider:

  • Should we require an RFC style process for removing old endpoints?
    • If so, should we also require the process for reviewing the addition of new endpoints?
  • Where would we communicate these changes so that external users are aware of proposed changes?
  • Should we instrument endpoints to confirm that that are no unexpected users before removal? Would reviewing logs be sufficient?
  • What exactly constitutes a breaking change?
    • For cargo endpoints, we should always return a 200 result status. Are we effectively committed to the same for other routes? (See HTTP error codes are barely used #712)
    • Is it okay to remove Option<T> fields from a json return type, or must we retain the field with a None value? In other words, is it okay to break clients that handle a nil value for a field but error when the field is absent?

Okay, so on to some specific examples!

GET /versions/:version_id and GET /crates/:crate_id/:version

These 2 routes are implemented in version::show(). There isn't really much reason for these to be combined as the endpoint has different semantics depending on if the :crate_id is present or not. I think this should be properly split into two endpoints.

For GET /versions/:version_id I don't expect there to be any external users at all as in order to use this api it is necessary to know the database id number for the version you seek. The primary way I see to obtain this is through GET /crates/:crate_id, but this endpoint already returns an array of versions containing all of this data. If there are any external users of this endpoint then we're probably doing duplicate effort to serve them.

GET /crates/:crate_id/:version has a much better interface, as crate_id and version are both human readable names and it is possible that some endpoints are constructing this URL on their own. This could be an argument for keeping this version of the endpoint around for longer, or at least doing more due-diligence to ensure there are no external uses.

GET /versions

This is very similar to the GET /versions/:version_id endpoint, except it accepts multiple id[] query parameters and returns a list of versions. Again, in order to make use of this endpoint the user has to already know the database id of the version.

JSON result type for GET /crates/:crate_id/:version/download

This endpoint is used by cargo and redirects to a URL on S3. However, if the request's Accept header contains json then we construct a 200 response with JSON data. The frontend code that used this code path was removed in #916 and had already been commented out for 3 years at the time.

While this code path is quite trivial, are we committed to keeping this until some far distant /api/v2 is released? (This is a slightly strange example because this is primarily a cargo route so I don't think this route would ever be removed even if other v1 endpoints are removed. At best we would remove this special case.)

Summary

In summary, I'm not suggesting that we remove any of these endpoints at this time. If we come up with a policy that allows for removal I would rank them as:

  • The endpoints that use raw database ids are low risk for removal.
  • The endpoint that uses human readable path segments is medium risk for removal.
  • The JSON response type for the download endpoint is medium risk for removal. We should probably add a comment describing the situation.

With these examples in mind, where do you fall on the scale between: "all endpoints must remain stable until /v2" and "cargo is our only official stability guarantee but we do our best to keep everyone happy"? There are of course mid-points along this scale. For instance, we could work with users of our api to triage the endpoints they are using and potentially expose them through an official client crate to encourage best practices.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions