rave-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Chris Geer <ch...@cxtsoftware.com>
Subject Re: [Proposal] REST API interface
Date Thu, 11 Jul 2013 20:47:05 GMT
Oh boy!! :)

Comments inline


On Thu, Jul 11, 2013 at 1:20 PM, Erin Noe-Payne <erin.noe.payne@gmail.com>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)

>
> 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.

>
> 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.

>
> GET /people/1
> {
>  meta: { ... },
>  data: { id: 1, name: 'canonical', email: 'canonical@gmail.com', ... }
> }
>
> 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?
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message