-
-
Notifications
You must be signed in to change notification settings - Fork 929
API v2
We've gone about as far as we can go to make API v1 better without breaking backwards compatibility. Compiled here is a non-exhaustive list of changes that will require a version bump.
-
More RESTful. Despite aspiring to be a RESTful API, some aspects of API v1 show a fundamental misunderstanding of REST. For example, it is redundant to say
DELETE /api/v1/web_hooks/remove
orDELETE /api/v1/gems/yank
. In v2, you'll be able to simply call theDELETE
method on the resource/api/v1/web_hooks
or/api/v1/gems
. To register a new web hook or gem, simplyPOST
to the same resource. To list your existing web hooks or gems, simplyGET
that resource. -
More concise. Some routes are unnecessarily long, for example
/api/v1/versions/[GEM NAME]-[GEM VERSION]/downloads/search.json
. This hierarchy serves no useful purpose. In v2, all routes should be designed to have no more than two levels of nesting. - More consistent. The API should explicitly declare what response formats are supported (e.g. JSON, Marshal, XML, YAML) and every resource should respond to a request for any supported format. If a user makes a request for a particular format, the response should always be in that format, even in the case of a 4xx error. This will make parsing responses easier.
- More complete. All methods should support a JSON-P response format, to allow anyone (including us) to build a complete RubyGems front-end. For example, the ability to update links via the API. This has the potential to dramatically increase the speed of development on RubyGems.org.
- More secure. Any methods that require authentication should only be accessible over HTTPS.
-
More semantic. Parameters (i.e. things that come after the question mark in a
GET
request) should always be optional. -
Pagination. There should be a consistent pagination scheme that can be applied to any
GET
method that can't return all of its results. I'd recommend adopting the GitHub v3 pagination scheme. - Better XML. XML responses should have non-dasherized keys (using underscores instead). This is perfectly valid XML and will make this response format more consistent with JSON and YAML responses.
Thoughts? Edit away, it's a wiki for a reason! :) —@qrush
In terms of suggestion (1), wouldn't it make more sense to have it be
DELETE /api/v2/web_hooks/[HOOK_NAME]
orDELETE /api/v2/gems/[GEM_NAME]-[GEM_VERSION]
? Making them into proper resources. I don't think having lots of parameters passed to an API method is necessarily better than having a multi-segment URL, especially if each segment has some meaning, and each end point is a 'resource'. —@namelessjon
I definitely understand where you're coming from. Let's take web hooks as an example. Today, you can pass
*
instead of a gem name to make the hook apply globally, to all your gems. Given that we need to maintain this functionality (but ideally without the*
), I think it makes sense to think of the resource as "the list of all your webhooks" to which you can add (POST
) or subtract (DELETE
). If you want to operate on a more granular basis, you can pass an optionalgem_name
parameter (see 6 above). How would you handle this specific case in your scheme? —@sferik
I think something like this: POST /web_hooks/[HOOK_NAME]
would create a hook for all of your gems. DELETE
to that uri would delete it for all your gems. POST /web_hooks/[HOOK_NAME]/[GEM_NAME]
makes a hook just for that gem, DELETE
removes it for a gem. With GET /web_hooks
giving you a list of all hooks, and GET /web_hooks/[HOOK_NAME]
giving you specific details (assuming you don't display the full resource in the list on the upper hook.) —@namelessjon
I'd love to see OPTIONS support and
<link>
s in the XML version (instead of bare IDs). I don't think there are a lot of clients out there right now that would benefit from either, but the RESTafarians of the world really emphasize both. I bet if we build it, people will build clients to take advantage, and that could really improve the state of Ruby + REST. —@jamesarosen
I am in complete agreement and plan to implement both of the features you've proposed, following the advice of Steve Klabnik. —@sferik
It might be nice to be able to specify the API version as a header (X-API-Version) instead of in the URL. -@wycats
I disagree. Now, instead of just running a simple GET request passing just the URL (with, say
open()
('open-url'
)) you need to add code to provide headers as well. -@dvyjones
It would be great to support CORS in addition to JSON-P. Check out the CORS Rack middleware: https://github.com/cyu/rack-cors. -@wycats