On Thu, Jul 11, 2013 at 2:02 PM, Matt Franklin <[email protected]>wrote:
> +1 for every one of Chris' +1s, unless otherwise noted. > > On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <[email protected]> wrote: > > > Oh boy!! :) > > > > Comments inline > > > > > > On Thu, Jul 11, 2013 at 1:20 PM, Erin Noe-Payne < > [email protected] > > >wrote: > > > > > Hey All, > > > > > > As we are starting to look at the rest apis in more detail, I would > > > like to discuss and agree upon a consistent interface for our apis. > > > We currently have several developers interested in contributing to the > > > apis and the angular branch, and I would like to solidify the > > > interface, methods, response format, etc so that we can be on the same > > > page going forward. If we can agree on an api virtualization layer > > > then we should be able to build against it on the server and on the > > > angular application in parallel. > > > > > > I'll start with a proposal and look for feedback to iterate from there. > > > > > > 1. API root url > > > > > > "/api". Drop support for rpc api, move from /api/rest to just /api. > > > > > > > +1 - the only downside of this is that it prohibits implementing over > time > > and requires a rip/replace approach of the whole system > > > > > > > > 2. Media Types > > > > > > Initially support only application/json. We can revisit > > > application/xml as a nice-to-have. > > > > > > > +1 > > > > > > > > 3. HTTP Methods > > > > > > GET, PUT, POST, DELETE > > > > > > > +1 (We also need to decide if PUT can handle partial updates) > > > > I say not. That is what PATCH is for, once everything supports it: > http://tools.ietf.org/html/rfc5789 I was going to mention patch HOWEVER if we allow returning subsets of data (with fields) we should accept a subset back without destroying the object IMHO. We can use PATCH in theory, it's just more confusing, and we'll need to make sure PUT validates the object from completeness somehow. > > > > > > > > > > 4. Status Codes > > > > > > 200, 201, 400, 401, 403, 404, 500 > > > > > > > +1 > > > > > > > > 5. URL formats > > > > > > Use plural nouns (pages, people, widgets). Do not nest associations > > > beyond one level deep. For example: > > > /pages/1/regions (ok) > > > /pages/1/regions/2/regionwidgets (not ok) > > > /regions/2/regionwidgets (ok) > > > > > > > I'm not a fan of this requirement. Your example is the exact reason I'm > not > > a fan actually. In all reality, regions don't mean anything outside a > page, > > and region widgets don't mean anything outside of a region. Yes, they > have > > IDs, but in reality, those IDs should be subordinate to the parent (so > > there should be nothing wrong with having Page 1 with regions [1,2] and > > Page 2 with regions [1,2]). I understand that's not how the DB works > today > > but it's what makes the most logical sense. > > > > I agree with Chris. We should not limit to a single level. That is counter > to a few REST web service principles. > > > > > > > > 6. Response formats > > > > > > 6a. Wrap all responses in an object. All valid (200) responses should > > > be wrapped in an object that includes a "meta" object for metadata, > > > and a "data" object for the response body. This allows us to capture > > > or extend metadata associated with a response as needed. Any metadata > > > properties should be standardized. > > > > > > Example: > > > > > > GET /people > > > { > > > meta: {count: 253, limit: 10, offset: 0, ...} > > > data: [ {id: 1, name: 'canonical', ...}, ... ] > > > } > > > > > > GET /people/1 > > > { > > > meta: { ... } > > > data: {id:1, name: 'canonical', ...} > > > } > > > > > > > This really complicates a couple things, first, it means the GET != PUT > > since the GET will include the meta data. Can we achieve this same result > > with HTTP Headers? > > > > > > > > 6b. Error objects. In the case of an error, the correct error code > > > should be returned. In addition, an error object should be returned > > > with a standardized format. Ideally including a verbose, > > > human-readable error message for developers, and an internationalized > > > readable error message for display to end users. > > > > > > GET /people/25 > > > 401 > > > { > > > developerMessage: 'Unauthorized. Access to this resource requires > > > authentication', > > > userMessage: 'Please login', > > > stackTrace: ... > > > } > > > > > > > +1 > > > > > > > > 6c. Partial responses. By default all responses, whether a list or > > > individual resource, should return a full representation of the > > > resources (not including security constraints). All endpoints should > > > support the query string parameter "fields", which accepts a comma > > > delimited list of fields to build a partial response. > > > > > > > Hmmm.....what's funny (except for the wasted work) is this is how I > > originally built the people resource. I changed it because the "fields" > > approach gets almost impossible to manage with nested elements (at least > in > > Java - rewrite in Ruby anyone??). I'm open to suggestions though. I guess > > we could also make a rule that the data objects shouldn't have nested > > elements but that is a tough rule. > > > > I think the fields approach makes sense long-term; but, it is not critical. > > > > > > > > > > GET /people/1 > > > { > > > meta: { ... }, > > > data: { id: 1, name: 'canonical', email: '[email protected]', ... } > > > } > > > > > > GET /people/1?fields=id,name > > > { > > > meta: { ... }, > > > data: { id: 1, name: 'canonical' } > > > } > > > > > > 6d. Pagination. All requests that return a list should be paginated. > > > The query string parameters "limit" and "offset" should be used for > > > pagination. On any request in which either parameter is not set, they > > > should default to 10 and 0 respectively. > > > > > > > +1 > > > > > > > > 6e. Use camelCase for properties. > > > > > > > +1 > > > > > > > > 7. Endpoints. > > > > > > 7a. Standard endpoints: there should be standard CRUD endpoints to > > > support each rave resource. In other words, any operation possible in > > > rave should be possible through a rest api action. > > > > > > > +1 > > > > > > > > 7b. Special endpoints. In the case of certain client needs, we can > > > implement a small number of special endpoints to fulfill a specific > > > role. The primary case in point is retrieving a page for render, which > > > returns a page, its regions, its regionWidgets, and their render data. > > > > > > > +1 > > > > > > > > > > > > > > Ok, I think that's it. This is meant as a proposal only - we are > > > looking for feedback to go forward. Thoughts? > > > > > >
