You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@rave.apache.org by Erin Noe-Payne <er...@gmail.com> on 2013/07/11 22:20:47 UTC

[Proposal] REST API interface

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.

2. Media Types

Initially support only application/json. We can revisit
application/xml as a nice-to-have.

3. HTTP Methods

GET, PUT, POST, DELETE

4. Status Codes

200, 201, 400, 401, 403, 404, 500

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)

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', ...}
}

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

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.

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.

6e. Use camelCase for properties.

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.

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.



Ok, I think that's it. This is meant as a proposal only - we are
looking for feedback to go forward. Thoughts?

Re: [Proposal] REST API interface

Posted by Matt Franklin <m....@gmail.com>.
On Tue, Jul 16, 2013 at 4:42 PM, Chris Geer <ch...@cxtsoftware.com> wrote:

> On Tue, Jul 16, 2013 at 12:55 PM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
> > In terms of implementation, I will definitely be interested to see how
> > the fields selector works.
> >
> > With respect to response format, all responses will be wrapped in the
> > same way. Will it make sense to create a custom "ApiResponse" class or
> > something of the sort that represents the wrapper. Alternatively could
> > cxf's outgoing interceptors be used to reformat the data response?
> > Same thing for errors.
> >
>
> I don't think we can do this with an interceptor because we would still
> need to communicate to the interceptor the data (total records....) so we
> might as well just wrap the responses.
>
> I was going to model the fields implementation after what we do for Shindig
> since they already have the fileds concept.
>

Ideally, we would have a better way than what we did in Shindig.  I haven't
thought through it much, but it would be nice if we could intercept the
intermediate JSON object and remove fields like you can with JSONObject
form json.org.


>
> >
> >
> > On Tue, Jul 16, 2013 at 2:22 PM, Erin Noe-Payne
> > <er...@gmail.com> wrote:
> > > On Tue, Jul 16, 2013 at 1:53 PM, Chris Geer <ch...@cxtsoftware.com>
> > wrote:
> > >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> > >> <er...@gmail.com>wrote:
> > >>
> > >>> Any further discussion here? I would like to start implementing more
> > >>> of the REST APIs, as it is foundational for the entire angular
> > >>> architecture.
> > >>>
> > >>> My understanding from Matt is that the current apis in trunk are
> > >>> mostly proof of concept - they are not tested and much of the
> > >>> functionality is just stubbed. Are any of the rest api
> implementations
> > >>> in the code base a good working example? Is there other documentation
> > >>> we can reference?
> > >>>
> > >>
> > >> I've been working on the People resource as a "reference" of how I'd
> > like
> > >> to see them done but it's still a work in progress. I need to go back
> > and
> > >> pull out the JSONView stuff and reimplement the "fields" concept.
> > Couple of
> > >> notes:
> > >>
> > >>  - Object representations should be as flat as possible
> > >> and separate requests should be made to nested resources to get nested
> > >> details (i.e. if you have regions and regions/1/regionwidgets, the
> > regions
> > >> representation should not contain an array of regionwidgets)
> > >>  - All methods should return standard HTTP codes. We should document
> > this
> > >> further on the wiki to make sure we all do the same way.
> > >>  - We won't accept partial updates with PUT, we will eventually add
> > PATCH
> > >> to support that in the future
> > >>  - If the "fields" query attribute isn't included in a GET then all
> > fields
> > >> are returned.
> > >
> > > +1 to all of the above
> > >
> > >>  - What is the full meta structure we want to return?
> > >
> > > So this can be fluid. In the case of lists (search or list endpoints)
> > > it should definitely contain pagination and count data. In the case of
> > > individual resources it does not necessarily need to contain anything.
> > > As long as we have the wrapped object then we have the key reserved to
> > > attach metadata as the need arises. One example of what we could use
> > > it for is to contain link information. I.E. a request to /page/1
> > > returns a flat resource, without the regions. Then meta could look
> > > like:
> > >
> > > {
> > >   "meta": {
> > >     "regions": "http://localhost:8080/portal/api/page/1/regions",
> > >     ...
> > >   }
> > > }
> > >
> > >>
> > >>
> > >>>
> > >>> On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> > >>> <er...@gmail.com> wrote:
> > >>> > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> > m.ben.franklin@gmail.com>
> > >>> wrote:
> > >>> >> +1 for every one of Chris' +1s, unless otherwise noted.
> > >>> >>
> > >>> >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <
> chris@cxtsoftware.com>
> > >>> wrote:
> > >>> >>
> > >>> >>> 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
> > >>> >
> > >>> > Well the development in trunk can continue to happen on /rest.
> > Angular
> > >>> > (aka the consuming client for most of these apis) is already
> > happening
> > >>> > in a branch, so those changes can be treated as a rip / replace
> > >>> > easily.
> > >>> >
> > >>> >>>
> > >>> >>> >
> > >>> >>> > 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
> > >>> >
> > >>> > My understanding is that PUT should always be a full object
> replace.
> > A
> > >>> > quick search returns the suggestion to use PATCH, or to use POST
> to a
> > >>> > subresource with a 303 response.
> > >>> >
> > >>> >>
> > >>> >>>
> > >>> >>> >
> > >>> >>> > 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.
> > >>> >>
> > >>> >
> > >>> > Fair enough. In this case I guess I would just be looking for
> > >>> > consistency - will associations be infinitely nest-able. If not,
> what
> > >>> > is the rule to determine where we support more or less deeply
> nested
> > >>> > associations.
> > >>> >
> > >>> >>
> > >>> >>> >
> > >>> >>> > 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?
> > >>> >>>
> > >>> >
> > >>> > We could possibly achieve the same with HTTP headers. I prefer the
> > >>> > object approach for clarity, since custom http headers are less
> > >>> > accessible or discoverable than object structure. I get your point,
> > >>> > but I see the wrapped object approach used commonly in major apis.
> If
> > >>> > it's clearly documented and used consistently across the entire
> api I
> > >>> > don't really see an issue.
> > >>> >
> > >>> >>> >
> > >>> >>> > 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.
> > >>> >>
> > >>> >>
> > >>> >
> > >>> > I don't really know what the implementation looks like. If you
> allow
> > >>> > field filtering only on properties and deliver only properties
> (i.e.
> > >>> > no nested objects / associations) then I would assume it is pretty
> > >>> > straightforward.
> > >>> >>>
> > >>> >>> >
> > >>> >>> > 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?
> > >>> >>> >
> > >>> >>>
> > >>>
> >
>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Tue, Jul 16, 2013 at 12:55 PM, Erin Noe-Payne
<er...@gmail.com>wrote:

> In terms of implementation, I will definitely be interested to see how
> the fields selector works.
>
> With respect to response format, all responses will be wrapped in the
> same way. Will it make sense to create a custom "ApiResponse" class or
> something of the sort that represents the wrapper. Alternatively could
> cxf's outgoing interceptors be used to reformat the data response?
> Same thing for errors.
>

I don't think we can do this with an interceptor because we would still
need to communicate to the interceptor the data (total records....) so we
might as well just wrap the responses.

I was going to model the fields implementation after what we do for Shindig
since they already have the fileds concept.

>
>
> On Tue, Jul 16, 2013 at 2:22 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > On Tue, Jul 16, 2013 at 1:53 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> <er...@gmail.com>wrote:
> >>
> >>> Any further discussion here? I would like to start implementing more
> >>> of the REST APIs, as it is foundational for the entire angular
> >>> architecture.
> >>>
> >>> My understanding from Matt is that the current apis in trunk are
> >>> mostly proof of concept - they are not tested and much of the
> >>> functionality is just stubbed. Are any of the rest api implementations
> >>> in the code base a good working example? Is there other documentation
> >>> we can reference?
> >>>
> >>
> >> I've been working on the People resource as a "reference" of how I'd
> like
> >> to see them done but it's still a work in progress. I need to go back
> and
> >> pull out the JSONView stuff and reimplement the "fields" concept.
> Couple of
> >> notes:
> >>
> >>  - Object representations should be as flat as possible
> >> and separate requests should be made to nested resources to get nested
> >> details (i.e. if you have regions and regions/1/regionwidgets, the
> regions
> >> representation should not contain an array of regionwidgets)
> >>  - All methods should return standard HTTP codes. We should document
> this
> >> further on the wiki to make sure we all do the same way.
> >>  - We won't accept partial updates with PUT, we will eventually add
> PATCH
> >> to support that in the future
> >>  - If the "fields" query attribute isn't included in a GET then all
> fields
> >> are returned.
> >
> > +1 to all of the above
> >
> >>  - What is the full meta structure we want to return?
> >
> > So this can be fluid. In the case of lists (search or list endpoints)
> > it should definitely contain pagination and count data. In the case of
> > individual resources it does not necessarily need to contain anything.
> > As long as we have the wrapped object then we have the key reserved to
> > attach metadata as the need arises. One example of what we could use
> > it for is to contain link information. I.E. a request to /page/1
> > returns a flat resource, without the regions. Then meta could look
> > like:
> >
> > {
> >   "meta": {
> >     "regions": "http://localhost:8080/portal/api/page/1/regions",
> >     ...
> >   }
> > }
> >
> >>
> >>
> >>>
> >>> On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> >>> <er...@gmail.com> wrote:
> >>> > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> m.ben.franklin@gmail.com>
> >>> wrote:
> >>> >> +1 for every one of Chris' +1s, unless otherwise noted.
> >>> >>
> >>> >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
> >>> wrote:
> >>> >>
> >>> >>> 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
> >>> >
> >>> > Well the development in trunk can continue to happen on /rest.
> Angular
> >>> > (aka the consuming client for most of these apis) is already
> happening
> >>> > in a branch, so those changes can be treated as a rip / replace
> >>> > easily.
> >>> >
> >>> >>>
> >>> >>> >
> >>> >>> > 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
> >>> >
> >>> > My understanding is that PUT should always be a full object replace.
> A
> >>> > quick search returns the suggestion to use PATCH, or to use POST to a
> >>> > subresource with a 303 response.
> >>> >
> >>> >>
> >>> >>>
> >>> >>> >
> >>> >>> > 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.
> >>> >>
> >>> >
> >>> > Fair enough. In this case I guess I would just be looking for
> >>> > consistency - will associations be infinitely nest-able. If not, what
> >>> > is the rule to determine where we support more or less deeply nested
> >>> > associations.
> >>> >
> >>> >>
> >>> >>> >
> >>> >>> > 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?
> >>> >>>
> >>> >
> >>> > We could possibly achieve the same with HTTP headers. I prefer the
> >>> > object approach for clarity, since custom http headers are less
> >>> > accessible or discoverable than object structure. I get your point,
> >>> > but I see the wrapped object approach used commonly in major apis. If
> >>> > it's clearly documented and used consistently across the entire api I
> >>> > don't really see an issue.
> >>> >
> >>> >>> >
> >>> >>> > 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.
> >>> >>
> >>> >>
> >>> >
> >>> > I don't really know what the implementation looks like. If you allow
> >>> > field filtering only on properties and deliver only properties (i.e.
> >>> > no nested objects / associations) then I would assume it is pretty
> >>> > straightforward.
> >>> >>>
> >>> >>> >
> >>> >>> > 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?
> >>> >>> >
> >>> >>>
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
In terms of implementation, I will definitely be interested to see how
the fields selector works.

With respect to response format, all responses will be wrapped in the
same way. Will it make sense to create a custom "ApiResponse" class or
something of the sort that represents the wrapper. Alternatively could
cxf's outgoing interceptors be used to reformat the data response?
Same thing for errors.


On Tue, Jul 16, 2013 at 2:22 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> On Tue, Jul 16, 2013 at 1:53 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> <er...@gmail.com>wrote:
>>
>>> Any further discussion here? I would like to start implementing more
>>> of the REST APIs, as it is foundational for the entire angular
>>> architecture.
>>>
>>> My understanding from Matt is that the current apis in trunk are
>>> mostly proof of concept - they are not tested and much of the
>>> functionality is just stubbed. Are any of the rest api implementations
>>> in the code base a good working example? Is there other documentation
>>> we can reference?
>>>
>>
>> I've been working on the People resource as a "reference" of how I'd like
>> to see them done but it's still a work in progress. I need to go back and
>> pull out the JSONView stuff and reimplement the "fields" concept. Couple of
>> notes:
>>
>>  - Object representations should be as flat as possible
>> and separate requests should be made to nested resources to get nested
>> details (i.e. if you have regions and regions/1/regionwidgets, the regions
>> representation should not contain an array of regionwidgets)
>>  - All methods should return standard HTTP codes. We should document this
>> further on the wiki to make sure we all do the same way.
>>  - We won't accept partial updates with PUT, we will eventually add PATCH
>> to support that in the future
>>  - If the "fields" query attribute isn't included in a GET then all fields
>> are returned.
>
> +1 to all of the above
>
>>  - What is the full meta structure we want to return?
>
> So this can be fluid. In the case of lists (search or list endpoints)
> it should definitely contain pagination and count data. In the case of
> individual resources it does not necessarily need to contain anything.
> As long as we have the wrapped object then we have the key reserved to
> attach metadata as the need arises. One example of what we could use
> it for is to contain link information. I.E. a request to /page/1
> returns a flat resource, without the regions. Then meta could look
> like:
>
> {
>   "meta": {
>     "regions": "http://localhost:8080/portal/api/page/1/regions",
>     ...
>   }
> }
>
>>
>>
>>>
>>> On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>>> <er...@gmail.com> wrote:
>>> > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <m....@gmail.com>
>>> wrote:
>>> >> +1 for every one of Chris' +1s, unless otherwise noted.
>>> >>
>>> >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >>
>>> >>> 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
>>> >
>>> > Well the development in trunk can continue to happen on /rest. Angular
>>> > (aka the consuming client for most of these apis) is already happening
>>> > in a branch, so those changes can be treated as a rip / replace
>>> > easily.
>>> >
>>> >>>
>>> >>> >
>>> >>> > 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
>>> >
>>> > My understanding is that PUT should always be a full object replace. A
>>> > quick search returns the suggestion to use PATCH, or to use POST to a
>>> > subresource with a 303 response.
>>> >
>>> >>
>>> >>>
>>> >>> >
>>> >>> > 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.
>>> >>
>>> >
>>> > Fair enough. In this case I guess I would just be looking for
>>> > consistency - will associations be infinitely nest-able. If not, what
>>> > is the rule to determine where we support more or less deeply nested
>>> > associations.
>>> >
>>> >>
>>> >>> >
>>> >>> > 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?
>>> >>>
>>> >
>>> > We could possibly achieve the same with HTTP headers. I prefer the
>>> > object approach for clarity, since custom http headers are less
>>> > accessible or discoverable than object structure. I get your point,
>>> > but I see the wrapped object approach used commonly in major apis. If
>>> > it's clearly documented and used consistently across the entire api I
>>> > don't really see an issue.
>>> >
>>> >>> >
>>> >>> > 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.
>>> >>
>>> >>
>>> >
>>> > I don't really know what the implementation looks like. If you allow
>>> > field filtering only on properties and deliver only properties (i.e.
>>> > no nested objects / associations) then I would assume it is pretty
>>> > straightforward.
>>> >>>
>>> >>> >
>>> >>> > 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?
>>> >>> >
>>> >>>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Tue, Jul 16, 2013 at 1:53 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> Any further discussion here? I would like to start implementing more
>> of the REST APIs, as it is foundational for the entire angular
>> architecture.
>>
>> My understanding from Matt is that the current apis in trunk are
>> mostly proof of concept - they are not tested and much of the
>> functionality is just stubbed. Are any of the rest api implementations
>> in the code base a good working example? Is there other documentation
>> we can reference?
>>
>
> I've been working on the People resource as a "reference" of how I'd like
> to see them done but it's still a work in progress. I need to go back and
> pull out the JSONView stuff and reimplement the "fields" concept. Couple of
> notes:
>
>  - Object representations should be as flat as possible
> and separate requests should be made to nested resources to get nested
> details (i.e. if you have regions and regions/1/regionwidgets, the regions
> representation should not contain an array of regionwidgets)
>  - All methods should return standard HTTP codes. We should document this
> further on the wiki to make sure we all do the same way.
>  - We won't accept partial updates with PUT, we will eventually add PATCH
> to support that in the future
>  - If the "fields" query attribute isn't included in a GET then all fields
> are returned.

+1 to all of the above

>  - What is the full meta structure we want to return?

So this can be fluid. In the case of lists (search or list endpoints)
it should definitely contain pagination and count data. In the case of
individual resources it does not necessarily need to contain anything.
As long as we have the wrapped object then we have the key reserved to
attach metadata as the need arises. One example of what we could use
it for is to contain link information. I.E. a request to /page/1
returns a flat resource, without the regions. Then meta could look
like:

{
  "meta": {
    "regions": "http://localhost:8080/portal/api/page/1/regions",
    ...
  }
}

>
>
>>
>> On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <m....@gmail.com>
>> wrote:
>> >> +1 for every one of Chris' +1s, unless otherwise noted.
>> >>
>> >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >>
>> >>> 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
>> >
>> > Well the development in trunk can continue to happen on /rest. Angular
>> > (aka the consuming client for most of these apis) is already happening
>> > in a branch, so those changes can be treated as a rip / replace
>> > easily.
>> >
>> >>>
>> >>> >
>> >>> > 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
>> >
>> > My understanding is that PUT should always be a full object replace. A
>> > quick search returns the suggestion to use PATCH, or to use POST to a
>> > subresource with a 303 response.
>> >
>> >>
>> >>>
>> >>> >
>> >>> > 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.
>> >>
>> >
>> > Fair enough. In this case I guess I would just be looking for
>> > consistency - will associations be infinitely nest-able. If not, what
>> > is the rule to determine where we support more or less deeply nested
>> > associations.
>> >
>> >>
>> >>> >
>> >>> > 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?
>> >>>
>> >
>> > We could possibly achieve the same with HTTP headers. I prefer the
>> > object approach for clarity, since custom http headers are less
>> > accessible or discoverable than object structure. I get your point,
>> > but I see the wrapped object approach used commonly in major apis. If
>> > it's clearly documented and used consistently across the entire api I
>> > don't really see an issue.
>> >
>> >>> >
>> >>> > 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.
>> >>
>> >>
>> >
>> > I don't really know what the implementation looks like. If you allow
>> > field filtering only on properties and deliver only properties (i.e.
>> > no nested objects / associations) then I would assume it is pretty
>> > straightforward.
>> >>>
>> >>> >
>> >>> > 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?
>> >>> >
>> >>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Tue, Jul 16, 2013 at 6:20 PM, Matt Franklin <m....@gmail.com>wrote:

> On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
>
> > On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> > <er...@gmail.com>wrote:
> >
> > > Any further discussion here? I would like to start implementing more
> > > of the REST APIs, as it is foundational for the entire angular
> > > architecture.
> > >
> > > My understanding from Matt is that the current apis in trunk are
> > > mostly proof of concept - they are not tested and much of the
> > > functionality is just stubbed. Are any of the rest api implementations
> > > in the code base a good working example? Is there other documentation
> > > we can reference?
> > >
> >
> > I've been working on the People resource as a "reference" of how I'd like
> > to see them done but it's still a work in progress. I need to go back and
> > pull out the JSONView stuff and reimplement the "fields" concept. Couple
> of
> > notes:
> >
> >  - Object representations should be as flat as possible
> > and separate requests should be made to nested resources to get nested
> > details (i.e. if you have regions and regions/1/regionwidgets, the
> regions
> > representation should not contain an array of regionwidgets)
> >
>
> I am concerned about the round trips to support this when rendering the
> page.  With any page that has a sufficient number of gadgets, adding to the
> number of requests becomes problematic.
>

I agree and still thinks its required. We need to make sure that the
representation we present with GET is the same one we accept with PUT. So
if we want Page to return a rich document, then it should accept a rich
document which would eliminate the need for separate resources for
Regions/RegionsWidgets....

Erin, won't Angular help with this with caching?

>
>
> >  - All methods should return standard HTTP codes. We should document this
> > further on the wiki to make sure we all do the same way.
> >  - We won't accept partial updates with PUT, we will eventually add PATCH
> > to support that in the future
> >  - If the "fields" query attribute isn't included in a GET then all
> fields
> > are returned.
> >  - What is the full meta structure we want to return?
> >
> >
> > >
> > > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> > > <er...@gmail.com> wrote:
> > > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> > m.ben.franklin@gmail.com>
> > > wrote:
> > > >> +1 for every one of Chris' +1s, unless otherwise noted.
> > > >>
> > > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
> > > wrote:
> > > >>
> > > >>> 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
> > > >
> > > > Well the development in trunk can continue to happen on /rest.
> Angular
> > > > (aka the consuming client for most of these apis) is already
> happening
> > > > in a branch, so those changes can be treated as a rip / replace
> > > > easily.
> > > >
> > > >>>
> > > >>> >
> > > >>> > 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
> > > >
> > > > My understanding is that PUT should always be a full object replace.
> A
> > > > quick search returns the suggestion to use PATCH, or to use POST to a
> > > > subresource with a 303 response.
> > > >
> > > >>
> > > >>>
> > > >>> >
> > > >>> > 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.
> > > >>
> > > >
> > > > Fair enough. In this case I guess I would just be looking for
> > > > consistency - will associations be infinitely nest-able. If not, what
> > > > is the rule to determine where we support more or less deeply nested
> > > > associations.
> > > >
> > > >>
> > > >>> >
> > > >>> > 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?
> > > >>>
> > > >
> > > > We could possibly achieve the same with HTTP headers. I prefer the
> > > > object approach for clarity, since custom http headers are less
> > > > accessible or discoverable than object structure. I get your point,
> > > > but I see the wrapped object approach used commonly in major apis. If
> > > > it's clearly documented and used consistently across the entire api I
> > > > don't really see an issue.
> > > >
> > > >>> >
> > > >>> > 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.
> > > >>
> > > >>
> > > >
> > > > I don't really know what the implementation looks like. If you allow
> > > > field filtering only on properties and deliver only properties (i.e.
> > > > no nested objects / associations) then I would assume it is pretty
> > > > straightforward.
> > > >>>
> > > >>> >
> > > >>> > 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?
> > > >>> >
> > > >>>
> > >
> >
>

Re: [Proposal] REST API interface

Posted by Matt Franklin <m....@gmail.com>.

> On Jul 22, 2013, at 14:58, Erin Noe-Payne <er...@gmail.com> wrote:
> 
> - Simple solution: All rest response models are flat. We ignore any
> nested data, and just have separate endpoints to deliver that data.
> I.E. Every model in the org.apache.rave.rest.model package has only
> properties of "primitive" types, with no lists, no other classes. That
> is NOT currently the case. Then the fields interceptor checks for the
> presence of a fields argument. If not present, the object is delivered
> as is. If present the argument (a string) is split by comma and only
> the matched properties are delivered. The fields qs argument only has
> to support comma-delimited list of property names.
> Ex: ?fields=name,pageType
> //returns a page or pages with only name and pageType properties
> 
> - Complicated solution: All rest response models include references to
> their nested data. This is the currently the case, and can be seen in
> org.apache.rave.rest.model.Page. The fields interceptor checks for
> presence of fields qs argument. If not present it strips all nested
> data from the models and only returns properties. If it is present, it
> parses the argument and updates the data. The fields argument needs to
> support a more complicated syntax that allows the requesting of nested
> data. I would copy the syntax of facebook's graph search api, which
> has a pretty readable solution. You allow for .fields and .limit on
> fields, which can be nested.
> Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> //returns a page or pages with name and pageType properties, nested
> list of regions (max of 2) with nested list of regionWidgets with only
> properties of widgetId and locked
> 
> In all cases, id should always be returned.
> I think the algorithm in the simple solution is easy.
> In a sense the algorithm in the second should be simple, because the
> service layer is already getting all the nested data, and you are just
> stripping it off. Not sure what the performance implications of that
> are though.

The complicated method should be pretty easy to manage with a simple state machine.  

> 
>> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> <er...@gmail.com>wrote:
>> 
>>> Going back to the discussion on field selection - I am currently going
>>> through the exercise of writing out the Resource interfaces to define
>>> our endpoints.  There is a set of generic query string parameters that
>>> we wish to support on all or many of the endpoints - fields (any get
>>> request), limit / offset (any get request that returns a list).
>>> 
>>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>>> the appropriate logic, I assume we would want to take advantage of cxf
>>> interceptors [1] to intelligently and generically handle those qs
>>> arguments?
>> 
>> I like the concept but I'm not sure how we generically filter, especially
>> with nested data. I'd love to see it work that way though. Interceptors are
>> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>> Thoughts?
>> 
>>> 
>>> [1] http://cxf.apache.org/docs/interceptors.html
>>> 
>>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>> <er...@gmail.com> wrote:
>>>> Ok, so the endpoint is now working. Any thoughts about the
>>>> JsonResponseWrapper approach? Does that seem like the best way to get
>>>> wrapped responses?
>>>> 
>>>> For the next step I would like to start writing out all of the
>>>> resource interfaces so that we can begin writing angular $resource
>>>> services against them.
>>>> 
>>>> On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>>> <er...@gmail.com> wrote:
>>>>> Awesome, thanks Chris. Not sure I would have ever figured that one
>>> out...
>>>>> 
>>>>> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>>>>> Erin,
>>>>>> 
>>>>>> I got it working, at least the CXF part. Couple things:
>>>>>> 
>>>>>> 1) In the interface, make sure to annotate the @GET methods
>>>>>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>>>>> attributes from variable signatures. I know Intellij puts those in
>>> there
>>>>>> but they cause problems. Only the interface should be annotated.
>>>>>> 
>>>>>> Chris
>>>>>> 
>>>>>> 
>>>>>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>> erin.noe.payne@gmail.com>wrote:
>>>>>> 
>>>>>>> Review board is not accepting my patch and is not accepting the valid
>>>>>>> file paths. I have attached the patch as a file to the review.
>>>>>>> 
>>>>>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>>>>>>> Erin, I'm not seeing a patch posted up there.
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>> 
>>>>>>>>> I was never able to hit the endpoint as expected. I've posted the
>>>>>>>>> patch on the review board if anyone can take a look and offer
>>> advice -
>>>>>>>>> https://reviews.apache.org/r/12777/.
>>>>>>>>> 
>>>>>>>>> Thanks
>>>>>>>>> 
>>>>>>>>> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>>>> 
>>>>>>> wrote:
>>>>>>>>>>> On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>>>>>>>>>> 
>>>>>>>>>>> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>> chris@cxtsoftware.com
>>>>>>>>> <javascript:;>>
>>>>>>>>>>> wrote:
>>>>>>>>>>>> In the xml file you need to create the bean, then reference
>>> it in
>>>>>>> the
>>>>>>>>>>>> server element near the top. Other than that...no, that
>>> should be
>>>>>>>>> all. I
>>>>>>>>>>>> assume you set the Path attribute on the resource.
>>>>>>>>>>> I did. I'm also messing around with the service injection,
>>> which may
>>>>>>>>>>> be the issue. Haven't gotten it to work yet though.
>>>>>>>>>>> 
>>>>>>>>>>>> I thought we were going to do
>>>>>>>>> pages/<id>/regions/<id>/regionwidgets/<id>
>>>>>>>>>>>> since it makes no sense to manage a region widget outside a
>>> region
>>>>>>>>>>> outside
>>>>>>>>>>>> a page?
>>>>>>>>>>> Possibly. Right now I'm just trying to do a proof of concept
>>> with
>>>>>>> the
>>>>>>>>>>> wrapped json object so I picked something simple with the
>>> service and
>>>>>>>>>>> rest models already in place.
>>>>>>>>>>> 
>>>>>>>>>>> In general though I don't see any value to dealing with region
>>>>>>> widgets
>>>>>>>>>>> as a nested resource (pages/:id/regions/:id...) over just
>>> dealing
>>>>>>> with
>>>>>>>>>>> them directly. It's just adding weight to the pages controller,
>>>>>>> rather
>>>>>>>>>>> than breaking them up and dealing with resource concerns
>>> separately.
>>>>>>>>>>> 
>>>>>>>>>>> I get what you're saying about regions and regionwidgets only
>>> making
>>>>>>>>>>> sense in the context of a page, but you could say the same
>>> thing for
>>>>>>>>>>> any 1-many associated resource. Both entities are always
>>> uniquely
>>>>>>>>>>> identified, so why not deal with them individually? I see an
>>> upside
>>>>>>> of
>>>>>>>>>>> simpler code, consistent api endpoints, and I see no downside.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> Honestly, my hope is that someday they aren't uniquely
>>> identified and
>>>>>>> are
>>>>>>>>>> really sun objects unlike JPA today. But that is a longer
>>>>>>> conversation.
>>>>>>>>>> 
>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>> 
>>>>>>>>>>>>> I'm trying to register a new endpoint for regionWidgets. I've
>>>>>>> added
>>>>>>>>>>>>> the interface and default implementation, and created /
>>> registered
>>>>>>>>> the
>>>>>>>>>>>>> bean in cxf-applicationContext.xml.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> However, when I hit the endpoint I get an error:
>>>>>>>>>>>>> [INFO] [talledLocalContainer] WARN :
>>>>>>>>>>>>> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>>>>>> request
>>>>>>>>>>>>> path "/portal/api/rest/regionWidgets/1" is found, Relative
>>> Path:
>>>>>>> /1,
>>>>>>>>>>>>> HTTP Method: GET, ContentType: */*, Accept:
>>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>>>>>>>>>>>> Please enable FINE/TRACE log level for more details.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> Is there anything else I need to do in order to create and
>>>>>>> register a
>>>>>>>>>>>>> new endpoint?
>>>>>>>>>>>>> 
>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>>>>>>>>>>>> <er...@gmail.com> wrote:
>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>>>>>>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>>>>>>>>>>>> m.ben.franklin@gmail.com>
>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>>>>>>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>> Any further discussion here? I would like to start
>>>>>>>>> implementing
>>>>>>>>>>>>> more
>>>>>>>>>>>>>>>>>>> of the REST APIs, as it is foundational for the
>>> entire
>>>>>>>>> angular
>>>>>>>>>>>>>>>>>>> architecture.
>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>> My understanding from Matt is that the current apis
>>> in
>>>>>>> trunk
>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>>> mostly proof of concept - they are not tested and
>>> much of
>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> functionality is just stubbed. Are any of the rest
>>> api
>>>>>>>>>>>>> implementations
>>>>>>>>>>>>>>>>>>> in the code base a good working example? Is there
>>> other
>>>>>>>>>>>>> documentation
>>>>>>>>>>>>>>>>>>> we can reference?
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> I've been working on the People resource as a
>>> "reference"
>>>>>>> of
>>>>>>>>> how
>>>>>>>>>>> I'd
>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>> to see them done but it's still a work in progress. I
>>> need
>>>>>>> to
>>>>>>>>> go
>>>>>>>>>>>>> back
>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>> pull out the JSONView stuff and reimplement the
>>> "fields"
>>>>>>>>> concept.
>>>>>>>>>>>>>>>> Couple of
>>>>>>>>>>>>>>>>>> notes:
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> - Object representations should be as flat as
>>> possible
>>>>>>>>>>>>>>>>>> and separate requests should be made to nested
>>> resources to
>>>>>>>>> get
>>>>>>>>>>>>> nested
>>>>>>>>>>>>>>>>>> details (i.e. if you have regions and
>>>>>>> regions/1/regionwidgets,
>>>>>>>>>>> the
>>>>>>>>>>>>>>>> regions
>>>>>>>>>>>>>>>>>> representation should not contain an array of
>>>>>>> regionwidgets)
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>> I am concerned about the round trips to support this
>>> when
>>>>>>>>>>> rendering
>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> page.  With any page that has a sufficient number of
>>>>>>> gadgets,
>>>>>>>>>>> adding
>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> number of requests becomes problematic.
>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>> I see that rule applying to the "standard" rest
>>> endpoints for
>>>>>>>>> crud
>>>>>>>>>>>>>>>> operations on resources. We
>>> 

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Thu, Aug 1, 2013 at 11:32 AM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Wed, Jul 31, 2013 at 11:19 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> On Mon, Jul 29, 2013 at 9:59 AM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > On Mon, Jul 29, 2013 at 1:54 AM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> On Thu, Jul 25, 2013 at 11:12 AM, Erin Noe-Payne
>> >> <er...@gmail.com>wrote:
>> >>
>> >>> I'm not entirely sure how to proceed at the moment. For now I will
>> >>> start work at the repository layer and try to implement consistent
>> >>> crud operations to support the REST api.
>> >>>
>> >>
>> >> Erin, on the CXF 2.7 migration page I saw this.
>> >>
>> >>
>> >>    - org.apache.cxf.jaxrs.ext.RequestHandler and
>> >>    org.apache.cxf.jaxrs.ext.ResponseHandler (use
>> >>    javax.ws.rs.container.ContainerRequestFilter and
>> >>    javax.ws.rs.container.ContainerResponseFilter instead).
>> >>
>> > Thanks Chris, I'll take a look.
>> >
>>
>> It looks like ContainerRequestFilter / ContainerResponseFilter do give
>> me access to valid request and response context objects that I can act
>> upon. So these are the interfaces we will want to use for setting up
>> filters.
>>
>> Also based on some more reading of CXF docs, it looks to me like we
>> can use sub-resource locators [1] as an approach for breaking apart
>> the page / region / regionWidget controllers while still using the
>> /pages/:id/regions/:id/regionWidgets/:id url paths.
>>
>> I have submitted a patch on the review board [2] with a partial
>> implementation (RB is again preventing me from uploading the patch
>> directly so it is an attachment on the review). Look at the resolution
>> from PagesResource to RegionsResource. If there are no complaints I am
>> going to move forward with this approach.
>>
>> [1]
>> http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Subresourcelocators
>> .
>> [2] https://reviews.apache.org/r/13119/
>
>
> Erin,
>
> On your RegionWidgetsResource, wouldn't you want the class level path to be
> @Path("/pages/{pageId}/regions/{regionsId}/regionWidgets")
>
> If you have it with just @Path("/pages") it doesn't really nest the
> regionWidgets under the correct page.
>

Good catch, thank you. I actually do not want a @Path annotation at
the class level at all. I want RegionWidgetsResource to be a
dynamically resolved subresource. It will be only accessible via the
RegionsResource "getRegionWidgetsResource" method, which is in turn
only accessible via PeopleResource's "getRegionsResource".

>>
>>
>> >>
>> >> So, it looks like the docs are a little out of date. The
>> >> ContainerResponseFilter handler method gets two params, Request Context
>> and
>> >> Response Context. That might give you what you need. I haven't played
>> with
>> >> it yet but it's worth a look.
>> >>
>> >> Chris
>> >>
>> >>
>> >>
>> >>> On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
>> >>> <er...@gmail.com> wrote:
>> >>> > On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com>
>> >>> wrote:
>> >>> >> What about this:
>> >>> >>
>> >>> >>
>> >>>
>> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
>> >>> >>
>> >>> >
>> >>> > This is referring to a RequestHandler, not a ResponseHandler. In the
>> >>> > request handler the Message object does have correct request uri
>> data,
>> >>> > etc, but I don't have access to the Response object yet.
>> >>> >
>> >>> >> The only thing I don't like about not returning Response objects is
>> it
>> >>> >> doesn't let the method set HTTP specific stuff. Which just means we
>> need
>> >>> >> really really good filters. For example, a create should set the
>> >>> Location
>> >>> >> HTTP header field with the proper URL to the newly created object.
>> >>> >>
>> >>> >
>> >>> > That's fair. And the controllers could return response objects and
>> >>> > following filters could just iteratively return
>> >>> > Response.fromResponse(). But if we take a step back from filters or
>> >>> > interceptors or whatever implementation approach, here's the problem
>> >>> > I'm trying to solve:
>> >>> >
>> >>> > Taking your Location header example - all requests to get or create
>> an
>> >>> > entity should have the location header set to the canonical url of
>> the
>> >>> > resource. Post requests creating a new resource should have a
>> location
>> >>> > header pointing to the newly created resource. That is universally
>> >>> > true, and I should be able to write that code generically. I do not
>> >>> > want to have to set the location header in every controller for every
>> >>> > resource that handles the @POST method. That seems like it should be
>> >>> > doable, and filters or interceptors seemed like the way to do it. Now
>> >>> > I'm not so sure.
>> >>> >
>> >>> > So is that a goal worth pursuing, and if yes what is the right
>> approach?
>> >>> >
>> >>> >>
>> >>> >> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <
>> >>> erin.noe.payne@gmail.com>wrote:
>> >>> >>
>> >>> >>> Ok, I'm having trouble setting up filters that are able to access
>> >>> >>> query string parameters to do pagination. I've submitted a review
>> >>> >>> request [1] with my work so far (look at pages, categories, and the
>> >>> >>> filters). My plan was the following workflow -
>> >>> >>>
>> >>> >>> - Request is received and processed by the controller. Controller
>> >>> >>> returns an object <T> or List<T> (Page, Category, etc). For any
>> list
>> >>> >>> resource it gets all entities, and allows the pagination filter to
>> >>> >>> subset.
>> >>> >>> - JsonWrapperResponseFilter process the request and wraps the data
>> >>> >>> object in the wrapper object
>> >>> >>> - PaginationResponseFilter checks if the data object is a list. It
>> >>> >>> retrieves the values of limit and offset QS parameters or sets
>> them to
>> >>> >>> defaults. It then subsets the data and sets appropriate meta
>> fields in
>> >>> >>> the json object.
>> >>> >>>
>> >>> >>> The issue is that the response handler does not give me access (as
>> far
>> >>> >>> as I can tell) to the query string values. Which makes me think I'm
>> >>> >>> missing something, or that this is the wrong way to approach the
>> >>> >>> problem.  Any help or input is appreciated.
>> >>> >>>
>> >>> >>>
>> >>> >>> [1] https://reviews.apache.org/r/12901/
>> >>> >>>
>> >>> >>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <chris@cxtsoftware.com
>> >
>> >>> wrote:
>> >>> >>> > Good point...I forgot Rave is using CXF 2.7.x which includes
>> that new
>> >>> >>> > stuff. That would be a better choice, plus it wouldn't tie us to
>> CXF.
>> >>> >>> >
>> >>> >>> >
>> >>> >>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
>> >>> >>> > <er...@gmail.com>wrote:
>> >>> >>> >
>> >>> >>> >> Slight update on this journey of discovery - it looks like what
>> we
>> >>> >>> >> actually want to use is not interceptors, but jaxrs filters.
>> See:
>> >>> >>> >> http://cxf.apache.org/docs/jax-rs-filters.html
>> >>> >>> >>
>> >>> >>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >>> >
>> >>> >>> >> wrote:
>> >>> >>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>> >>> >>> >> erin.noe.payne@gmail.com>wrote:
>> >>> >>> >> >
>> >>> >>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <
>> >>> chris@cxtsoftware.com>
>> >>> >>> >> >> wrote:
>> >>> >>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>> >>> >>> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >>> >> >> >
>> >>> >>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
>> >>> >>> chris@cxtsoftware.com>
>> >>> >>> >> >> >> wrote:
>> >>> >>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> >>> >>> >> >> >> > <er...@gmail.com>wrote:
>> >>> >>> >> >> >> >
>> >>> >>> >> >> >> >> - Simple solution: All rest response models are flat.
>> We
>> >>> ignore
>> >>> >>> >> any
>> >>> >>> >> >> >> >> nested data, and just have separate endpoints to
>> deliver
>> >>> that
>> >>> >>> >> data.
>> >>> >>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model
>> package
>> >>> has
>> >>> >>> >> only
>> >>> >>> >> >> >> >> properties of "primitive" types, with no lists, no
>> other
>> >>> >>> classes.
>> >>> >>> >> >> That
>> >>> >>> >> >> >> >> is NOT currently the case. Then the fields interceptor
>> >>> checks
>> >>> >>> for
>> >>> >>> >> the
>> >>> >>> >> >> >> >> presence of a fields argument. If not present, the
>> object
>> >>> is
>> >>> >>> >> >> delivered
>> >>> >>> >> >> >> >> as is. If present the argument (a string) is split by
>> >>> comma and
>> >>> >>> >> only
>> >>> >>> >> >> >> >> the matched properties are delivered. The fields qs
>> >>> argument
>> >>> >>> only
>> >>> >>> >> has
>> >>> >>> >> >> >> >> to support comma-delimited list of property names.
>> >>> >>> >> >> >> >> Ex: ?fields=name,pageType
>> >>> >>> >> >> >> >> //returns a page or pages with only name and pageType
>> >>> >>> properties
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >> >
>> >>> >>> >> >> >> > I like the simple solution. I think the CRUD part of
>> the API
>> >>> >>> should
>> >>> >>> >> >> be as
>> >>> >>> >> >> >> > flat as possible like Erin suggested and we have
>> "special"
>> >>> end
>> >>> >>> >> points
>> >>> >>> >> >> to
>> >>> >>> >> >> >> > get back hierarchical data when needed, i.e. page
>> rendering.
>> >>> >>> >> >> >> >
>> >>> >>> >> >> >>
>> >>> >>> >> >> >> Just to make sure we are on the same page, my proposal is
>> >>> that in
>> >>> >>> >> both
>> >>> >>> >> >> >> cases a get request without any special query string will
>> >>> return
>> >>> >>> only
>> >>> >>> >> >> >> flat data. The difference is that in the second case the
>> >>> fields
>> >>> >>> query
>> >>> >>> >> >> >> parameter will support a syntax that CAN deliver nested
>> data
>> >>> in a
>> >>> >>> >> >> >> single request.
>> >>> >>> >> >> >>
>> >>> >>> >> >> >
>> >>> >>> >> >> > That confuses me. I thought the whole point of the
>> "special"
>> >>> end
>> >>> >>> point
>> >>> >>> >> >> was
>> >>> >>> >> >> > to handle things like page rendering in one query which
>> would
>> >>> >>> require
>> >>> >>> >> >> > hierarchical data every time. Why force the use of query
>> string
>> >>> >>> >> params to
>> >>> >>> >> >> > get that?
>> >>> >>> >> >> >
>> >>> >>> >> >>
>> >>> >>> >> >> I was speaking in reference to the standard endpoints. The
>> >>> >>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
>> >>> >>> specific
>> >>> >>> >> >> client need for a complex nested data set. It will always
>> return
>> >>> >>> >> >> hierarchical data, will probably not support field selection
>> at
>> >>> all.
>> >>> >>> >> >>
>> >>> >>> >> >> The standard endpoints will by default return flat data. They
>> >>> will
>> >>> >>> >> >> support field selection. If we choose to implement the more
>> >>> complex
>> >>> >>> >> >> field selection, then they will allow you to request nested
>> data
>> >>> >>> >> >> through the field selection syntax.
>> >>> >>> >> >>
>> >>> >>> >> >
>> >>> >>> >> > ok
>> >>> >>> >> >
>> >>> >>> >> >>
>> >>> >>> >> >> >>
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >> >> - Complicated solution: All rest response models
>> include
>> >>> >>> >> references
>> >>> >>> >> >> to
>> >>> >>> >> >> >> >> their nested data. This is the currently the case, and
>> can
>> >>> be
>> >>> >>> >> seen in
>> >>> >>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor
>> >>> checks
>> >>> >>> for
>> >>> >>> >> >> >> >> presence of fields qs argument. If not present it
>> strips
>> >>> all
>> >>> >>> >> nested
>> >>> >>> >> >> >> >> data from the models and only returns properties. If
>> it is
>> >>> >>> >> present,
>> >>> >>> >> >> it
>> >>> >>> >> >> >> >> parses the argument and updates the data. The fields
>> >>> argument
>> >>> >>> >> needs
>> >>> >>> >> >> to
>> >>> >>> >> >> >> >> support a more complicated syntax that allows the
>> >>> requesting of
>> >>> >>> >> >> nested
>> >>> >>> >> >> >> >> data. I would copy the syntax of facebook's graph
>> search
>> >>> api,
>> >>> >>> >> which
>> >>> >>> >> >> >> >> has a pretty readable solution. You allow for .fields
>> and
>> >>> >>> .limit
>> >>> >>> >> on
>> >>> >>> >> >> >> >> fields, which can be nested.
>> >>> >>> >> >> >> >> Ex:
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >>
>> >>> >>> >> >>
>> >>> >>> >>
>> >>> >>>
>> >>>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >>> >>> >> >> >> >> //returns a page or pages with name and pageType
>> >>> properties,
>> >>> >>> >> nested
>> >>> >>> >> >> >> >> list of regions (max of 2) with nested list of
>> >>> regionWidgets
>> >>> >>> with
>> >>> >>> >> >> only
>> >>> >>> >> >> >> >> properties of widgetId and locked
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >> >> In all cases, id should always be returned.
>> >>> >>> >> >> >> >> I think the algorithm in the simple solution is easy.
>> >>> >>> >> >> >> >> In a sense the algorithm in the second should be
>> simple,
>> >>> >>> because
>> >>> >>> >> the
>> >>> >>> >> >> >> >> service layer is already getting all the nested data,
>> and
>> >>> you
>> >>> >>> are
>> >>> >>> >> >> just
>> >>> >>> >> >> >> >> stripping it off. Not sure what the performance
>> >>> implications of
>> >>> >>> >> that
>> >>> >>> >> >> >> >> are though.
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>> >>> >>> >> chris@cxtsoftware.com>
>> >>> >>> >> >> >> wrote:
>> >>> >>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >>> >>> >> >> >> >> > <er...@gmail.com>wrote:
>> >>> >>> >> >> >> >> >
>> >>> >>> >> >> >> >> >> Going back to the discussion on field selection - I
>> am
>> >>> >>> >> currently
>> >>> >>> >> >> >> going
>> >>> >>> >> >> >> >> >> through the exercise of writing out the Resource
>> >>> interfaces
>> >>> >>> to
>> >>> >>> >> >> define
>> >>> >>> >> >> >> >> >> our endpoints.  There is a set of generic query
>> string
>> >>> >>> >> parameters
>> >>> >>> >> >> >> that
>> >>> >>> >> >> >> >> >> we wish to support on all or many of the endpoints -
>> >>> fields
>> >>> >>> >> (any
>> >>> >>> >> >> get
>> >>> >>> >> >> >> >> >> request), limit / offset (any get request that
>> returns a
>> >>> >>> list).
>> >>> >>> >> >> >> >> >>
>> >>> >>> >> >> >> >> >> Rather than writing each endpoint to accept
>> >>> QueryParam()'s
>> >>> >>> and
>> >>> >>> >> >> repeat
>> >>> >>> >> >> >> >> >> the appropriate logic, I assume we would want to
>> take
>> >>> >>> >> advantage of
>> >>> >>> >> >> >> cxf
>> >>> >>> >> >> >> >> >> interceptors [1] to intelligently and generically
>> handle
>> >>> >>> those
>> >>> >>> >> qs
>> >>> >>> >> >> >> >> >> arguments?
>> >>> >>> >> >> >> >> >>
>> >>> >>> >> >> >> >> >
>> >>> >>> >> >> >> >> > I like the concept but I'm not sure how we
>> generically
>> >>> >>> filter,
>> >>> >>> >> >> >> especially
>> >>> >>> >> >> >> >> > with nested data. I'd love to see it work that way
>> >>> though.
>> >>> >>> >> >> >> Interceptors
>> >>> >>> >> >> >> >> are
>> >>> >>> >> >> >> >> > pretty easy to use, it's the filter algorithm I
>> haven't
>> >>> >>> figured
>> >>> >>> >> out
>> >>> >>> >> >> >> yet.
>> >>> >>> >> >> >> >> > Thoughts?
>> >>> >>> >> >> >> >> >
>> >>> >>> >> >> >> >> >>
>> >>> >>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >>> >>> >> >> >> >> >>
>> >>> >>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >>> >>> >> >> >> >> >> <er...@gmail.com> wrote:
>> >>> >>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts
>> >>> about the
>> >>> >>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like
>> the
>> >>> best
>> >>> >>> >> way
>> >>> >>> >> >> to
>> >>> >>> >> >> >> get
>> >>> >>> >> >> >> >> >> > wrapped responses?
>> >>> >>> >> >> >> >> >> >
>> >>> >>> >> >> >> >> >> > For the next step I would like to start writing
>> out
>> >>> all of
>> >>> >>> >> the
>> >>> >>> >> >> >> >> >> > resource interfaces so that we can begin writing
>> >>> angular
>> >>> >>> >> >> $resource
>> >>> >>> >> >> >> >> >> > services against them.
>> >>> >>> >> >> >> >> >> >
>> >>> >>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >>> >>> >> >> >> >> >> > <er...@gmail.com> wrote:
>> >>> >>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever
>> >>> figured
>> >>> >>> >> that
>> >>> >>> >> >> one
>> >>> >>> >> >> >> >> >> out...
>> >>> >>> >> >> >> >> >> >>
>> >>> >>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> >>> >>> >> >> >> chris@cxtsoftware.com>
>> >>> >>> >> >> >> >> >> wrote:
>> >>> >>> >> >> >> >> >> >>> Erin,
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple
>> >>> things:
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the
>> @GET
>> >>> >>> methods
>> >>> >>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class,
>> >>> remove
>> >>> >>> the
>> >>> >>> >> >> >> @ParamPath
>> >>> >>> >> >> >> >> >> >>> attributes from variable signatures. I know
>> Intellij
>> >>> >>> puts
>> >>> >>> >> >> those
>> >>> >>> >> >> >> in
>> >>> >>> >> >> >> >> >> there
>> >>> >>> >> >> >> >> >> >>> but they cause problems. Only the interface
>> should
>> >>> be
>> >>> >>> >> >> annotated.
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>> Chris
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne
>> <
>> >>> >>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >>> >> >> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>>> Review board is not accepting my patch and is
>> not
>> >>> >>> >> accepting
>> >>> >>> >> >> the
>> >>> >>> >> >> >> >> valid
>> >>> >>> >> >> >> >> >> >>>> file paths. I have attached the patch as a
>> file to
>> >>> the
>> >>> >>> >> >> review.
>> >>> >>> >> >> >> >> >> >>>>
>> >>> >>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> >>> >>> >> >> >> chris@cxtsoftware.com
>> >>> >>> >> >> >> >> >
>> >>> >>> >> >> >> >> >> wrote:
>> >>> >>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >>> >>> >> >> >> >> >> >>>> >
>> >>> >>> >> >> >> >> >> >>>> >
>> >>> >>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin
>> Noe-Payne <
>> >>> >>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >>> >>> >> >> >> >> >> >>>> >
>> >>> >>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as
>> >>> expected.
>> >>> >>> I've
>> >>> >>> >> >> posted
>> >>> >>> >> >> >> >> the
>> >>> >>> >> >> >> >> >> >>>> >> patch on the review board if anyone can
>> take a
>> >>> look
>> >>> >>> and
>> >>> >>> >> >> offer
>> >>> >>> >> >> >> >> >> advice -
>> >>> >>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >>> >>> >> >> >> >> >> >>>> >>
>> >>> >>> >> >> >> >> >> >>>> >> Thanks
>> >>> >>> >> >> >> >> >> >>>> >>
>> >>> >>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer
>> <
>> >>> >>> >> >> >> >> chris@cxtsoftware.com
>> >>> >>> >> >> >> >> >> >
>> >>> >>> >> >> >> >> >> >>>> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne
>> >>> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris
>> Geer <
>> >>> >>> >> >> >> >> >> chris@cxtsoftware.com
>> >>> >>> >> >> >> >> >> >>>> >> <javascript:;>>
>> >>> >>> >> >> >> >> >> >>>> >> >> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the
>> >>> bean,
>> >>> >>> then
>> >>> >>> >> >> >> reference
>> >>> >>> >> >> >> >> >> it in
>> >>> >>> >> >> >> >> >> >>>> the
>> >>> >>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
>> >>> >>> that...no,
>> >>> >>> >> >> that
>> >>> >>> >> >> >> >> >> should be
>> >>> >>> >> >> >> >> >> >>>> >> all. I
>> >>> >>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on
>> the
>> >>> >>> resource.
>> >>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the
>> >>> service
>> >>> >>> >> >> injection,
>> >>> >>> >> >> >> >> >> which may
>> >>> >>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work
>> yet
>> >>> >>> though.
>> >>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
>> >>> >>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >>> >>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a
>> region
>> >>> >>> widget
>> >>> >>> >> >> >> outside a
>> >>> >>> >> >> >> >> >> region
>> >>> >>> >> >> >> >> >> >>>> >> >> outside
>> >>> >>> >> >> >> >> >> >>>> >> >> > a page?
>> >>> >>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to
>> do a
>> >>> >>> proof
>> >>> >>> >> of
>> >>> >>> >> >> >> concept
>> >>> >>> >> >> >> >> >> with
>> >>> >>> >> >> >> >> >> >>>> the
>> >>> >>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something
>> >>> simple
>> >>> >>> >> with
>> >>> >>> >> >> the
>> >>> >>> >> >> >> >> >> service and
>> >>> >>> >> >> >> >> >> >>>> >> >> rest models already in place.
>> >>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> In general though I don't see any value
>> to
>> >>> >>> dealing
>> >>> >>> >> with
>> >>> >>> >> >> >> >> region
>> >>> >>> >> >> >> >> >> >>>> widgets
>> >>> >>> >> >> >> >> >> >>>> >> >> as a nested resource
>> >>> (pages/:id/regions/:id...)
>> >>> >>> over
>> >>> >>> >> >> just
>> >>> >>> >> >> >> >> >> dealing
>> >>> >>> >> >> >> >> >> >>>> with
>> >>> >>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight
>> to the
>> >>> >>> pages
>> >>> >>> >> >> >> >> controller,
>> >>> >>> >> >> >> >> >> >>>> rather
>> >>> >>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with
>> >>> resource
>> >>> >>> >> >> concerns
>> >>> >>> >> >> >> >> >> separately.
>> >>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions
>> and
>> >>> >>> >> >> regionwidgets
>> >>> >>> >> >> >> only
>> >>> >>> >> >> >> >> >> making
>> >>> >>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you
>> >>> could say
>> >>> >>> >> the
>> >>> >>> >> >> same
>> >>> >>> >> >> >> >> >> thing for
>> >>> >>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both
>> >>> entities are
>> >>> >>> >> >> always
>> >>> >>> >> >> >> >> >> uniquely
>> >>> >>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
>> >>> >>> individually?
>> >>> >>> >> I
>> >>> >>> >> >> see
>> >>> >>> >> >> >> an
>> >>> >>> >> >> >> >> >> upside
>> >>> >>> >> >> >> >> >> >>>> of
>> >>> >>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints,
>> and I
>> >>> >>> see no
>> >>> >>> >> >> >> >> downside.
>> >>> >>> >> >> >> >> >> >>>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they
>> aren't
>> >>> >>> >> uniquely
>> >>> >>> >> >> >> >> >> identified and
>> >>> >>> >> >> >> >> >> >>>> are
>> >>> >>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But
>> that
>> >>> is a
>> >>> >>> >> >> longer
>> >>> >>> >> >> >> >> >> >>>> conversation.
>> >>> >>> >> >> >> >> >> >>>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
>> >>> >>> Noe-Payne
>> >>> >>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint
>> for
>> >>> >>> >> >> >> regionWidgets.
>> >>> >>> >> >> >> >> I've
>> >>> >>> >> >> >> >> >> >>>> added
>> >>> >>> >> >> >> >> >> >>>> >> >> >> the interface and default
>> implementation,
>> >>> and
>> >>> >>> >> >> created /
>> >>> >>> >> >> >> >> >> registered
>> >>> >>> >> >> >> >> >> >>>> >> the
>> >>> >>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I
>> get an
>> >>> >>> error:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >>> >>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils
>> - No
>> >>> >>> >> operation
>> >>> >>> >> >> >> >> matching
>> >>> >>> >> >> >> >> >> >>>> request
>> >>> >>> >> >> >> >> >> >>>> >> >> >> path
>> "/portal/api/rest/regionWidgets/1" is
>> >>> >>> found,
>> >>> >>> >> >> >> Relative
>> >>> >>> >> >> >> >> >> Path:
>> >>> >>> >> >> >> >> >> >>>> /1,
>> >>> >>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*,
>> >>> Accept:
>> >>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >>> >> >> >> >> >>
>> >>> >>> >>
>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >>> >>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for
>> >>> more
>> >>> >>> >> details.
>> >>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in
>> >>> order
>> >>> >>> to
>> >>> >>> >> >> create
>> >>> >>> >> >> >> and
>> >>> >>> >> >> >> >> >> >>>> register a
>> >>> >>> >> >> >> >> >> >>>> >> >> >> new endpoint?
>> >>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
>> >>> >>> Noe-Payne
>> >>> >>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM,
>> Chris
>> >>> >>> Geer <
>> >>> >>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM,
>> Erin
>> >>> >>> >> Noe-Payne <
>> >>> >>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM,
>> Matt
>> >>> >>> >> Franklin <
>> >>> >>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53
>> PM,
>> >>> Chris
>> >>> >>> >> Geer <
>> >>> >>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32
>> AM,
>> >>> Erin
>> >>> >>> >> >> Noe-Payne
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> <erin.noe.payne@gmail.com
>> >wrote:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here?
>> I
>> >>> would
>> >>> >>> >> like
>> >>> >>> >> >> to
>> >>> >>> >> >> >> >> start
>> >>> >>> >> >> >> >> >> >>>> >> implementing
>> >>> >>> >> >> >> >> >> >>>> >> >> >> more
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
>> >>> >>> foundational
>> >>> >>> >> for
>> >>> >>> >> >> >> the
>> >>> >>> >> >> >> >> >> entire
>> >>> >>> >> >> >> >> >> >>>> >> angular
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is
>> >>> that
>> >>> >>> the
>> >>> >>> >> >> current
>> >>> >>> >> >> >> >> apis
>> >>> >>> >> >> >> >> >> in
>> >>> >>> >> >> >> >> >> >>>> trunk
>> >>> >>> >> >> >> >> >> >>>> >> >> are
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept -
>> they
>> >>> are
>> >>> >>> not
>> >>> >>> >> >> tested
>> >>> >>> >> >> >> and
>> >>> >>> >> >> >> >> >> much of
>> >>> >>> >> >> >> >> >> >>>> >> the
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just
>> stubbed.
>> >>> Are
>> >>> >>> any
>> >>> >>> >> of
>> >>> >>> >> >> the
>> >>> >>> >> >> >> >> rest
>> >>> >>> >> >> >> >> >> api
>> >>> >>> >> >> >> >> >> >>>> >> >> >> implementations
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good
>> working
>> >>> >>> >> example? Is
>> >>> >>> >> >> >> there
>> >>> >>> >> >> >> >> >> other
>> >>> >>> >> >> >> >> >> >>>> >> >> >> documentation
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
>> >>> >>> resource
>> >>> >>> >> as a
>> >>> >>> >> >> >> >> >> "reference"
>> >>> >>> >> >> >> >> >> >>>> of
>> >>> >>> >> >> >> >> >> >>>> >> how
>> >>> >>> >> >> >> >> >> >>>> >> >> I'd
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> like
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's
>> still a
>> >>> work
>> >>> >>> in
>> >>> >>> >> >> >> >> progress. I
>> >>> >>> >> >> >> >> >> need
>> >>> >>> >> >> >> >> >> >>>> to
>> >>> >>> >> >> >> >> >> >>>> >> go
>> >>> >>> >> >> >> >> >> >>>> >> >> >> back
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> and
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>> >>> >>> >> reimplement
>> >>> >>> >> >> the
>> >>> >>> >> >> >> >> >> "fields"
>> >>> >>> >> >> >> >> >> >>>> >> concept.
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations
>> should
>> >>> be as
>> >>> >>> >> flat
>> >>> >>> >> >> as
>> >>> >>> >> >> >> >> >> possible
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be
>> >>> made to
>> >>> >>> >> >> nested
>> >>> >>> >> >> >> >> >> resources to
>> >>> >>> >> >> >> >> >> >>>> >> get
>> >>> >>> >> >> >> >> >> >>>> >> >> >> nested
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have
>> regions
>> >>> and
>> >>> >>> >> >> >> >> >> >>>> regions/1/regionwidgets,
>> >>> >>> >> >> >> >> >> >>>> >> >> the
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> regions
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not
>> contain
>> >>> an
>> >>> >>> >> array of
>> >>> >>> >> >> >> >> >> >>>> regionwidgets)
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round
>> >>> trips to
>> >>> >>> >> >> support
>> >>> >>> >> >> >> this
>> >>> >>> >> >> >> >> >> when
>> >>> >>> >> >> >> >> >> >>>> >> >> rendering
>> >>> >>> >> >> >> >> >> >>>> >> >> >> the
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
>> >>> >>> sufficient
>> >>> >>> >> >> >> number of
>> >>> >>> >> >> >> >> >> >>>> gadgets,
>> >>> >>> >> >> >> >> >> >>>> >> >> adding
>> >>> >>> >> >> >> >> >> >>>> >> >> >> to
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> the
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes
>> >>> problematic.
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>>
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the
>> >>> "standard"
>> >>> >>> >> rest
>> >>> >>> >> >> >> >> >> endpoints for
>> >>> >>> >> >> >> >> >> >>>> >> crud
>> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>> >>> >>> >> >> >> >> >> >>>> >>
>> >>> >>> >> >> >> >> >> >>>>
>> >>> >>> >> >> >> >> >>
>> >>> >>> >> >> >> >>
>> >>> >>> >> >> >>
>> >>> >>> >> >>
>> >>> >>> >>
>> >>> >>>
>> >>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Wed, Jul 31, 2013 at 11:19 AM, Erin Noe-Payne
<er...@gmail.com>wrote:

> On Mon, Jul 29, 2013 at 9:59 AM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > On Mon, Jul 29, 2013 at 1:54 AM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> On Thu, Jul 25, 2013 at 11:12 AM, Erin Noe-Payne
> >> <er...@gmail.com>wrote:
> >>
> >>> I'm not entirely sure how to proceed at the moment. For now I will
> >>> start work at the repository layer and try to implement consistent
> >>> crud operations to support the REST api.
> >>>
> >>
> >> Erin, on the CXF 2.7 migration page I saw this.
> >>
> >>
> >>    - org.apache.cxf.jaxrs.ext.RequestHandler and
> >>    org.apache.cxf.jaxrs.ext.ResponseHandler (use
> >>    javax.ws.rs.container.ContainerRequestFilter and
> >>    javax.ws.rs.container.ContainerResponseFilter instead).
> >>
> > Thanks Chris, I'll take a look.
> >
>
> It looks like ContainerRequestFilter / ContainerResponseFilter do give
> me access to valid request and response context objects that I can act
> upon. So these are the interfaces we will want to use for setting up
> filters.
>
> Also based on some more reading of CXF docs, it looks to me like we
> can use sub-resource locators [1] as an approach for breaking apart
> the page / region / regionWidget controllers while still using the
> /pages/:id/regions/:id/regionWidgets/:id url paths.
>
> I have submitted a patch on the review board [2] with a partial
> implementation (RB is again preventing me from uploading the patch
> directly so it is an attachment on the review). Look at the resolution
> from PagesResource to RegionsResource. If there are no complaints I am
> going to move forward with this approach.
>
> [1]
> http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Subresourcelocators
> .
> [2] https://reviews.apache.org/r/13119/


Erin,

On your RegionWidgetsResource, wouldn't you want the class level path to be
@Path("/pages/{pageId}/regions/{regionsId}/regionWidgets")

If you have it with just @Path("/pages") it doesn't really nest the
regionWidgets under the correct page.

>
>
> >>
> >> So, it looks like the docs are a little out of date. The
> >> ContainerResponseFilter handler method gets two params, Request Context
> and
> >> Response Context. That might give you what you need. I haven't played
> with
> >> it yet but it's worth a look.
> >>
> >> Chris
> >>
> >>
> >>
> >>> On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
> >>> <er...@gmail.com> wrote:
> >>> > On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com>
> >>> wrote:
> >>> >> What about this:
> >>> >>
> >>> >>
> >>>
> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
> >>> >>
> >>> >
> >>> > This is referring to a RequestHandler, not a ResponseHandler. In the
> >>> > request handler the Message object does have correct request uri
> data,
> >>> > etc, but I don't have access to the Response object yet.
> >>> >
> >>> >> The only thing I don't like about not returning Response objects is
> it
> >>> >> doesn't let the method set HTTP specific stuff. Which just means we
> need
> >>> >> really really good filters. For example, a create should set the
> >>> Location
> >>> >> HTTP header field with the proper URL to the newly created object.
> >>> >>
> >>> >
> >>> > That's fair. And the controllers could return response objects and
> >>> > following filters could just iteratively return
> >>> > Response.fromResponse(). But if we take a step back from filters or
> >>> > interceptors or whatever implementation approach, here's the problem
> >>> > I'm trying to solve:
> >>> >
> >>> > Taking your Location header example - all requests to get or create
> an
> >>> > entity should have the location header set to the canonical url of
> the
> >>> > resource. Post requests creating a new resource should have a
> location
> >>> > header pointing to the newly created resource. That is universally
> >>> > true, and I should be able to write that code generically. I do not
> >>> > want to have to set the location header in every controller for every
> >>> > resource that handles the @POST method. That seems like it should be
> >>> > doable, and filters or interceptors seemed like the way to do it. Now
> >>> > I'm not so sure.
> >>> >
> >>> > So is that a goal worth pursuing, and if yes what is the right
> approach?
> >>> >
> >>> >>
> >>> >> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <
> >>> erin.noe.payne@gmail.com>wrote:
> >>> >>
> >>> >>> Ok, I'm having trouble setting up filters that are able to access
> >>> >>> query string parameters to do pagination. I've submitted a review
> >>> >>> request [1] with my work so far (look at pages, categories, and the
> >>> >>> filters). My plan was the following workflow -
> >>> >>>
> >>> >>> - Request is received and processed by the controller. Controller
> >>> >>> returns an object <T> or List<T> (Page, Category, etc). For any
> list
> >>> >>> resource it gets all entities, and allows the pagination filter to
> >>> >>> subset.
> >>> >>> - JsonWrapperResponseFilter process the request and wraps the data
> >>> >>> object in the wrapper object
> >>> >>> - PaginationResponseFilter checks if the data object is a list. It
> >>> >>> retrieves the values of limit and offset QS parameters or sets
> them to
> >>> >>> defaults. It then subsets the data and sets appropriate meta
> fields in
> >>> >>> the json object.
> >>> >>>
> >>> >>> The issue is that the response handler does not give me access (as
> far
> >>> >>> as I can tell) to the query string values. Which makes me think I'm
> >>> >>> missing something, or that this is the wrong way to approach the
> >>> >>> problem.  Any help or input is appreciated.
> >>> >>>
> >>> >>>
> >>> >>> [1] https://reviews.apache.org/r/12901/
> >>> >>>
> >>> >>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <chris@cxtsoftware.com
> >
> >>> wrote:
> >>> >>> > Good point...I forgot Rave is using CXF 2.7.x which includes
> that new
> >>> >>> > stuff. That would be a better choice, plus it wouldn't tie us to
> CXF.
> >>> >>> >
> >>> >>> >
> >>> >>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
> >>> >>> > <er...@gmail.com>wrote:
> >>> >>> >
> >>> >>> >> Slight update on this journey of discovery - it looks like what
> we
> >>> >>> >> actually want to use is not interceptors, but jaxrs filters.
> See:
> >>> >>> >> http://cxf.apache.org/docs/jax-rs-filters.html
> >>> >>> >>
> >>> >>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <
> chris@cxtsoftware.com
> >>> >
> >>> >>> >> wrote:
> >>> >>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
> >>> >>> >> erin.noe.payne@gmail.com>wrote:
> >>> >>> >> >
> >>> >>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <
> >>> chris@cxtsoftware.com>
> >>> >>> >> >> wrote:
> >>> >>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
> >>> >>> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >>> >> >> >
> >>> >>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
> >>> >>> chris@cxtsoftware.com>
> >>> >>> >> >> >> wrote:
> >>> >>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> >>> >>> >> >> >> > <er...@gmail.com>wrote:
> >>> >>> >> >> >> >
> >>> >>> >> >> >> >> - Simple solution: All rest response models are flat.
> We
> >>> ignore
> >>> >>> >> any
> >>> >>> >> >> >> >> nested data, and just have separate endpoints to
> deliver
> >>> that
> >>> >>> >> data.
> >>> >>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model
> package
> >>> has
> >>> >>> >> only
> >>> >>> >> >> >> >> properties of "primitive" types, with no lists, no
> other
> >>> >>> classes.
> >>> >>> >> >> That
> >>> >>> >> >> >> >> is NOT currently the case. Then the fields interceptor
> >>> checks
> >>> >>> for
> >>> >>> >> the
> >>> >>> >> >> >> >> presence of a fields argument. If not present, the
> object
> >>> is
> >>> >>> >> >> delivered
> >>> >>> >> >> >> >> as is. If present the argument (a string) is split by
> >>> comma and
> >>> >>> >> only
> >>> >>> >> >> >> >> the matched properties are delivered. The fields qs
> >>> argument
> >>> >>> only
> >>> >>> >> has
> >>> >>> >> >> >> >> to support comma-delimited list of property names.
> >>> >>> >> >> >> >> Ex: ?fields=name,pageType
> >>> >>> >> >> >> >> //returns a page or pages with only name and pageType
> >>> >>> properties
> >>> >>> >> >> >> >>
> >>> >>> >> >> >> >
> >>> >>> >> >> >> > I like the simple solution. I think the CRUD part of
> the API
> >>> >>> should
> >>> >>> >> >> be as
> >>> >>> >> >> >> > flat as possible like Erin suggested and we have
> "special"
> >>> end
> >>> >>> >> points
> >>> >>> >> >> to
> >>> >>> >> >> >> > get back hierarchical data when needed, i.e. page
> rendering.
> >>> >>> >> >> >> >
> >>> >>> >> >> >>
> >>> >>> >> >> >> Just to make sure we are on the same page, my proposal is
> >>> that in
> >>> >>> >> both
> >>> >>> >> >> >> cases a get request without any special query string will
> >>> return
> >>> >>> only
> >>> >>> >> >> >> flat data. The difference is that in the second case the
> >>> fields
> >>> >>> query
> >>> >>> >> >> >> parameter will support a syntax that CAN deliver nested
> data
> >>> in a
> >>> >>> >> >> >> single request.
> >>> >>> >> >> >>
> >>> >>> >> >> >
> >>> >>> >> >> > That confuses me. I thought the whole point of the
> "special"
> >>> end
> >>> >>> point
> >>> >>> >> >> was
> >>> >>> >> >> > to handle things like page rendering in one query which
> would
> >>> >>> require
> >>> >>> >> >> > hierarchical data every time. Why force the use of query
> string
> >>> >>> >> params to
> >>> >>> >> >> > get that?
> >>> >>> >> >> >
> >>> >>> >> >>
> >>> >>> >> >> I was speaking in reference to the standard endpoints. The
> >>> >>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
> >>> >>> specific
> >>> >>> >> >> client need for a complex nested data set. It will always
> return
> >>> >>> >> >> hierarchical data, will probably not support field selection
> at
> >>> all.
> >>> >>> >> >>
> >>> >>> >> >> The standard endpoints will by default return flat data. They
> >>> will
> >>> >>> >> >> support field selection. If we choose to implement the more
> >>> complex
> >>> >>> >> >> field selection, then they will allow you to request nested
> data
> >>> >>> >> >> through the field selection syntax.
> >>> >>> >> >>
> >>> >>> >> >
> >>> >>> >> > ok
> >>> >>> >> >
> >>> >>> >> >>
> >>> >>> >> >> >>
> >>> >>> >> >> >> >>
> >>> >>> >> >> >> >> - Complicated solution: All rest response models
> include
> >>> >>> >> references
> >>> >>> >> >> to
> >>> >>> >> >> >> >> their nested data. This is the currently the case, and
> can
> >>> be
> >>> >>> >> seen in
> >>> >>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor
> >>> checks
> >>> >>> for
> >>> >>> >> >> >> >> presence of fields qs argument. If not present it
> strips
> >>> all
> >>> >>> >> nested
> >>> >>> >> >> >> >> data from the models and only returns properties. If
> it is
> >>> >>> >> present,
> >>> >>> >> >> it
> >>> >>> >> >> >> >> parses the argument and updates the data. The fields
> >>> argument
> >>> >>> >> needs
> >>> >>> >> >> to
> >>> >>> >> >> >> >> support a more complicated syntax that allows the
> >>> requesting of
> >>> >>> >> >> nested
> >>> >>> >> >> >> >> data. I would copy the syntax of facebook's graph
> search
> >>> api,
> >>> >>> >> which
> >>> >>> >> >> >> >> has a pretty readable solution. You allow for .fields
> and
> >>> >>> .limit
> >>> >>> >> on
> >>> >>> >> >> >> >> fields, which can be nested.
> >>> >>> >> >> >> >> Ex:
> >>> >>> >> >> >> >>
> >>> >>> >> >> >>
> >>> >>> >> >>
> >>> >>> >>
> >>> >>>
> >>>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >>> >>> >> >> >> >> //returns a page or pages with name and pageType
> >>> properties,
> >>> >>> >> nested
> >>> >>> >> >> >> >> list of regions (max of 2) with nested list of
> >>> regionWidgets
> >>> >>> with
> >>> >>> >> >> only
> >>> >>> >> >> >> >> properties of widgetId and locked
> >>> >>> >> >> >> >>
> >>> >>> >> >> >> >> In all cases, id should always be returned.
> >>> >>> >> >> >> >> I think the algorithm in the simple solution is easy.
> >>> >>> >> >> >> >> In a sense the algorithm in the second should be
> simple,
> >>> >>> because
> >>> >>> >> the
> >>> >>> >> >> >> >> service layer is already getting all the nested data,
> and
> >>> you
> >>> >>> are
> >>> >>> >> >> just
> >>> >>> >> >> >> >> stripping it off. Not sure what the performance
> >>> implications of
> >>> >>> >> that
> >>> >>> >> >> >> >> are though.
> >>> >>> >> >> >> >>
> >>> >>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
> >>> >>> >> chris@cxtsoftware.com>
> >>> >>> >> >> >> wrote:
> >>> >>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >>> >>> >> >> >> >> > <er...@gmail.com>wrote:
> >>> >>> >> >> >> >> >
> >>> >>> >> >> >> >> >> Going back to the discussion on field selection - I
> am
> >>> >>> >> currently
> >>> >>> >> >> >> going
> >>> >>> >> >> >> >> >> through the exercise of writing out the Resource
> >>> interfaces
> >>> >>> to
> >>> >>> >> >> define
> >>> >>> >> >> >> >> >> our endpoints.  There is a set of generic query
> string
> >>> >>> >> parameters
> >>> >>> >> >> >> that
> >>> >>> >> >> >> >> >> we wish to support on all or many of the endpoints -
> >>> fields
> >>> >>> >> (any
> >>> >>> >> >> get
> >>> >>> >> >> >> >> >> request), limit / offset (any get request that
> returns a
> >>> >>> list).
> >>> >>> >> >> >> >> >>
> >>> >>> >> >> >> >> >> Rather than writing each endpoint to accept
> >>> QueryParam()'s
> >>> >>> and
> >>> >>> >> >> repeat
> >>> >>> >> >> >> >> >> the appropriate logic, I assume we would want to
> take
> >>> >>> >> advantage of
> >>> >>> >> >> >> cxf
> >>> >>> >> >> >> >> >> interceptors [1] to intelligently and generically
> handle
> >>> >>> those
> >>> >>> >> qs
> >>> >>> >> >> >> >> >> arguments?
> >>> >>> >> >> >> >> >>
> >>> >>> >> >> >> >> >
> >>> >>> >> >> >> >> > I like the concept but I'm not sure how we
> generically
> >>> >>> filter,
> >>> >>> >> >> >> especially
> >>> >>> >> >> >> >> > with nested data. I'd love to see it work that way
> >>> though.
> >>> >>> >> >> >> Interceptors
> >>> >>> >> >> >> >> are
> >>> >>> >> >> >> >> > pretty easy to use, it's the filter algorithm I
> haven't
> >>> >>> figured
> >>> >>> >> out
> >>> >>> >> >> >> yet.
> >>> >>> >> >> >> >> > Thoughts?
> >>> >>> >> >> >> >> >
> >>> >>> >> >> >> >> >>
> >>> >>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >>> >>> >> >> >> >> >>
> >>> >>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >>> >>> >> >> >> >> >> <er...@gmail.com> wrote:
> >>> >>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts
> >>> about the
> >>> >>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like
> the
> >>> best
> >>> >>> >> way
> >>> >>> >> >> to
> >>> >>> >> >> >> get
> >>> >>> >> >> >> >> >> > wrapped responses?
> >>> >>> >> >> >> >> >> >
> >>> >>> >> >> >> >> >> > For the next step I would like to start writing
> out
> >>> all of
> >>> >>> >> the
> >>> >>> >> >> >> >> >> > resource interfaces so that we can begin writing
> >>> angular
> >>> >>> >> >> $resource
> >>> >>> >> >> >> >> >> > services against them.
> >>> >>> >> >> >> >> >> >
> >>> >>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >>> >>> >> >> >> >> >> > <er...@gmail.com> wrote:
> >>> >>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever
> >>> figured
> >>> >>> >> that
> >>> >>> >> >> one
> >>> >>> >> >> >> >> >> out...
> >>> >>> >> >> >> >> >> >>
> >>> >>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> >>> >>> >> >> >> chris@cxtsoftware.com>
> >>> >>> >> >> >> >> >> wrote:
> >>> >>> >> >> >> >> >> >>> Erin,
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple
> >>> things:
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the
> @GET
> >>> >>> methods
> >>> >>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class,
> >>> remove
> >>> >>> the
> >>> >>> >> >> >> @ParamPath
> >>> >>> >> >> >> >> >> >>> attributes from variable signatures. I know
> Intellij
> >>> >>> puts
> >>> >>> >> >> those
> >>> >>> >> >> >> in
> >>> >>> >> >> >> >> >> there
> >>> >>> >> >> >> >> >> >>> but they cause problems. Only the interface
> should
> >>> be
> >>> >>> >> >> annotated.
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>> Chris
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne
> <
> >>> >>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >>> >> >> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>>> Review board is not accepting my patch and is
> not
> >>> >>> >> accepting
> >>> >>> >> >> the
> >>> >>> >> >> >> >> valid
> >>> >>> >> >> >> >> >> >>>> file paths. I have attached the patch as a
> file to
> >>> the
> >>> >>> >> >> review.
> >>> >>> >> >> >> >> >> >>>>
> >>> >>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> >>> >>> >> >> >> chris@cxtsoftware.com
> >>> >>> >> >> >> >> >
> >>> >>> >> >> >> >> >> wrote:
> >>> >>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >>> >>> >> >> >> >> >> >>>> >
> >>> >>> >> >> >> >> >> >>>> >
> >>> >>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin
> Noe-Payne <
> >>> >>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >>> >>> >> >> >> >> >> >>>> >
> >>> >>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as
> >>> expected.
> >>> >>> I've
> >>> >>> >> >> posted
> >>> >>> >> >> >> >> the
> >>> >>> >> >> >> >> >> >>>> >> patch on the review board if anyone can
> take a
> >>> look
> >>> >>> and
> >>> >>> >> >> offer
> >>> >>> >> >> >> >> >> advice -
> >>> >>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >>> >>> >> >> >> >> >> >>>> >>
> >>> >>> >> >> >> >> >> >>>> >> Thanks
> >>> >>> >> >> >> >> >> >>>> >>
> >>> >>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer
> <
> >>> >>> >> >> >> >> chris@cxtsoftware.com
> >>> >>> >> >> >> >> >> >
> >>> >>> >> >> >> >> >> >>>> wrote:
> >>> >>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne
> >>> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris
> Geer <
> >>> >>> >> >> >> >> >> chris@cxtsoftware.com
> >>> >>> >> >> >> >> >> >>>> >> <javascript:;>>
> >>> >>> >> >> >> >> >> >>>> >> >> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the
> >>> bean,
> >>> >>> then
> >>> >>> >> >> >> reference
> >>> >>> >> >> >> >> >> it in
> >>> >>> >> >> >> >> >> >>>> the
> >>> >>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
> >>> >>> that...no,
> >>> >>> >> >> that
> >>> >>> >> >> >> >> >> should be
> >>> >>> >> >> >> >> >> >>>> >> all. I
> >>> >>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on
> the
> >>> >>> resource.
> >>> >>> >> >> >> >> >> >>>> >> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the
> >>> service
> >>> >>> >> >> injection,
> >>> >>> >> >> >> >> >> which may
> >>> >>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work
> yet
> >>> >>> though.
> >>> >>> >> >> >> >> >> >>>> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
> >>> >>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >>> >>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a
> region
> >>> >>> widget
> >>> >>> >> >> >> outside a
> >>> >>> >> >> >> >> >> region
> >>> >>> >> >> >> >> >> >>>> >> >> outside
> >>> >>> >> >> >> >> >> >>>> >> >> > a page?
> >>> >>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to
> do a
> >>> >>> proof
> >>> >>> >> of
> >>> >>> >> >> >> concept
> >>> >>> >> >> >> >> >> with
> >>> >>> >> >> >> >> >> >>>> the
> >>> >>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something
> >>> simple
> >>> >>> >> with
> >>> >>> >> >> the
> >>> >>> >> >> >> >> >> service and
> >>> >>> >> >> >> >> >> >>>> >> >> rest models already in place.
> >>> >>> >> >> >> >> >> >>>> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> In general though I don't see any value
> to
> >>> >>> dealing
> >>> >>> >> with
> >>> >>> >> >> >> >> region
> >>> >>> >> >> >> >> >> >>>> widgets
> >>> >>> >> >> >> >> >> >>>> >> >> as a nested resource
> >>> (pages/:id/regions/:id...)
> >>> >>> over
> >>> >>> >> >> just
> >>> >>> >> >> >> >> >> dealing
> >>> >>> >> >> >> >> >> >>>> with
> >>> >>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight
> to the
> >>> >>> pages
> >>> >>> >> >> >> >> controller,
> >>> >>> >> >> >> >> >> >>>> rather
> >>> >>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with
> >>> resource
> >>> >>> >> >> concerns
> >>> >>> >> >> >> >> >> separately.
> >>> >>> >> >> >> >> >> >>>> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions
> and
> >>> >>> >> >> regionwidgets
> >>> >>> >> >> >> only
> >>> >>> >> >> >> >> >> making
> >>> >>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you
> >>> could say
> >>> >>> >> the
> >>> >>> >> >> same
> >>> >>> >> >> >> >> >> thing for
> >>> >>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both
> >>> entities are
> >>> >>> >> >> always
> >>> >>> >> >> >> >> >> uniquely
> >>> >>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
> >>> >>> individually?
> >>> >>> >> I
> >>> >>> >> >> see
> >>> >>> >> >> >> an
> >>> >>> >> >> >> >> >> upside
> >>> >>> >> >> >> >> >> >>>> of
> >>> >>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints,
> and I
> >>> >>> see no
> >>> >>> >> >> >> >> downside.
> >>> >>> >> >> >> >> >> >>>> >> >
> >>> >>> >> >> >> >> >> >>>> >> >
> >>> >>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they
> aren't
> >>> >>> >> uniquely
> >>> >>> >> >> >> >> >> identified and
> >>> >>> >> >> >> >> >> >>>> are
> >>> >>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But
> that
> >>> is a
> >>> >>> >> >> longer
> >>> >>> >> >> >> >> >> >>>> conversation.
> >>> >>> >> >> >> >> >> >>>> >> >
> >>> >>> >> >> >> >> >> >>>> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
> >>> >>> Noe-Payne
> >>> >>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint
> for
> >>> >>> >> >> >> regionWidgets.
> >>> >>> >> >> >> >> I've
> >>> >>> >> >> >> >> >> >>>> added
> >>> >>> >> >> >> >> >> >>>> >> >> >> the interface and default
> implementation,
> >>> and
> >>> >>> >> >> created /
> >>> >>> >> >> >> >> >> registered
> >>> >>> >> >> >> >> >> >>>> >> the
> >>> >>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >>> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I
> get an
> >>> >>> error:
> >>> >>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >>> >>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils
> - No
> >>> >>> >> operation
> >>> >>> >> >> >> >> matching
> >>> >>> >> >> >> >> >> >>>> request
> >>> >>> >> >> >> >> >> >>>> >> >> >> path
> "/portal/api/rest/regionWidgets/1" is
> >>> >>> found,
> >>> >>> >> >> >> Relative
> >>> >>> >> >> >> >> >> Path:
> >>> >>> >> >> >> >> >> >>>> /1,
> >>> >>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*,
> >>> Accept:
> >>> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >>> >> >> >> >> >>
> >>> >>> >>
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >>> >>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for
> >>> more
> >>> >>> >> details.
> >>> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in
> >>> order
> >>> >>> to
> >>> >>> >> >> create
> >>> >>> >> >> >> and
> >>> >>> >> >> >> >> >> >>>> register a
> >>> >>> >> >> >> >> >> >>>> >> >> >> new endpoint?
> >>> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
> >>> >>> Noe-Payne
> >>> >>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM,
> Chris
> >>> >>> Geer <
> >>> >>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
> >>> >>> >> >> >> >> >> >>>> >> >> >> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM,
> Erin
> >>> >>> >> Noe-Payne <
> >>> >>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM,
> Matt
> >>> >>> >> Franklin <
> >>> >>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53
> PM,
> >>> Chris
> >>> >>> >> Geer <
> >>> >>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32
> AM,
> >>> Erin
> >>> >>> >> >> Noe-Payne
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> <erin.noe.payne@gmail.com
> >wrote:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here?
> I
> >>> would
> >>> >>> >> like
> >>> >>> >> >> to
> >>> >>> >> >> >> >> start
> >>> >>> >> >> >> >> >> >>>> >> implementing
> >>> >>> >> >> >> >> >> >>>> >> >> >> more
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
> >>> >>> foundational
> >>> >>> >> for
> >>> >>> >> >> >> the
> >>> >>> >> >> >> >> >> entire
> >>> >>> >> >> >> >> >> >>>> >> angular
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is
> >>> that
> >>> >>> the
> >>> >>> >> >> current
> >>> >>> >> >> >> >> apis
> >>> >>> >> >> >> >> >> in
> >>> >>> >> >> >> >> >> >>>> trunk
> >>> >>> >> >> >> >> >> >>>> >> >> are
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept -
> they
> >>> are
> >>> >>> not
> >>> >>> >> >> tested
> >>> >>> >> >> >> and
> >>> >>> >> >> >> >> >> much of
> >>> >>> >> >> >> >> >> >>>> >> the
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just
> stubbed.
> >>> Are
> >>> >>> any
> >>> >>> >> of
> >>> >>> >> >> the
> >>> >>> >> >> >> >> rest
> >>> >>> >> >> >> >> >> api
> >>> >>> >> >> >> >> >> >>>> >> >> >> implementations
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good
> working
> >>> >>> >> example? Is
> >>> >>> >> >> >> there
> >>> >>> >> >> >> >> >> other
> >>> >>> >> >> >> >> >> >>>> >> >> >> documentation
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
> >>> >>> resource
> >>> >>> >> as a
> >>> >>> >> >> >> >> >> "reference"
> >>> >>> >> >> >> >> >> >>>> of
> >>> >>> >> >> >> >> >> >>>> >> how
> >>> >>> >> >> >> >> >> >>>> >> >> I'd
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> like
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's
> still a
> >>> work
> >>> >>> in
> >>> >>> >> >> >> >> progress. I
> >>> >>> >> >> >> >> >> need
> >>> >>> >> >> >> >> >> >>>> to
> >>> >>> >> >> >> >> >> >>>> >> go
> >>> >>> >> >> >> >> >> >>>> >> >> >> back
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> and
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
> >>> >>> >> reimplement
> >>> >>> >> >> the
> >>> >>> >> >> >> >> >> "fields"
> >>> >>> >> >> >> >> >> >>>> >> concept.
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations
> should
> >>> be as
> >>> >>> >> flat
> >>> >>> >> >> as
> >>> >>> >> >> >> >> >> possible
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be
> >>> made to
> >>> >>> >> >> nested
> >>> >>> >> >> >> >> >> resources to
> >>> >>> >> >> >> >> >> >>>> >> get
> >>> >>> >> >> >> >> >> >>>> >> >> >> nested
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have
> regions
> >>> and
> >>> >>> >> >> >> >> >> >>>> regions/1/regionwidgets,
> >>> >>> >> >> >> >> >> >>>> >> >> the
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> regions
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not
> contain
> >>> an
> >>> >>> >> array of
> >>> >>> >> >> >> >> >> >>>> regionwidgets)
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round
> >>> trips to
> >>> >>> >> >> support
> >>> >>> >> >> >> this
> >>> >>> >> >> >> >> >> when
> >>> >>> >> >> >> >> >> >>>> >> >> rendering
> >>> >>> >> >> >> >> >> >>>> >> >> >> the
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
> >>> >>> sufficient
> >>> >>> >> >> >> number of
> >>> >>> >> >> >> >> >> >>>> gadgets,
> >>> >>> >> >> >> >> >> >>>> >> >> adding
> >>> >>> >> >> >> >> >> >>>> >> >> >> to
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> the
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes
> >>> problematic.
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>>
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the
> >>> "standard"
> >>> >>> >> rest
> >>> >>> >> >> >> >> >> endpoints for
> >>> >>> >> >> >> >> >> >>>> >> crud
> >>> >>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
> >>> >>> >> >> >> >> >> >>>> >>
> >>> >>> >> >> >> >> >> >>>>
> >>> >>> >> >> >> >> >>
> >>> >>> >> >> >> >>
> >>> >>> >> >> >>
> >>> >>> >> >>
> >>> >>> >>
> >>> >>>
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Mon, Jul 29, 2013 at 9:59 AM, Erin Noe-Payne
<er...@gmail.com> wrote:
> On Mon, Jul 29, 2013 at 1:54 AM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> On Thu, Jul 25, 2013 at 11:12 AM, Erin Noe-Payne
>> <er...@gmail.com>wrote:
>>
>>> I'm not entirely sure how to proceed at the moment. For now I will
>>> start work at the repository layer and try to implement consistent
>>> crud operations to support the REST api.
>>>
>>
>> Erin, on the CXF 2.7 migration page I saw this.
>>
>>
>>    - org.apache.cxf.jaxrs.ext.RequestHandler and
>>    org.apache.cxf.jaxrs.ext.ResponseHandler (use
>>    javax.ws.rs.container.ContainerRequestFilter and
>>    javax.ws.rs.container.ContainerResponseFilter instead).
>>
> Thanks Chris, I'll take a look.
>

It looks like ContainerRequestFilter / ContainerResponseFilter do give
me access to valid request and response context objects that I can act
upon. So these are the interfaces we will want to use for setting up
filters.

Also based on some more reading of CXF docs, it looks to me like we
can use sub-resource locators [1] as an approach for breaking apart
the page / region / regionWidget controllers while still using the
/pages/:id/regions/:id/regionWidgets/:id url paths.

I have submitted a patch on the review board [2] with a partial
implementation (RB is again preventing me from uploading the patch
directly so it is an attachment on the review). Look at the resolution
from PagesResource to RegionsResource. If there are no complaints I am
going to move forward with this approach.

[1] http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Subresourcelocators.
[2] https://reviews.apache.org/r/13119/

>>
>> So, it looks like the docs are a little out of date. The
>> ContainerResponseFilter handler method gets two params, Request Context and
>> Response Context. That might give you what you need. I haven't played with
>> it yet but it's worth a look.
>>
>> Chris
>>
>>
>>
>>> On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
>>> <er...@gmail.com> wrote:
>>> > On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >> What about this:
>>> >>
>>> >>
>>> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
>>> >>
>>> >
>>> > This is referring to a RequestHandler, not a ResponseHandler. In the
>>> > request handler the Message object does have correct request uri data,
>>> > etc, but I don't have access to the Response object yet.
>>> >
>>> >> The only thing I don't like about not returning Response objects is it
>>> >> doesn't let the method set HTTP specific stuff. Which just means we need
>>> >> really really good filters. For example, a create should set the
>>> Location
>>> >> HTTP header field with the proper URL to the newly created object.
>>> >>
>>> >
>>> > That's fair. And the controllers could return response objects and
>>> > following filters could just iteratively return
>>> > Response.fromResponse(). But if we take a step back from filters or
>>> > interceptors or whatever implementation approach, here's the problem
>>> > I'm trying to solve:
>>> >
>>> > Taking your Location header example - all requests to get or create an
>>> > entity should have the location header set to the canonical url of the
>>> > resource. Post requests creating a new resource should have a location
>>> > header pointing to the newly created resource. That is universally
>>> > true, and I should be able to write that code generically. I do not
>>> > want to have to set the location header in every controller for every
>>> > resource that handles the @POST method. That seems like it should be
>>> > doable, and filters or interceptors seemed like the way to do it. Now
>>> > I'm not so sure.
>>> >
>>> > So is that a goal worth pursuing, and if yes what is the right approach?
>>> >
>>> >>
>>> >> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <
>>> erin.noe.payne@gmail.com>wrote:
>>> >>
>>> >>> Ok, I'm having trouble setting up filters that are able to access
>>> >>> query string parameters to do pagination. I've submitted a review
>>> >>> request [1] with my work so far (look at pages, categories, and the
>>> >>> filters). My plan was the following workflow -
>>> >>>
>>> >>> - Request is received and processed by the controller. Controller
>>> >>> returns an object <T> or List<T> (Page, Category, etc). For any list
>>> >>> resource it gets all entities, and allows the pagination filter to
>>> >>> subset.
>>> >>> - JsonWrapperResponseFilter process the request and wraps the data
>>> >>> object in the wrapper object
>>> >>> - PaginationResponseFilter checks if the data object is a list. It
>>> >>> retrieves the values of limit and offset QS parameters or sets them to
>>> >>> defaults. It then subsets the data and sets appropriate meta fields in
>>> >>> the json object.
>>> >>>
>>> >>> The issue is that the response handler does not give me access (as far
>>> >>> as I can tell) to the query string values. Which makes me think I'm
>>> >>> missing something, or that this is the wrong way to approach the
>>> >>> problem.  Any help or input is appreciated.
>>> >>>
>>> >>>
>>> >>> [1] https://reviews.apache.org/r/12901/
>>> >>>
>>> >>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >>> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
>>> >>> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
>>> >>> >
>>> >>> >
>>> >>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
>>> >>> > <er...@gmail.com>wrote:
>>> >>> >
>>> >>> >> Slight update on this journey of discovery - it looks like what we
>>> >>> >> actually want to use is not interceptors, but jaxrs filters. See:
>>> >>> >> http://cxf.apache.org/docs/jax-rs-filters.html
>>> >>> >>
>>> >>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <chris@cxtsoftware.com
>>> >
>>> >>> >> wrote:
>>> >>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>>> >>> >> erin.noe.payne@gmail.com>wrote:
>>> >>> >> >
>>> >>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <
>>> chris@cxtsoftware.com>
>>> >>> >> >> wrote:
>>> >>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>>> >>> >> >> erin.noe.payne@gmail.com>wrote:
>>> >>> >> >> >
>>> >>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
>>> >>> chris@cxtsoftware.com>
>>> >>> >> >> >> wrote:
>>> >>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>>> >>> >> >> >> > <er...@gmail.com>wrote:
>>> >>> >> >> >> >
>>> >>> >> >> >> >> - Simple solution: All rest response models are flat. We
>>> ignore
>>> >>> >> any
>>> >>> >> >> >> >> nested data, and just have separate endpoints to deliver
>>> that
>>> >>> >> data.
>>> >>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package
>>> has
>>> >>> >> only
>>> >>> >> >> >> >> properties of "primitive" types, with no lists, no other
>>> >>> classes.
>>> >>> >> >> That
>>> >>> >> >> >> >> is NOT currently the case. Then the fields interceptor
>>> checks
>>> >>> for
>>> >>> >> the
>>> >>> >> >> >> >> presence of a fields argument. If not present, the object
>>> is
>>> >>> >> >> delivered
>>> >>> >> >> >> >> as is. If present the argument (a string) is split by
>>> comma and
>>> >>> >> only
>>> >>> >> >> >> >> the matched properties are delivered. The fields qs
>>> argument
>>> >>> only
>>> >>> >> has
>>> >>> >> >> >> >> to support comma-delimited list of property names.
>>> >>> >> >> >> >> Ex: ?fields=name,pageType
>>> >>> >> >> >> >> //returns a page or pages with only name and pageType
>>> >>> properties
>>> >>> >> >> >> >>
>>> >>> >> >> >> >
>>> >>> >> >> >> > I like the simple solution. I think the CRUD part of the API
>>> >>> should
>>> >>> >> >> be as
>>> >>> >> >> >> > flat as possible like Erin suggested and we have "special"
>>> end
>>> >>> >> points
>>> >>> >> >> to
>>> >>> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
>>> >>> >> >> >> >
>>> >>> >> >> >>
>>> >>> >> >> >> Just to make sure we are on the same page, my proposal is
>>> that in
>>> >>> >> both
>>> >>> >> >> >> cases a get request without any special query string will
>>> return
>>> >>> only
>>> >>> >> >> >> flat data. The difference is that in the second case the
>>> fields
>>> >>> query
>>> >>> >> >> >> parameter will support a syntax that CAN deliver nested data
>>> in a
>>> >>> >> >> >> single request.
>>> >>> >> >> >>
>>> >>> >> >> >
>>> >>> >> >> > That confuses me. I thought the whole point of the "special"
>>> end
>>> >>> point
>>> >>> >> >> was
>>> >>> >> >> > to handle things like page rendering in one query which would
>>> >>> require
>>> >>> >> >> > hierarchical data every time. Why force the use of query string
>>> >>> >> params to
>>> >>> >> >> > get that?
>>> >>> >> >> >
>>> >>> >> >>
>>> >>> >> >> I was speaking in reference to the standard endpoints. The
>>> >>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
>>> >>> specific
>>> >>> >> >> client need for a complex nested data set. It will always return
>>> >>> >> >> hierarchical data, will probably not support field selection at
>>> all.
>>> >>> >> >>
>>> >>> >> >> The standard endpoints will by default return flat data. They
>>> will
>>> >>> >> >> support field selection. If we choose to implement the more
>>> complex
>>> >>> >> >> field selection, then they will allow you to request nested data
>>> >>> >> >> through the field selection syntax.
>>> >>> >> >>
>>> >>> >> >
>>> >>> >> > ok
>>> >>> >> >
>>> >>> >> >>
>>> >>> >> >> >>
>>> >>> >> >> >> >>
>>> >>> >> >> >> >> - Complicated solution: All rest response models include
>>> >>> >> references
>>> >>> >> >> to
>>> >>> >> >> >> >> their nested data. This is the currently the case, and can
>>> be
>>> >>> >> seen in
>>> >>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor
>>> checks
>>> >>> for
>>> >>> >> >> >> >> presence of fields qs argument. If not present it strips
>>> all
>>> >>> >> nested
>>> >>> >> >> >> >> data from the models and only returns properties. If it is
>>> >>> >> present,
>>> >>> >> >> it
>>> >>> >> >> >> >> parses the argument and updates the data. The fields
>>> argument
>>> >>> >> needs
>>> >>> >> >> to
>>> >>> >> >> >> >> support a more complicated syntax that allows the
>>> requesting of
>>> >>> >> >> nested
>>> >>> >> >> >> >> data. I would copy the syntax of facebook's graph search
>>> api,
>>> >>> >> which
>>> >>> >> >> >> >> has a pretty readable solution. You allow for .fields and
>>> >>> .limit
>>> >>> >> on
>>> >>> >> >> >> >> fields, which can be nested.
>>> >>> >> >> >> >> Ex:
>>> >>> >> >> >> >>
>>> >>> >> >> >>
>>> >>> >> >>
>>> >>> >>
>>> >>>
>>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>>> >>> >> >> >> >> //returns a page or pages with name and pageType
>>> properties,
>>> >>> >> nested
>>> >>> >> >> >> >> list of regions (max of 2) with nested list of
>>> regionWidgets
>>> >>> with
>>> >>> >> >> only
>>> >>> >> >> >> >> properties of widgetId and locked
>>> >>> >> >> >> >>
>>> >>> >> >> >> >> In all cases, id should always be returned.
>>> >>> >> >> >> >> I think the algorithm in the simple solution is easy.
>>> >>> >> >> >> >> In a sense the algorithm in the second should be simple,
>>> >>> because
>>> >>> >> the
>>> >>> >> >> >> >> service layer is already getting all the nested data, and
>>> you
>>> >>> are
>>> >>> >> >> just
>>> >>> >> >> >> >> stripping it off. Not sure what the performance
>>> implications of
>>> >>> >> that
>>> >>> >> >> >> >> are though.
>>> >>> >> >> >> >>
>>> >>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>>> >>> >> chris@cxtsoftware.com>
>>> >>> >> >> >> wrote:
>>> >>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>>> >>> >> >> >> >> > <er...@gmail.com>wrote:
>>> >>> >> >> >> >> >
>>> >>> >> >> >> >> >> Going back to the discussion on field selection - I am
>>> >>> >> currently
>>> >>> >> >> >> going
>>> >>> >> >> >> >> >> through the exercise of writing out the Resource
>>> interfaces
>>> >>> to
>>> >>> >> >> define
>>> >>> >> >> >> >> >> our endpoints.  There is a set of generic query string
>>> >>> >> parameters
>>> >>> >> >> >> that
>>> >>> >> >> >> >> >> we wish to support on all or many of the endpoints -
>>> fields
>>> >>> >> (any
>>> >>> >> >> get
>>> >>> >> >> >> >> >> request), limit / offset (any get request that returns a
>>> >>> list).
>>> >>> >> >> >> >> >>
>>> >>> >> >> >> >> >> Rather than writing each endpoint to accept
>>> QueryParam()'s
>>> >>> and
>>> >>> >> >> repeat
>>> >>> >> >> >> >> >> the appropriate logic, I assume we would want to take
>>> >>> >> advantage of
>>> >>> >> >> >> cxf
>>> >>> >> >> >> >> >> interceptors [1] to intelligently and generically handle
>>> >>> those
>>> >>> >> qs
>>> >>> >> >> >> >> >> arguments?
>>> >>> >> >> >> >> >>
>>> >>> >> >> >> >> >
>>> >>> >> >> >> >> > I like the concept but I'm not sure how we generically
>>> >>> filter,
>>> >>> >> >> >> especially
>>> >>> >> >> >> >> > with nested data. I'd love to see it work that way
>>> though.
>>> >>> >> >> >> Interceptors
>>> >>> >> >> >> >> are
>>> >>> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
>>> >>> figured
>>> >>> >> out
>>> >>> >> >> >> yet.
>>> >>> >> >> >> >> > Thoughts?
>>> >>> >> >> >> >> >
>>> >>> >> >> >> >> >>
>>> >>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>>> >>> >> >> >> >> >>
>>> >>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>> >>> >> >> >> >> >> <er...@gmail.com> wrote:
>>> >>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts
>>> about the
>>> >>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the
>>> best
>>> >>> >> way
>>> >>> >> >> to
>>> >>> >> >> >> get
>>> >>> >> >> >> >> >> > wrapped responses?
>>> >>> >> >> >> >> >> >
>>> >>> >> >> >> >> >> > For the next step I would like to start writing out
>>> all of
>>> >>> >> the
>>> >>> >> >> >> >> >> > resource interfaces so that we can begin writing
>>> angular
>>> >>> >> >> $resource
>>> >>> >> >> >> >> >> > services against them.
>>> >>> >> >> >> >> >> >
>>> >>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>> >>> >> >> >> >> >> > <er...@gmail.com> wrote:
>>> >>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever
>>> figured
>>> >>> >> that
>>> >>> >> >> one
>>> >>> >> >> >> >> >> out...
>>> >>> >> >> >> >> >> >>
>>> >>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>>> >>> >> >> >> chris@cxtsoftware.com>
>>> >>> >> >> >> >> >> wrote:
>>> >>> >> >> >> >> >> >>> Erin,
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple
>>> things:
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
>>> >>> methods
>>> >>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class,
>>> remove
>>> >>> the
>>> >>> >> >> >> @ParamPath
>>> >>> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
>>> >>> puts
>>> >>> >> >> those
>>> >>> >> >> >> in
>>> >>> >> >> >> >> >> there
>>> >>> >> >> >> >> >> >>> but they cause problems. Only the interface should
>>> be
>>> >>> >> >> annotated.
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>> Chris
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>> >>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >>> >> >> >> >> >> >>>
>>> >>> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
>>> >>> >> accepting
>>> >>> >> >> the
>>> >>> >> >> >> >> valid
>>> >>> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to
>>> the
>>> >>> >> >> review.
>>> >>> >> >> >> >> >> >>>>
>>> >>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>>> >>> >> >> >> chris@cxtsoftware.com
>>> >>> >> >> >> >> >
>>> >>> >> >> >> >> >> wrote:
>>> >>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>>> >>> >> >> >> >> >> >>>> >
>>> >>> >> >> >> >> >> >>>> >
>>> >>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>> >>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>>> >>> >> >> >> >> >> >>>> >
>>> >>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as
>>> expected.
>>> >>> I've
>>> >>> >> >> posted
>>> >>> >> >> >> >> the
>>> >>> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a
>>> look
>>> >>> and
>>> >>> >> >> offer
>>> >>> >> >> >> >> >> advice -
>>> >>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>>> >>> >> >> >> >> >> >>>> >>
>>> >>> >> >> >> >> >> >>>> >> Thanks
>>> >>> >> >> >> >> >> >>>> >>
>>> >>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>>> >>> >> >> >> >> chris@cxtsoftware.com
>>> >>> >> >> >> >> >> >
>>> >>> >> >> >> >> >> >>>> wrote:
>>> >>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne
>>> wrote:
>>> >>> >> >> >> >> >> >>>> >> >
>>> >>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>> >>> >> >> >> >> >> chris@cxtsoftware.com
>>> >>> >> >> >> >> >> >>>> >> <javascript:;>>
>>> >>> >> >> >> >> >> >>>> >> >> wrote:
>>> >>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the
>>> bean,
>>> >>> then
>>> >>> >> >> >> reference
>>> >>> >> >> >> >> >> it in
>>> >>> >> >> >> >> >> >>>> the
>>> >>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
>>> >>> that...no,
>>> >>> >> >> that
>>> >>> >> >> >> >> >> should be
>>> >>> >> >> >> >> >> >>>> >> all. I
>>> >>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
>>> >>> resource.
>>> >>> >> >> >> >> >> >>>> >> >> >
>>> >>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the
>>> service
>>> >>> >> >> injection,
>>> >>> >> >> >> >> >> which may
>>> >>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
>>> >>> though.
>>> >>> >> >> >> >> >> >>>> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
>>> >>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>> >>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
>>> >>> widget
>>> >>> >> >> >> outside a
>>> >>> >> >> >> >> >> region
>>> >>> >> >> >> >> >> >>>> >> >> outside
>>> >>> >> >> >> >> >> >>>> >> >> > a page?
>>> >>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
>>> >>> proof
>>> >>> >> of
>>> >>> >> >> >> concept
>>> >>> >> >> >> >> >> with
>>> >>> >> >> >> >> >> >>>> the
>>> >>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something
>>> simple
>>> >>> >> with
>>> >>> >> >> the
>>> >>> >> >> >> >> >> service and
>>> >>> >> >> >> >> >> >>>> >> >> rest models already in place.
>>> >>> >> >> >> >> >> >>>> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
>>> >>> dealing
>>> >>> >> with
>>> >>> >> >> >> >> region
>>> >>> >> >> >> >> >> >>>> widgets
>>> >>> >> >> >> >> >> >>>> >> >> as a nested resource
>>> (pages/:id/regions/:id...)
>>> >>> over
>>> >>> >> >> just
>>> >>> >> >> >> >> >> dealing
>>> >>> >> >> >> >> >> >>>> with
>>> >>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
>>> >>> pages
>>> >>> >> >> >> >> controller,
>>> >>> >> >> >> >> >> >>>> rather
>>> >>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with
>>> resource
>>> >>> >> >> concerns
>>> >>> >> >> >> >> >> separately.
>>> >>> >> >> >> >> >> >>>> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
>>> >>> >> >> regionwidgets
>>> >>> >> >> >> only
>>> >>> >> >> >> >> >> making
>>> >>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you
>>> could say
>>> >>> >> the
>>> >>> >> >> same
>>> >>> >> >> >> >> >> thing for
>>> >>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both
>>> entities are
>>> >>> >> >> always
>>> >>> >> >> >> >> >> uniquely
>>> >>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
>>> >>> individually?
>>> >>> >> I
>>> >>> >> >> see
>>> >>> >> >> >> an
>>> >>> >> >> >> >> >> upside
>>> >>> >> >> >> >> >> >>>> of
>>> >>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
>>> >>> see no
>>> >>> >> >> >> >> downside.
>>> >>> >> >> >> >> >> >>>> >> >
>>> >>> >> >> >> >> >> >>>> >> >
>>> >>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
>>> >>> >> uniquely
>>> >>> >> >> >> >> >> identified and
>>> >>> >> >> >> >> >> >>>> are
>>> >>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that
>>> is a
>>> >>> >> >> longer
>>> >>> >> >> >> >> >> >>>> conversation.
>>> >>> >> >> >> >> >> >>>> >> >
>>> >>> >> >> >> >> >> >>>> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> >
>>> >>> >> >> >> >> >> >>>> >> >> >
>>> >>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
>>> >>> Noe-Payne
>>> >>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >
>>> >>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>>> >>> >> >> >> regionWidgets.
>>> >>> >> >> >> >> I've
>>> >>> >> >> >> >> >> >>>> added
>>> >>> >> >> >> >> >> >>>> >> >> >> the interface and default implementation,
>>> and
>>> >>> >> >> created /
>>> >>> >> >> >> >> >> registered
>>> >>> >> >> >> >> >> >>>> >> the
>>> >>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>>> >>> >> >> >> >> >> >>>> >> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
>>> >>> error:
>>> >>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>> >>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
>>> >>> >> operation
>>> >>> >> >> >> >> matching
>>> >>> >> >> >> >> >> >>>> request
>>> >>> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
>>> >>> found,
>>> >>> >> >> >> Relative
>>> >>> >> >> >> >> >> Path:
>>> >>> >> >> >> >> >> >>>> /1,
>>> >>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*,
>>> Accept:
>>> >>> >> >> >> >> >> >>>> >> >> >>
>>> >>> >> >> >> >> >>
>>> >>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>> >>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for
>>> more
>>> >>> >> details.
>>> >>> >> >> >> >> >> >>>> >> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in
>>> order
>>> >>> to
>>> >>> >> >> create
>>> >>> >> >> >> and
>>> >>> >> >> >> >> >> >>>> register a
>>> >>> >> >> >> >> >> >>>> >> >> >> new endpoint?
>>> >>> >> >> >> >> >> >>>> >> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
>>> >>> Noe-Payne
>>> >>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
>>> >>> Geer <
>>> >>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>>> >>> >> >> >> >> >> >>>> >> >> >> wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
>>> >>> >> Noe-Payne <
>>> >>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
>>> >>> >> Franklin <
>>> >>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM,
>>> Chris
>>> >>> >> Geer <
>>> >>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM,
>>> Erin
>>> >>> >> >> Noe-Payne
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I
>>> would
>>> >>> >> like
>>> >>> >> >> to
>>> >>> >> >> >> >> start
>>> >>> >> >> >> >> >> >>>> >> implementing
>>> >>> >> >> >> >> >> >>>> >> >> >> more
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
>>> >>> foundational
>>> >>> >> for
>>> >>> >> >> >> the
>>> >>> >> >> >> >> >> entire
>>> >>> >> >> >> >> >> >>>> >> angular
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is
>>> that
>>> >>> the
>>> >>> >> >> current
>>> >>> >> >> >> >> apis
>>> >>> >> >> >> >> >> in
>>> >>> >> >> >> >> >> >>>> trunk
>>> >>> >> >> >> >> >> >>>> >> >> are
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they
>>> are
>>> >>> not
>>> >>> >> >> tested
>>> >>> >> >> >> and
>>> >>> >> >> >> >> >> much of
>>> >>> >> >> >> >> >> >>>> >> the
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed.
>>> Are
>>> >>> any
>>> >>> >> of
>>> >>> >> >> the
>>> >>> >> >> >> >> rest
>>> >>> >> >> >> >> >> api
>>> >>> >> >> >> >> >> >>>> >> >> >> implementations
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
>>> >>> >> example? Is
>>> >>> >> >> >> there
>>> >>> >> >> >> >> >> other
>>> >>> >> >> >> >> >> >>>> >> >> >> documentation
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
>>> >>> resource
>>> >>> >> as a
>>> >>> >> >> >> >> >> "reference"
>>> >>> >> >> >> >> >> >>>> of
>>> >>> >> >> >> >> >> >>>> >> how
>>> >>> >> >> >> >> >> >>>> >> >> I'd
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> like
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a
>>> work
>>> >>> in
>>> >>> >> >> >> >> progress. I
>>> >>> >> >> >> >> >> need
>>> >>> >> >> >> >> >> >>>> to
>>> >>> >> >> >> >> >> >>>> >> go
>>> >>> >> >> >> >> >> >>>> >> >> >> back
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> and
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>>> >>> >> reimplement
>>> >>> >> >> the
>>> >>> >> >> >> >> >> "fields"
>>> >>> >> >> >> >> >> >>>> >> concept.
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should
>>> be as
>>> >>> >> flat
>>> >>> >> >> as
>>> >>> >> >> >> >> >> possible
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be
>>> made to
>>> >>> >> >> nested
>>> >>> >> >> >> >> >> resources to
>>> >>> >> >> >> >> >> >>>> >> get
>>> >>> >> >> >> >> >> >>>> >> >> >> nested
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions
>>> and
>>> >>> >> >> >> >> >> >>>> regions/1/regionwidgets,
>>> >>> >> >> >> >> >> >>>> >> >> the
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> regions
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain
>>> an
>>> >>> >> array of
>>> >>> >> >> >> >> >> >>>> regionwidgets)
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round
>>> trips to
>>> >>> >> >> support
>>> >>> >> >> >> this
>>> >>> >> >> >> >> >> when
>>> >>> >> >> >> >> >> >>>> >> >> rendering
>>> >>> >> >> >> >> >> >>>> >> >> >> the
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
>>> >>> sufficient
>>> >>> >> >> >> number of
>>> >>> >> >> >> >> >> >>>> gadgets,
>>> >>> >> >> >> >> >> >>>> >> >> adding
>>> >>> >> >> >> >> >> >>>> >> >> >> to
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> the
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes
>>> problematic.
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >>> >> >> >> >> >> >>>> >> >> >> >>>
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the
>>> "standard"
>>> >>> >> rest
>>> >>> >> >> >> >> >> endpoints for
>>> >>> >> >> >> >> >> >>>> >> crud
>>> >>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>>> >>> >> >> >> >> >> >>>> >>
>>> >>> >> >> >> >> >> >>>>
>>> >>> >> >> >> >> >>
>>> >>> >> >> >> >>
>>> >>> >> >> >>
>>> >>> >> >>
>>> >>> >>
>>> >>>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Mon, Jul 29, 2013 at 1:54 AM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Thu, Jul 25, 2013 at 11:12 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> I'm not entirely sure how to proceed at the moment. For now I will
>> start work at the repository layer and try to implement consistent
>> crud operations to support the REST api.
>>
>
> Erin, on the CXF 2.7 migration page I saw this.
>
>
>    - org.apache.cxf.jaxrs.ext.RequestHandler and
>    org.apache.cxf.jaxrs.ext.ResponseHandler (use
>    javax.ws.rs.container.ContainerRequestFilter and
>    javax.ws.rs.container.ContainerResponseFilter instead).
>
Thanks Chris, I'll take a look.

>
> So, it looks like the docs are a little out of date. The
> ContainerResponseFilter handler method gets two params, Request Context and
> Response Context. That might give you what you need. I haven't played with
> it yet but it's worth a look.
>
> Chris
>
>
>
>> On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> What about this:
>> >>
>> >>
>> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
>> >>
>> >
>> > This is referring to a RequestHandler, not a ResponseHandler. In the
>> > request handler the Message object does have correct request uri data,
>> > etc, but I don't have access to the Response object yet.
>> >
>> >> The only thing I don't like about not returning Response objects is it
>> >> doesn't let the method set HTTP specific stuff. Which just means we need
>> >> really really good filters. For example, a create should set the
>> Location
>> >> HTTP header field with the proper URL to the newly created object.
>> >>
>> >
>> > That's fair. And the controllers could return response objects and
>> > following filters could just iteratively return
>> > Response.fromResponse(). But if we take a step back from filters or
>> > interceptors or whatever implementation approach, here's the problem
>> > I'm trying to solve:
>> >
>> > Taking your Location header example - all requests to get or create an
>> > entity should have the location header set to the canonical url of the
>> > resource. Post requests creating a new resource should have a location
>> > header pointing to the newly created resource. That is universally
>> > true, and I should be able to write that code generically. I do not
>> > want to have to set the location header in every controller for every
>> > resource that handles the @POST method. That seems like it should be
>> > doable, and filters or interceptors seemed like the way to do it. Now
>> > I'm not so sure.
>> >
>> > So is that a goal worth pursuing, and if yes what is the right approach?
>> >
>> >>
>> >> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >>
>> >>> Ok, I'm having trouble setting up filters that are able to access
>> >>> query string parameters to do pagination. I've submitted a review
>> >>> request [1] with my work so far (look at pages, categories, and the
>> >>> filters). My plan was the following workflow -
>> >>>
>> >>> - Request is received and processed by the controller. Controller
>> >>> returns an object <T> or List<T> (Page, Category, etc). For any list
>> >>> resource it gets all entities, and allows the pagination filter to
>> >>> subset.
>> >>> - JsonWrapperResponseFilter process the request and wraps the data
>> >>> object in the wrapper object
>> >>> - PaginationResponseFilter checks if the data object is a list. It
>> >>> retrieves the values of limit and offset QS parameters or sets them to
>> >>> defaults. It then subsets the data and sets appropriate meta fields in
>> >>> the json object.
>> >>>
>> >>> The issue is that the response handler does not give me access (as far
>> >>> as I can tell) to the query string values. Which makes me think I'm
>> >>> missing something, or that this is the wrong way to approach the
>> >>> problem.  Any help or input is appreciated.
>> >>>
>> >>>
>> >>> [1] https://reviews.apache.org/r/12901/
>> >>>
>> >>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >>> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
>> >>> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
>> >>> >
>> >>> >
>> >>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
>> >>> > <er...@gmail.com>wrote:
>> >>> >
>> >>> >> Slight update on this journey of discovery - it looks like what we
>> >>> >> actually want to use is not interceptors, but jaxrs filters. See:
>> >>> >> http://cxf.apache.org/docs/jax-rs-filters.html
>> >>> >>
>> >>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <chris@cxtsoftware.com
>> >
>> >>> >> wrote:
>> >>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>> >>> >> erin.noe.payne@gmail.com>wrote:
>> >>> >> >
>> >>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >>> >> >> wrote:
>> >>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>> >>> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >> >> >
>> >>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
>> >>> chris@cxtsoftware.com>
>> >>> >> >> >> wrote:
>> >>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> >>> >> >> >> > <er...@gmail.com>wrote:
>> >>> >> >> >> >
>> >>> >> >> >> >> - Simple solution: All rest response models are flat. We
>> ignore
>> >>> >> any
>> >>> >> >> >> >> nested data, and just have separate endpoints to deliver
>> that
>> >>> >> data.
>> >>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package
>> has
>> >>> >> only
>> >>> >> >> >> >> properties of "primitive" types, with no lists, no other
>> >>> classes.
>> >>> >> >> That
>> >>> >> >> >> >> is NOT currently the case. Then the fields interceptor
>> checks
>> >>> for
>> >>> >> the
>> >>> >> >> >> >> presence of a fields argument. If not present, the object
>> is
>> >>> >> >> delivered
>> >>> >> >> >> >> as is. If present the argument (a string) is split by
>> comma and
>> >>> >> only
>> >>> >> >> >> >> the matched properties are delivered. The fields qs
>> argument
>> >>> only
>> >>> >> has
>> >>> >> >> >> >> to support comma-delimited list of property names.
>> >>> >> >> >> >> Ex: ?fields=name,pageType
>> >>> >> >> >> >> //returns a page or pages with only name and pageType
>> >>> properties
>> >>> >> >> >> >>
>> >>> >> >> >> >
>> >>> >> >> >> > I like the simple solution. I think the CRUD part of the API
>> >>> should
>> >>> >> >> be as
>> >>> >> >> >> > flat as possible like Erin suggested and we have "special"
>> end
>> >>> >> points
>> >>> >> >> to
>> >>> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
>> >>> >> >> >> >
>> >>> >> >> >>
>> >>> >> >> >> Just to make sure we are on the same page, my proposal is
>> that in
>> >>> >> both
>> >>> >> >> >> cases a get request without any special query string will
>> return
>> >>> only
>> >>> >> >> >> flat data. The difference is that in the second case the
>> fields
>> >>> query
>> >>> >> >> >> parameter will support a syntax that CAN deliver nested data
>> in a
>> >>> >> >> >> single request.
>> >>> >> >> >>
>> >>> >> >> >
>> >>> >> >> > That confuses me. I thought the whole point of the "special"
>> end
>> >>> point
>> >>> >> >> was
>> >>> >> >> > to handle things like page rendering in one query which would
>> >>> require
>> >>> >> >> > hierarchical data every time. Why force the use of query string
>> >>> >> params to
>> >>> >> >> > get that?
>> >>> >> >> >
>> >>> >> >>
>> >>> >> >> I was speaking in reference to the standard endpoints. The
>> >>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
>> >>> specific
>> >>> >> >> client need for a complex nested data set. It will always return
>> >>> >> >> hierarchical data, will probably not support field selection at
>> all.
>> >>> >> >>
>> >>> >> >> The standard endpoints will by default return flat data. They
>> will
>> >>> >> >> support field selection. If we choose to implement the more
>> complex
>> >>> >> >> field selection, then they will allow you to request nested data
>> >>> >> >> through the field selection syntax.
>> >>> >> >>
>> >>> >> >
>> >>> >> > ok
>> >>> >> >
>> >>> >> >>
>> >>> >> >> >>
>> >>> >> >> >> >>
>> >>> >> >> >> >> - Complicated solution: All rest response models include
>> >>> >> references
>> >>> >> >> to
>> >>> >> >> >> >> their nested data. This is the currently the case, and can
>> be
>> >>> >> seen in
>> >>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor
>> checks
>> >>> for
>> >>> >> >> >> >> presence of fields qs argument. If not present it strips
>> all
>> >>> >> nested
>> >>> >> >> >> >> data from the models and only returns properties. If it is
>> >>> >> present,
>> >>> >> >> it
>> >>> >> >> >> >> parses the argument and updates the data. The fields
>> argument
>> >>> >> needs
>> >>> >> >> to
>> >>> >> >> >> >> support a more complicated syntax that allows the
>> requesting of
>> >>> >> >> nested
>> >>> >> >> >> >> data. I would copy the syntax of facebook's graph search
>> api,
>> >>> >> which
>> >>> >> >> >> >> has a pretty readable solution. You allow for .fields and
>> >>> .limit
>> >>> >> on
>> >>> >> >> >> >> fields, which can be nested.
>> >>> >> >> >> >> Ex:
>> >>> >> >> >> >>
>> >>> >> >> >>
>> >>> >> >>
>> >>> >>
>> >>>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >>> >> >> >> >> //returns a page or pages with name and pageType
>> properties,
>> >>> >> nested
>> >>> >> >> >> >> list of regions (max of 2) with nested list of
>> regionWidgets
>> >>> with
>> >>> >> >> only
>> >>> >> >> >> >> properties of widgetId and locked
>> >>> >> >> >> >>
>> >>> >> >> >> >> In all cases, id should always be returned.
>> >>> >> >> >> >> I think the algorithm in the simple solution is easy.
>> >>> >> >> >> >> In a sense the algorithm in the second should be simple,
>> >>> because
>> >>> >> the
>> >>> >> >> >> >> service layer is already getting all the nested data, and
>> you
>> >>> are
>> >>> >> >> just
>> >>> >> >> >> >> stripping it off. Not sure what the performance
>> implications of
>> >>> >> that
>> >>> >> >> >> >> are though.
>> >>> >> >> >> >>
>> >>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>> >>> >> chris@cxtsoftware.com>
>> >>> >> >> >> wrote:
>> >>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >>> >> >> >> >> > <er...@gmail.com>wrote:
>> >>> >> >> >> >> >
>> >>> >> >> >> >> >> Going back to the discussion on field selection - I am
>> >>> >> currently
>> >>> >> >> >> going
>> >>> >> >> >> >> >> through the exercise of writing out the Resource
>> interfaces
>> >>> to
>> >>> >> >> define
>> >>> >> >> >> >> >> our endpoints.  There is a set of generic query string
>> >>> >> parameters
>> >>> >> >> >> that
>> >>> >> >> >> >> >> we wish to support on all or many of the endpoints -
>> fields
>> >>> >> (any
>> >>> >> >> get
>> >>> >> >> >> >> >> request), limit / offset (any get request that returns a
>> >>> list).
>> >>> >> >> >> >> >>
>> >>> >> >> >> >> >> Rather than writing each endpoint to accept
>> QueryParam()'s
>> >>> and
>> >>> >> >> repeat
>> >>> >> >> >> >> >> the appropriate logic, I assume we would want to take
>> >>> >> advantage of
>> >>> >> >> >> cxf
>> >>> >> >> >> >> >> interceptors [1] to intelligently and generically handle
>> >>> those
>> >>> >> qs
>> >>> >> >> >> >> >> arguments?
>> >>> >> >> >> >> >>
>> >>> >> >> >> >> >
>> >>> >> >> >> >> > I like the concept but I'm not sure how we generically
>> >>> filter,
>> >>> >> >> >> especially
>> >>> >> >> >> >> > with nested data. I'd love to see it work that way
>> though.
>> >>> >> >> >> Interceptors
>> >>> >> >> >> >> are
>> >>> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
>> >>> figured
>> >>> >> out
>> >>> >> >> >> yet.
>> >>> >> >> >> >> > Thoughts?
>> >>> >> >> >> >> >
>> >>> >> >> >> >> >>
>> >>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >>> >> >> >> >> >>
>> >>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >>> >> >> >> >> >> <er...@gmail.com> wrote:
>> >>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts
>> about the
>> >>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the
>> best
>> >>> >> way
>> >>> >> >> to
>> >>> >> >> >> get
>> >>> >> >> >> >> >> > wrapped responses?
>> >>> >> >> >> >> >> >
>> >>> >> >> >> >> >> > For the next step I would like to start writing out
>> all of
>> >>> >> the
>> >>> >> >> >> >> >> > resource interfaces so that we can begin writing
>> angular
>> >>> >> >> $resource
>> >>> >> >> >> >> >> > services against them.
>> >>> >> >> >> >> >> >
>> >>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >>> >> >> >> >> >> > <er...@gmail.com> wrote:
>> >>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever
>> figured
>> >>> >> that
>> >>> >> >> one
>> >>> >> >> >> >> >> out...
>> >>> >> >> >> >> >> >>
>> >>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> >>> >> >> >> chris@cxtsoftware.com>
>> >>> >> >> >> >> >> wrote:
>> >>> >> >> >> >> >> >>> Erin,
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple
>> things:
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
>> >>> methods
>> >>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class,
>> remove
>> >>> the
>> >>> >> >> >> @ParamPath
>> >>> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
>> >>> puts
>> >>> >> >> those
>> >>> >> >> >> in
>> >>> >> >> >> >> >> there
>> >>> >> >> >> >> >> >>> but they cause problems. Only the interface should
>> be
>> >>> >> >> annotated.
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>> Chris
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >> >> >> >> >> >>>
>> >>> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
>> >>> >> accepting
>> >>> >> >> the
>> >>> >> >> >> >> valid
>> >>> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to
>> the
>> >>> >> >> review.
>> >>> >> >> >> >> >> >>>>
>> >>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> >>> >> >> >> chris@cxtsoftware.com
>> >>> >> >> >> >> >
>> >>> >> >> >> >> >> wrote:
>> >>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >>> >> >> >> >> >> >>>> >
>> >>> >> >> >> >> >> >>>> >
>> >>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >>> >> >> >> >> >> >>>> >
>> >>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as
>> expected.
>> >>> I've
>> >>> >> >> posted
>> >>> >> >> >> >> the
>> >>> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a
>> look
>> >>> and
>> >>> >> >> offer
>> >>> >> >> >> >> >> advice -
>> >>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >>> >> >> >> >> >> >>>> >>
>> >>> >> >> >> >> >> >>>> >> Thanks
>> >>> >> >> >> >> >> >>>> >>
>> >>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> >>> >> >> >> >> chris@cxtsoftware.com
>> >>> >> >> >> >> >> >
>> >>> >> >> >> >> >> >>>> wrote:
>> >>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne
>> wrote:
>> >>> >> >> >> >> >> >>>> >> >
>> >>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >>> >> >> >> >> >> chris@cxtsoftware.com
>> >>> >> >> >> >> >> >>>> >> <javascript:;>>
>> >>> >> >> >> >> >> >>>> >> >> wrote:
>> >>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the
>> bean,
>> >>> then
>> >>> >> >> >> reference
>> >>> >> >> >> >> >> it in
>> >>> >> >> >> >> >> >>>> the
>> >>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
>> >>> that...no,
>> >>> >> >> that
>> >>> >> >> >> >> >> should be
>> >>> >> >> >> >> >> >>>> >> all. I
>> >>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
>> >>> resource.
>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the
>> service
>> >>> >> >> injection,
>> >>> >> >> >> >> >> which may
>> >>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
>> >>> though.
>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
>> >>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
>> >>> widget
>> >>> >> >> >> outside a
>> >>> >> >> >> >> >> region
>> >>> >> >> >> >> >> >>>> >> >> outside
>> >>> >> >> >> >> >> >>>> >> >> > a page?
>> >>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
>> >>> proof
>> >>> >> of
>> >>> >> >> >> concept
>> >>> >> >> >> >> >> with
>> >>> >> >> >> >> >> >>>> the
>> >>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something
>> simple
>> >>> >> with
>> >>> >> >> the
>> >>> >> >> >> >> >> service and
>> >>> >> >> >> >> >> >>>> >> >> rest models already in place.
>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
>> >>> dealing
>> >>> >> with
>> >>> >> >> >> >> region
>> >>> >> >> >> >> >> >>>> widgets
>> >>> >> >> >> >> >> >>>> >> >> as a nested resource
>> (pages/:id/regions/:id...)
>> >>> over
>> >>> >> >> just
>> >>> >> >> >> >> >> dealing
>> >>> >> >> >> >> >> >>>> with
>> >>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
>> >>> pages
>> >>> >> >> >> >> controller,
>> >>> >> >> >> >> >> >>>> rather
>> >>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with
>> resource
>> >>> >> >> concerns
>> >>> >> >> >> >> >> separately.
>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
>> >>> >> >> regionwidgets
>> >>> >> >> >> only
>> >>> >> >> >> >> >> making
>> >>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you
>> could say
>> >>> >> the
>> >>> >> >> same
>> >>> >> >> >> >> >> thing for
>> >>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both
>> entities are
>> >>> >> >> always
>> >>> >> >> >> >> >> uniquely
>> >>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
>> >>> individually?
>> >>> >> I
>> >>> >> >> see
>> >>> >> >> >> an
>> >>> >> >> >> >> >> upside
>> >>> >> >> >> >> >> >>>> of
>> >>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
>> >>> see no
>> >>> >> >> >> >> downside.
>> >>> >> >> >> >> >> >>>> >> >
>> >>> >> >> >> >> >> >>>> >> >
>> >>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
>> >>> >> uniquely
>> >>> >> >> >> >> >> identified and
>> >>> >> >> >> >> >> >>>> are
>> >>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that
>> is a
>> >>> >> >> longer
>> >>> >> >> >> >> >> >>>> conversation.
>> >>> >> >> >> >> >> >>>> >> >
>> >>> >> >> >> >> >> >>>> >> >>
>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
>> >>> Noe-Payne
>> >>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >>> >> >> >> >> >> >>>> >> >> >
>> >>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>> >>> >> >> >> regionWidgets.
>> >>> >> >> >> >> I've
>> >>> >> >> >> >> >> >>>> added
>> >>> >> >> >> >> >> >>>> >> >> >> the interface and default implementation,
>> and
>> >>> >> >> created /
>> >>> >> >> >> >> >> registered
>> >>> >> >> >> >> >> >>>> >> the
>> >>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
>> >>> error:
>> >>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
>> >>> >> operation
>> >>> >> >> >> >> matching
>> >>> >> >> >> >> >> >>>> request
>> >>> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
>> >>> found,
>> >>> >> >> >> Relative
>> >>> >> >> >> >> >> Path:
>> >>> >> >> >> >> >> >>>> /1,
>> >>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*,
>> Accept:
>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >> >> >> >> >>
>> >>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for
>> more
>> >>> >> details.
>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in
>> order
>> >>> to
>> >>> >> >> create
>> >>> >> >> >> and
>> >>> >> >> >> >> >> >>>> register a
>> >>> >> >> >> >> >> >>>> >> >> >> new endpoint?
>> >>> >> >> >> >> >> >>>> >> >> >>
>> >>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
>> >>> Noe-Payne
>> >>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
>> >>> Geer <
>> >>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>> >>> >> >> >> >> >> >>>> >> >> >> wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
>> >>> >> Noe-Payne <
>> >>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> >>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
>> >>> >> Franklin <
>> >>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM,
>> Chris
>> >>> >> Geer <
>> >>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM,
>> Erin
>> >>> >> >> Noe-Payne
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I
>> would
>> >>> >> like
>> >>> >> >> to
>> >>> >> >> >> >> start
>> >>> >> >> >> >> >> >>>> >> implementing
>> >>> >> >> >> >> >> >>>> >> >> >> more
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
>> >>> foundational
>> >>> >> for
>> >>> >> >> >> the
>> >>> >> >> >> >> >> entire
>> >>> >> >> >> >> >> >>>> >> angular
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is
>> that
>> >>> the
>> >>> >> >> current
>> >>> >> >> >> >> apis
>> >>> >> >> >> >> >> in
>> >>> >> >> >> >> >> >>>> trunk
>> >>> >> >> >> >> >> >>>> >> >> are
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they
>> are
>> >>> not
>> >>> >> >> tested
>> >>> >> >> >> and
>> >>> >> >> >> >> >> much of
>> >>> >> >> >> >> >> >>>> >> the
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed.
>> Are
>> >>> any
>> >>> >> of
>> >>> >> >> the
>> >>> >> >> >> >> rest
>> >>> >> >> >> >> >> api
>> >>> >> >> >> >> >> >>>> >> >> >> implementations
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
>> >>> >> example? Is
>> >>> >> >> >> there
>> >>> >> >> >> >> >> other
>> >>> >> >> >> >> >> >>>> >> >> >> documentation
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
>> >>> resource
>> >>> >> as a
>> >>> >> >> >> >> >> "reference"
>> >>> >> >> >> >> >> >>>> of
>> >>> >> >> >> >> >> >>>> >> how
>> >>> >> >> >> >> >> >>>> >> >> I'd
>> >>> >> >> >> >> >> >>>> >> >> >> >>> like
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a
>> work
>> >>> in
>> >>> >> >> >> >> progress. I
>> >>> >> >> >> >> >> need
>> >>> >> >> >> >> >> >>>> to
>> >>> >> >> >> >> >> >>>> >> go
>> >>> >> >> >> >> >> >>>> >> >> >> back
>> >>> >> >> >> >> >> >>>> >> >> >> >>> and
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>> >>> >> reimplement
>> >>> >> >> the
>> >>> >> >> >> >> >> "fields"
>> >>> >> >> >> >> >> >>>> >> concept.
>> >>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should
>> be as
>> >>> >> flat
>> >>> >> >> as
>> >>> >> >> >> >> >> possible
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be
>> made to
>> >>> >> >> nested
>> >>> >> >> >> >> >> resources to
>> >>> >> >> >> >> >> >>>> >> get
>> >>> >> >> >> >> >> >>>> >> >> >> nested
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions
>> and
>> >>> >> >> >> >> >> >>>> regions/1/regionwidgets,
>> >>> >> >> >> >> >> >>>> >> >> the
>> >>> >> >> >> >> >> >>>> >> >> >> >>> regions
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain
>> an
>> >>> >> array of
>> >>> >> >> >> >> >> >>>> regionwidgets)
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round
>> trips to
>> >>> >> >> support
>> >>> >> >> >> this
>> >>> >> >> >> >> >> when
>> >>> >> >> >> >> >> >>>> >> >> rendering
>> >>> >> >> >> >> >> >>>> >> >> >> the
>> >>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
>> >>> sufficient
>> >>> >> >> >> number of
>> >>> >> >> >> >> >> >>>> gadgets,
>> >>> >> >> >> >> >> >>>> >> >> adding
>> >>> >> >> >> >> >> >>>> >> >> >> to
>> >>> >> >> >> >> >> >>>> >> >> >> >>> the
>> >>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes
>> problematic.
>> >>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >>> >> >> >> >> >> >>>> >> >> >> >>>
>> >>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the
>> "standard"
>> >>> >> rest
>> >>> >> >> >> >> >> endpoints for
>> >>> >> >> >> >> >> >>>> >> crud
>> >>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>> >>> >> >> >> >> >> >>>> >>
>> >>> >> >> >> >> >> >>>>
>> >>> >> >> >> >> >>
>> >>> >> >> >> >>
>> >>> >> >> >>
>> >>> >> >>
>> >>> >>
>> >>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Thu, Jul 25, 2013 at 11:12 AM, Erin Noe-Payne
<er...@gmail.com>wrote:

> I'm not entirely sure how to proceed at the moment. For now I will
> start work at the repository layer and try to implement consistent
> crud operations to support the REST api.
>

Erin, on the CXF 2.7 migration page I saw this.


   - org.apache.cxf.jaxrs.ext.RequestHandler and
   org.apache.cxf.jaxrs.ext.ResponseHandler (use
   javax.ws.rs.container.ContainerRequestFilter and
   javax.ws.rs.container.ContainerResponseFilter instead).


So, it looks like the docs are a little out of date. The
ContainerResponseFilter handler method gets two params, Request Context and
Response Context. That might give you what you need. I haven't played with
it yet but it's worth a look.

Chris



> On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> What about this:
> >>
> >>
> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
> >>
> >
> > This is referring to a RequestHandler, not a ResponseHandler. In the
> > request handler the Message object does have correct request uri data,
> > etc, but I don't have access to the Response object yet.
> >
> >> The only thing I don't like about not returning Response objects is it
> >> doesn't let the method set HTTP specific stuff. Which just means we need
> >> really really good filters. For example, a create should set the
> Location
> >> HTTP header field with the proper URL to the newly created object.
> >>
> >
> > That's fair. And the controllers could return response objects and
> > following filters could just iteratively return
> > Response.fromResponse(). But if we take a step back from filters or
> > interceptors or whatever implementation approach, here's the problem
> > I'm trying to solve:
> >
> > Taking your Location header example - all requests to get or create an
> > entity should have the location header set to the canonical url of the
> > resource. Post requests creating a new resource should have a location
> > header pointing to the newly created resource. That is universally
> > true, and I should be able to write that code generically. I do not
> > want to have to set the location header in every controller for every
> > resource that handles the @POST method. That seems like it should be
> > doable, and filters or interceptors seemed like the way to do it. Now
> > I'm not so sure.
> >
> > So is that a goal worth pursuing, and if yes what is the right approach?
> >
> >>
> >> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >>
> >>> Ok, I'm having trouble setting up filters that are able to access
> >>> query string parameters to do pagination. I've submitted a review
> >>> request [1] with my work so far (look at pages, categories, and the
> >>> filters). My plan was the following workflow -
> >>>
> >>> - Request is received and processed by the controller. Controller
> >>> returns an object <T> or List<T> (Page, Category, etc). For any list
> >>> resource it gets all entities, and allows the pagination filter to
> >>> subset.
> >>> - JsonWrapperResponseFilter process the request and wraps the data
> >>> object in the wrapper object
> >>> - PaginationResponseFilter checks if the data object is a list. It
> >>> retrieves the values of limit and offset QS parameters or sets them to
> >>> defaults. It then subsets the data and sets appropriate meta fields in
> >>> the json object.
> >>>
> >>> The issue is that the response handler does not give me access (as far
> >>> as I can tell) to the query string values. Which makes me think I'm
> >>> missing something, or that this is the wrong way to approach the
> >>> problem.  Any help or input is appreciated.
> >>>
> >>>
> >>> [1] https://reviews.apache.org/r/12901/
> >>>
> >>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >>> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
> >>> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
> >>> >
> >>> >
> >>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
> >>> > <er...@gmail.com>wrote:
> >>> >
> >>> >> Slight update on this journey of discovery - it looks like what we
> >>> >> actually want to use is not interceptors, but jaxrs filters. See:
> >>> >> http://cxf.apache.org/docs/jax-rs-filters.html
> >>> >>
> >>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <chris@cxtsoftware.com
> >
> >>> >> wrote:
> >>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
> >>> >> erin.noe.payne@gmail.com>wrote:
> >>> >> >
> >>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <
> chris@cxtsoftware.com>
> >>> >> >> wrote:
> >>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
> >>> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >> >> >
> >>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
> >>> chris@cxtsoftware.com>
> >>> >> >> >> wrote:
> >>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> >>> >> >> >> > <er...@gmail.com>wrote:
> >>> >> >> >> >
> >>> >> >> >> >> - Simple solution: All rest response models are flat. We
> ignore
> >>> >> any
> >>> >> >> >> >> nested data, and just have separate endpoints to deliver
> that
> >>> >> data.
> >>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package
> has
> >>> >> only
> >>> >> >> >> >> properties of "primitive" types, with no lists, no other
> >>> classes.
> >>> >> >> That
> >>> >> >> >> >> is NOT currently the case. Then the fields interceptor
> checks
> >>> for
> >>> >> the
> >>> >> >> >> >> presence of a fields argument. If not present, the object
> is
> >>> >> >> delivered
> >>> >> >> >> >> as is. If present the argument (a string) is split by
> comma and
> >>> >> only
> >>> >> >> >> >> the matched properties are delivered. The fields qs
> argument
> >>> only
> >>> >> has
> >>> >> >> >> >> to support comma-delimited list of property names.
> >>> >> >> >> >> Ex: ?fields=name,pageType
> >>> >> >> >> >> //returns a page or pages with only name and pageType
> >>> properties
> >>> >> >> >> >>
> >>> >> >> >> >
> >>> >> >> >> > I like the simple solution. I think the CRUD part of the API
> >>> should
> >>> >> >> be as
> >>> >> >> >> > flat as possible like Erin suggested and we have "special"
> end
> >>> >> points
> >>> >> >> to
> >>> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
> >>> >> >> >> >
> >>> >> >> >>
> >>> >> >> >> Just to make sure we are on the same page, my proposal is
> that in
> >>> >> both
> >>> >> >> >> cases a get request without any special query string will
> return
> >>> only
> >>> >> >> >> flat data. The difference is that in the second case the
> fields
> >>> query
> >>> >> >> >> parameter will support a syntax that CAN deliver nested data
> in a
> >>> >> >> >> single request.
> >>> >> >> >>
> >>> >> >> >
> >>> >> >> > That confuses me. I thought the whole point of the "special"
> end
> >>> point
> >>> >> >> was
> >>> >> >> > to handle things like page rendering in one query which would
> >>> require
> >>> >> >> > hierarchical data every time. Why force the use of query string
> >>> >> params to
> >>> >> >> > get that?
> >>> >> >> >
> >>> >> >>
> >>> >> >> I was speaking in reference to the standard endpoints. The
> >>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
> >>> specific
> >>> >> >> client need for a complex nested data set. It will always return
> >>> >> >> hierarchical data, will probably not support field selection at
> all.
> >>> >> >>
> >>> >> >> The standard endpoints will by default return flat data. They
> will
> >>> >> >> support field selection. If we choose to implement the more
> complex
> >>> >> >> field selection, then they will allow you to request nested data
> >>> >> >> through the field selection syntax.
> >>> >> >>
> >>> >> >
> >>> >> > ok
> >>> >> >
> >>> >> >>
> >>> >> >> >>
> >>> >> >> >> >>
> >>> >> >> >> >> - Complicated solution: All rest response models include
> >>> >> references
> >>> >> >> to
> >>> >> >> >> >> their nested data. This is the currently the case, and can
> be
> >>> >> seen in
> >>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor
> checks
> >>> for
> >>> >> >> >> >> presence of fields qs argument. If not present it strips
> all
> >>> >> nested
> >>> >> >> >> >> data from the models and only returns properties. If it is
> >>> >> present,
> >>> >> >> it
> >>> >> >> >> >> parses the argument and updates the data. The fields
> argument
> >>> >> needs
> >>> >> >> to
> >>> >> >> >> >> support a more complicated syntax that allows the
> requesting of
> >>> >> >> nested
> >>> >> >> >> >> data. I would copy the syntax of facebook's graph search
> api,
> >>> >> which
> >>> >> >> >> >> has a pretty readable solution. You allow for .fields and
> >>> .limit
> >>> >> on
> >>> >> >> >> >> fields, which can be nested.
> >>> >> >> >> >> Ex:
> >>> >> >> >> >>
> >>> >> >> >>
> >>> >> >>
> >>> >>
> >>>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >>> >> >> >> >> //returns a page or pages with name and pageType
> properties,
> >>> >> nested
> >>> >> >> >> >> list of regions (max of 2) with nested list of
> regionWidgets
> >>> with
> >>> >> >> only
> >>> >> >> >> >> properties of widgetId and locked
> >>> >> >> >> >>
> >>> >> >> >> >> In all cases, id should always be returned.
> >>> >> >> >> >> I think the algorithm in the simple solution is easy.
> >>> >> >> >> >> In a sense the algorithm in the second should be simple,
> >>> because
> >>> >> the
> >>> >> >> >> >> service layer is already getting all the nested data, and
> you
> >>> are
> >>> >> >> just
> >>> >> >> >> >> stripping it off. Not sure what the performance
> implications of
> >>> >> that
> >>> >> >> >> >> are though.
> >>> >> >> >> >>
> >>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
> >>> >> chris@cxtsoftware.com>
> >>> >> >> >> wrote:
> >>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >>> >> >> >> >> > <er...@gmail.com>wrote:
> >>> >> >> >> >> >
> >>> >> >> >> >> >> Going back to the discussion on field selection - I am
> >>> >> currently
> >>> >> >> >> going
> >>> >> >> >> >> >> through the exercise of writing out the Resource
> interfaces
> >>> to
> >>> >> >> define
> >>> >> >> >> >> >> our endpoints.  There is a set of generic query string
> >>> >> parameters
> >>> >> >> >> that
> >>> >> >> >> >> >> we wish to support on all or many of the endpoints -
> fields
> >>> >> (any
> >>> >> >> get
> >>> >> >> >> >> >> request), limit / offset (any get request that returns a
> >>> list).
> >>> >> >> >> >> >>
> >>> >> >> >> >> >> Rather than writing each endpoint to accept
> QueryParam()'s
> >>> and
> >>> >> >> repeat
> >>> >> >> >> >> >> the appropriate logic, I assume we would want to take
> >>> >> advantage of
> >>> >> >> >> cxf
> >>> >> >> >> >> >> interceptors [1] to intelligently and generically handle
> >>> those
> >>> >> qs
> >>> >> >> >> >> >> arguments?
> >>> >> >> >> >> >>
> >>> >> >> >> >> >
> >>> >> >> >> >> > I like the concept but I'm not sure how we generically
> >>> filter,
> >>> >> >> >> especially
> >>> >> >> >> >> > with nested data. I'd love to see it work that way
> though.
> >>> >> >> >> Interceptors
> >>> >> >> >> >> are
> >>> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
> >>> figured
> >>> >> out
> >>> >> >> >> yet.
> >>> >> >> >> >> > Thoughts?
> >>> >> >> >> >> >
> >>> >> >> >> >> >>
> >>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >>> >> >> >> >> >>
> >>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >>> >> >> >> >> >> <er...@gmail.com> wrote:
> >>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts
> about the
> >>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the
> best
> >>> >> way
> >>> >> >> to
> >>> >> >> >> get
> >>> >> >> >> >> >> > wrapped responses?
> >>> >> >> >> >> >> >
> >>> >> >> >> >> >> > For the next step I would like to start writing out
> all of
> >>> >> the
> >>> >> >> >> >> >> > resource interfaces so that we can begin writing
> angular
> >>> >> >> $resource
> >>> >> >> >> >> >> > services against them.
> >>> >> >> >> >> >> >
> >>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >>> >> >> >> >> >> > <er...@gmail.com> wrote:
> >>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever
> figured
> >>> >> that
> >>> >> >> one
> >>> >> >> >> >> >> out...
> >>> >> >> >> >> >> >>
> >>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> >>> >> >> >> chris@cxtsoftware.com>
> >>> >> >> >> >> >> wrote:
> >>> >> >> >> >> >> >>> Erin,
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple
> things:
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
> >>> methods
> >>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class,
> remove
> >>> the
> >>> >> >> >> @ParamPath
> >>> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
> >>> puts
> >>> >> >> those
> >>> >> >> >> in
> >>> >> >> >> >> >> there
> >>> >> >> >> >> >> >>> but they cause problems. Only the interface should
> be
> >>> >> >> annotated.
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>> Chris
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >> >> >> >> >> >>>
> >>> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
> >>> >> accepting
> >>> >> >> the
> >>> >> >> >> >> valid
> >>> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to
> the
> >>> >> >> review.
> >>> >> >> >> >> >> >>>>
> >>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> >>> >> >> >> chris@cxtsoftware.com
> >>> >> >> >> >> >
> >>> >> >> >> >> >> wrote:
> >>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >>> >> >> >> >> >> >>>> >
> >>> >> >> >> >> >> >>>> >
> >>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >>> >> >> >> >> >> >>>> >
> >>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as
> expected.
> >>> I've
> >>> >> >> posted
> >>> >> >> >> >> the
> >>> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a
> look
> >>> and
> >>> >> >> offer
> >>> >> >> >> >> >> advice -
> >>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >>> >> >> >> >> >> >>>> >>
> >>> >> >> >> >> >> >>>> >> Thanks
> >>> >> >> >> >> >> >>>> >>
> >>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> >>> >> >> >> >> chris@cxtsoftware.com
> >>> >> >> >> >> >> >
> >>> >> >> >> >> >> >>>> wrote:
> >>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne
> wrote:
> >>> >> >> >> >> >> >>>> >> >
> >>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >>> >> >> >> >> >> chris@cxtsoftware.com
> >>> >> >> >> >> >> >>>> >> <javascript:;>>
> >>> >> >> >> >> >> >>>> >> >> wrote:
> >>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the
> bean,
> >>> then
> >>> >> >> >> reference
> >>> >> >> >> >> >> it in
> >>> >> >> >> >> >> >>>> the
> >>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
> >>> that...no,
> >>> >> >> that
> >>> >> >> >> >> >> should be
> >>> >> >> >> >> >> >>>> >> all. I
> >>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
> >>> resource.
> >>> >> >> >> >> >> >>>> >> >> >
> >>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the
> service
> >>> >> >> injection,
> >>> >> >> >> >> >> which may
> >>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
> >>> though.
> >>> >> >> >> >> >> >>>> >> >>
> >>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
> >>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
> >>> widget
> >>> >> >> >> outside a
> >>> >> >> >> >> >> region
> >>> >> >> >> >> >> >>>> >> >> outside
> >>> >> >> >> >> >> >>>> >> >> > a page?
> >>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
> >>> proof
> >>> >> of
> >>> >> >> >> concept
> >>> >> >> >> >> >> with
> >>> >> >> >> >> >> >>>> the
> >>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something
> simple
> >>> >> with
> >>> >> >> the
> >>> >> >> >> >> >> service and
> >>> >> >> >> >> >> >>>> >> >> rest models already in place.
> >>> >> >> >> >> >> >>>> >> >>
> >>> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
> >>> dealing
> >>> >> with
> >>> >> >> >> >> region
> >>> >> >> >> >> >> >>>> widgets
> >>> >> >> >> >> >> >>>> >> >> as a nested resource
> (pages/:id/regions/:id...)
> >>> over
> >>> >> >> just
> >>> >> >> >> >> >> dealing
> >>> >> >> >> >> >> >>>> with
> >>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
> >>> pages
> >>> >> >> >> >> controller,
> >>> >> >> >> >> >> >>>> rather
> >>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with
> resource
> >>> >> >> concerns
> >>> >> >> >> >> >> separately.
> >>> >> >> >> >> >> >>>> >> >>
> >>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
> >>> >> >> regionwidgets
> >>> >> >> >> only
> >>> >> >> >> >> >> making
> >>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you
> could say
> >>> >> the
> >>> >> >> same
> >>> >> >> >> >> >> thing for
> >>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both
> entities are
> >>> >> >> always
> >>> >> >> >> >> >> uniquely
> >>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
> >>> individually?
> >>> >> I
> >>> >> >> see
> >>> >> >> >> an
> >>> >> >> >> >> >> upside
> >>> >> >> >> >> >> >>>> of
> >>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
> >>> see no
> >>> >> >> >> >> downside.
> >>> >> >> >> >> >> >>>> >> >
> >>> >> >> >> >> >> >>>> >> >
> >>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
> >>> >> uniquely
> >>> >> >> >> >> >> identified and
> >>> >> >> >> >> >> >>>> are
> >>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that
> is a
> >>> >> >> longer
> >>> >> >> >> >> >> >>>> conversation.
> >>> >> >> >> >> >> >>>> >> >
> >>> >> >> >> >> >> >>>> >> >>
> >>> >> >> >> >> >> >>>> >> >> >
> >>> >> >> >> >> >> >>>> >> >> >
> >>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
> >>> Noe-Payne
> >>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >>> >> >> >> >> >> >>>> >> >> >
> >>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
> >>> >> >> >> regionWidgets.
> >>> >> >> >> >> I've
> >>> >> >> >> >> >> >>>> added
> >>> >> >> >> >> >> >>>> >> >> >> the interface and default implementation,
> and
> >>> >> >> created /
> >>> >> >> >> >> >> registered
> >>> >> >> >> >> >> >>>> >> the
> >>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
> >>> error:
> >>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
> >>> >> operation
> >>> >> >> >> >> matching
> >>> >> >> >> >> >> >>>> request
> >>> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
> >>> found,
> >>> >> >> >> Relative
> >>> >> >> >> >> >> Path:
> >>> >> >> >> >> >> >>>> /1,
> >>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*,
> Accept:
> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >> >> >> >> >>
> >>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for
> more
> >>> >> details.
> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in
> order
> >>> to
> >>> >> >> create
> >>> >> >> >> and
> >>> >> >> >> >> >> >>>> register a
> >>> >> >> >> >> >> >>>> >> >> >> new endpoint?
> >>> >> >> >> >> >> >>>> >> >> >>
> >>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
> >>> Noe-Payne
> >>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
> >>> Geer <
> >>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
> >>> >> >> >> >> >> >>>> >> >> >> wrote:
> >>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
> >>> >> Noe-Payne <
> >>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >> >> >> >> >> >>>> >> >> >> >>
> >>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
> >>> >> Franklin <
> >>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM,
> Chris
> >>> >> Geer <
> >>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
> >>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM,
> Erin
> >>> >> >> Noe-Payne
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I
> would
> >>> >> like
> >>> >> >> to
> >>> >> >> >> >> start
> >>> >> >> >> >> >> >>>> >> implementing
> >>> >> >> >> >> >> >>>> >> >> >> more
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
> >>> foundational
> >>> >> for
> >>> >> >> >> the
> >>> >> >> >> >> >> entire
> >>> >> >> >> >> >> >>>> >> angular
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is
> that
> >>> the
> >>> >> >> current
> >>> >> >> >> >> apis
> >>> >> >> >> >> >> in
> >>> >> >> >> >> >> >>>> trunk
> >>> >> >> >> >> >> >>>> >> >> are
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they
> are
> >>> not
> >>> >> >> tested
> >>> >> >> >> and
> >>> >> >> >> >> >> much of
> >>> >> >> >> >> >> >>>> >> the
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed.
> Are
> >>> any
> >>> >> of
> >>> >> >> the
> >>> >> >> >> >> rest
> >>> >> >> >> >> >> api
> >>> >> >> >> >> >> >>>> >> >> >> implementations
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
> >>> >> example? Is
> >>> >> >> >> there
> >>> >> >> >> >> >> other
> >>> >> >> >> >> >> >>>> >> >> >> documentation
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
> >>> resource
> >>> >> as a
> >>> >> >> >> >> >> "reference"
> >>> >> >> >> >> >> >>>> of
> >>> >> >> >> >> >> >>>> >> how
> >>> >> >> >> >> >> >>>> >> >> I'd
> >>> >> >> >> >> >> >>>> >> >> >> >>> like
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a
> work
> >>> in
> >>> >> >> >> >> progress. I
> >>> >> >> >> >> >> need
> >>> >> >> >> >> >> >>>> to
> >>> >> >> >> >> >> >>>> >> go
> >>> >> >> >> >> >> >>>> >> >> >> back
> >>> >> >> >> >> >> >>>> >> >> >> >>> and
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
> >>> >> reimplement
> >>> >> >> the
> >>> >> >> >> >> >> "fields"
> >>> >> >> >> >> >> >>>> >> concept.
> >>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should
> be as
> >>> >> flat
> >>> >> >> as
> >>> >> >> >> >> >> possible
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be
> made to
> >>> >> >> nested
> >>> >> >> >> >> >> resources to
> >>> >> >> >> >> >> >>>> >> get
> >>> >> >> >> >> >> >>>> >> >> >> nested
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions
> and
> >>> >> >> >> >> >> >>>> regions/1/regionwidgets,
> >>> >> >> >> >> >> >>>> >> >> the
> >>> >> >> >> >> >> >>>> >> >> >> >>> regions
> >>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain
> an
> >>> >> array of
> >>> >> >> >> >> >> >>>> regionwidgets)
> >>> >> >> >> >> >> >>>> >> >> >> >>> >>
> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round
> trips to
> >>> >> >> support
> >>> >> >> >> this
> >>> >> >> >> >> >> when
> >>> >> >> >> >> >> >>>> >> >> rendering
> >>> >> >> >> >> >> >>>> >> >> >> the
> >>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
> >>> sufficient
> >>> >> >> >> number of
> >>> >> >> >> >> >> >>>> gadgets,
> >>> >> >> >> >> >> >>>> >> >> adding
> >>> >> >> >> >> >> >>>> >> >> >> to
> >>> >> >> >> >> >> >>>> >> >> >> >>> the
> >>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes
> problematic.
> >>> >> >> >> >> >> >>>> >> >> >> >>> >
> >>> >> >> >> >> >> >>>> >> >> >> >>>
> >>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the
> "standard"
> >>> >> rest
> >>> >> >> >> >> >> endpoints for
> >>> >> >> >> >> >> >>>> >> crud
> >>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
> >>> >> >> >> >> >> >>>> >>
> >>> >> >> >> >> >> >>>>
> >>> >> >> >> >> >>
> >>> >> >> >> >>
> >>> >> >> >>
> >>> >> >>
> >>> >>
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
I'm not entirely sure how to proceed at the moment. For now I will
start work at the repository layer and try to implement consistent
crud operations to support the REST api.

On Wed, Jul 24, 2013 at 1:59 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> What about this:
>>
>> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
>>
>
> This is referring to a RequestHandler, not a ResponseHandler. In the
> request handler the Message object does have correct request uri data,
> etc, but I don't have access to the Response object yet.
>
>> The only thing I don't like about not returning Response objects is it
>> doesn't let the method set HTTP specific stuff. Which just means we need
>> really really good filters. For example, a create should set the Location
>> HTTP header field with the proper URL to the newly created object.
>>
>
> That's fair. And the controllers could return response objects and
> following filters could just iteratively return
> Response.fromResponse(). But if we take a step back from filters or
> interceptors or whatever implementation approach, here's the problem
> I'm trying to solve:
>
> Taking your Location header example - all requests to get or create an
> entity should have the location header set to the canonical url of the
> resource. Post requests creating a new resource should have a location
> header pointing to the newly created resource. That is universally
> true, and I should be able to write that code generically. I do not
> want to have to set the location header in every controller for every
> resource that handles the @POST method. That seems like it should be
> doable, and filters or interceptors seemed like the way to do it. Now
> I'm not so sure.
>
> So is that a goal worth pursuing, and if yes what is the right approach?
>
>>
>> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <er...@gmail.com>wrote:
>>
>>> Ok, I'm having trouble setting up filters that are able to access
>>> query string parameters to do pagination. I've submitted a review
>>> request [1] with my work so far (look at pages, categories, and the
>>> filters). My plan was the following workflow -
>>>
>>> - Request is received and processed by the controller. Controller
>>> returns an object <T> or List<T> (Page, Category, etc). For any list
>>> resource it gets all entities, and allows the pagination filter to
>>> subset.
>>> - JsonWrapperResponseFilter process the request and wraps the data
>>> object in the wrapper object
>>> - PaginationResponseFilter checks if the data object is a list. It
>>> retrieves the values of limit and offset QS parameters or sets them to
>>> defaults. It then subsets the data and sets appropriate meta fields in
>>> the json object.
>>>
>>> The issue is that the response handler does not give me access (as far
>>> as I can tell) to the query string values. Which makes me think I'm
>>> missing something, or that this is the wrong way to approach the
>>> problem.  Any help or input is appreciated.
>>>
>>>
>>> [1] https://reviews.apache.org/r/12901/
>>>
>>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
>>> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
>>> >
>>> >
>>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
>>> > <er...@gmail.com>wrote:
>>> >
>>> >> Slight update on this journey of discovery - it looks like what we
>>> >> actually want to use is not interceptors, but jaxrs filters. See:
>>> >> http://cxf.apache.org/docs/jax-rs-filters.html
>>> >>
>>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com>
>>> >> wrote:
>>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>>> >> erin.noe.payne@gmail.com>wrote:
>>> >> >
>>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
>>> >> >> wrote:
>>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>>> >> >> erin.noe.payne@gmail.com>wrote:
>>> >> >> >
>>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
>>> chris@cxtsoftware.com>
>>> >> >> >> wrote:
>>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>>> >> >> >> > <er...@gmail.com>wrote:
>>> >> >> >> >
>>> >> >> >> >> - Simple solution: All rest response models are flat. We ignore
>>> >> any
>>> >> >> >> >> nested data, and just have separate endpoints to deliver that
>>> >> data.
>>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package has
>>> >> only
>>> >> >> >> >> properties of "primitive" types, with no lists, no other
>>> classes.
>>> >> >> That
>>> >> >> >> >> is NOT currently the case. Then the fields interceptor checks
>>> for
>>> >> the
>>> >> >> >> >> presence of a fields argument. If not present, the object is
>>> >> >> delivered
>>> >> >> >> >> as is. If present the argument (a string) is split by comma and
>>> >> only
>>> >> >> >> >> the matched properties are delivered. The fields qs argument
>>> only
>>> >> has
>>> >> >> >> >> to support comma-delimited list of property names.
>>> >> >> >> >> Ex: ?fields=name,pageType
>>> >> >> >> >> //returns a page or pages with only name and pageType
>>> properties
>>> >> >> >> >>
>>> >> >> >> >
>>> >> >> >> > I like the simple solution. I think the CRUD part of the API
>>> should
>>> >> >> be as
>>> >> >> >> > flat as possible like Erin suggested and we have "special" end
>>> >> points
>>> >> >> to
>>> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
>>> >> >> >> >
>>> >> >> >>
>>> >> >> >> Just to make sure we are on the same page, my proposal is that in
>>> >> both
>>> >> >> >> cases a get request without any special query string will return
>>> only
>>> >> >> >> flat data. The difference is that in the second case the fields
>>> query
>>> >> >> >> parameter will support a syntax that CAN deliver nested data in a
>>> >> >> >> single request.
>>> >> >> >>
>>> >> >> >
>>> >> >> > That confuses me. I thought the whole point of the "special" end
>>> point
>>> >> >> was
>>> >> >> > to handle things like page rendering in one query which would
>>> require
>>> >> >> > hierarchical data every time. Why force the use of query string
>>> >> params to
>>> >> >> > get that?
>>> >> >> >
>>> >> >>
>>> >> >> I was speaking in reference to the standard endpoints. The
>>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
>>> specific
>>> >> >> client need for a complex nested data set. It will always return
>>> >> >> hierarchical data, will probably not support field selection at all.
>>> >> >>
>>> >> >> The standard endpoints will by default return flat data. They will
>>> >> >> support field selection. If we choose to implement the more complex
>>> >> >> field selection, then they will allow you to request nested data
>>> >> >> through the field selection syntax.
>>> >> >>
>>> >> >
>>> >> > ok
>>> >> >
>>> >> >>
>>> >> >> >>
>>> >> >> >> >>
>>> >> >> >> >> - Complicated solution: All rest response models include
>>> >> references
>>> >> >> to
>>> >> >> >> >> their nested data. This is the currently the case, and can be
>>> >> seen in
>>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks
>>> for
>>> >> >> >> >> presence of fields qs argument. If not present it strips all
>>> >> nested
>>> >> >> >> >> data from the models and only returns properties. If it is
>>> >> present,
>>> >> >> it
>>> >> >> >> >> parses the argument and updates the data. The fields argument
>>> >> needs
>>> >> >> to
>>> >> >> >> >> support a more complicated syntax that allows the requesting of
>>> >> >> nested
>>> >> >> >> >> data. I would copy the syntax of facebook's graph search api,
>>> >> which
>>> >> >> >> >> has a pretty readable solution. You allow for .fields and
>>> .limit
>>> >> on
>>> >> >> >> >> fields, which can be nested.
>>> >> >> >> >> Ex:
>>> >> >> >> >>
>>> >> >> >>
>>> >> >>
>>> >>
>>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>>> >> >> >> >> //returns a page or pages with name and pageType properties,
>>> >> nested
>>> >> >> >> >> list of regions (max of 2) with nested list of regionWidgets
>>> with
>>> >> >> only
>>> >> >> >> >> properties of widgetId and locked
>>> >> >> >> >>
>>> >> >> >> >> In all cases, id should always be returned.
>>> >> >> >> >> I think the algorithm in the simple solution is easy.
>>> >> >> >> >> In a sense the algorithm in the second should be simple,
>>> because
>>> >> the
>>> >> >> >> >> service layer is already getting all the nested data, and you
>>> are
>>> >> >> just
>>> >> >> >> >> stripping it off. Not sure what the performance implications of
>>> >> that
>>> >> >> >> >> are though.
>>> >> >> >> >>
>>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>>> >> chris@cxtsoftware.com>
>>> >> >> >> wrote:
>>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>>> >> >> >> >> > <er...@gmail.com>wrote:
>>> >> >> >> >> >
>>> >> >> >> >> >> Going back to the discussion on field selection - I am
>>> >> currently
>>> >> >> >> going
>>> >> >> >> >> >> through the exercise of writing out the Resource interfaces
>>> to
>>> >> >> define
>>> >> >> >> >> >> our endpoints.  There is a set of generic query string
>>> >> parameters
>>> >> >> >> that
>>> >> >> >> >> >> we wish to support on all or many of the endpoints - fields
>>> >> (any
>>> >> >> get
>>> >> >> >> >> >> request), limit / offset (any get request that returns a
>>> list).
>>> >> >> >> >> >>
>>> >> >> >> >> >> Rather than writing each endpoint to accept QueryParam()'s
>>> and
>>> >> >> repeat
>>> >> >> >> >> >> the appropriate logic, I assume we would want to take
>>> >> advantage of
>>> >> >> >> cxf
>>> >> >> >> >> >> interceptors [1] to intelligently and generically handle
>>> those
>>> >> qs
>>> >> >> >> >> >> arguments?
>>> >> >> >> >> >>
>>> >> >> >> >> >
>>> >> >> >> >> > I like the concept but I'm not sure how we generically
>>> filter,
>>> >> >> >> especially
>>> >> >> >> >> > with nested data. I'd love to see it work that way though.
>>> >> >> >> Interceptors
>>> >> >> >> >> are
>>> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
>>> figured
>>> >> out
>>> >> >> >> yet.
>>> >> >> >> >> > Thoughts?
>>> >> >> >> >> >
>>> >> >> >> >> >>
>>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>>> >> >> >> >> >>
>>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>> >> >> >> >> >> <er...@gmail.com> wrote:
>>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
>>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the best
>>> >> way
>>> >> >> to
>>> >> >> >> get
>>> >> >> >> >> >> > wrapped responses?
>>> >> >> >> >> >> >
>>> >> >> >> >> >> > For the next step I would like to start writing out all of
>>> >> the
>>> >> >> >> >> >> > resource interfaces so that we can begin writing angular
>>> >> >> $resource
>>> >> >> >> >> >> > services against them.
>>> >> >> >> >> >> >
>>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>> >> >> >> >> >> > <er...@gmail.com> wrote:
>>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured
>>> >> that
>>> >> >> one
>>> >> >> >> >> >> out...
>>> >> >> >> >> >> >>
>>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>>> >> >> >> chris@cxtsoftware.com>
>>> >> >> >> >> >> wrote:
>>> >> >> >> >> >> >>> Erin,
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple things:
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
>>> methods
>>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove
>>> the
>>> >> >> >> @ParamPath
>>> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
>>> puts
>>> >> >> those
>>> >> >> >> in
>>> >> >> >> >> >> there
>>> >> >> >> >> >> >>> but they cause problems. Only the interface should be
>>> >> >> annotated.
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>> Chris
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >> >> >> >> >> >>>
>>> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
>>> >> accepting
>>> >> >> the
>>> >> >> >> >> valid
>>> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to the
>>> >> >> review.
>>> >> >> >> >> >> >>>>
>>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>>> >> >> >> chris@cxtsoftware.com
>>> >> >> >> >> >
>>> >> >> >> >> >> wrote:
>>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>>> >> >> >> >> >> >>>> >
>>> >> >> >> >> >> >>>> >
>>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>>> >> >> >> >> >> >>>> >
>>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as expected.
>>> I've
>>> >> >> posted
>>> >> >> >> >> the
>>> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a look
>>> and
>>> >> >> offer
>>> >> >> >> >> >> advice -
>>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>>> >> >> >> >> >> >>>> >>
>>> >> >> >> >> >> >>>> >> Thanks
>>> >> >> >> >> >> >>>> >>
>>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>>> >> >> >> >> chris@cxtsoftware.com
>>> >> >> >> >> >> >
>>> >> >> >> >> >> >>>> wrote:
>>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>> >> >> >> >> >> >>>> >> >
>>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>> >> >> >> >> >> chris@cxtsoftware.com
>>> >> >> >> >> >> >>>> >> <javascript:;>>
>>> >> >> >> >> >> >>>> >> >> wrote:
>>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the bean,
>>> then
>>> >> >> >> reference
>>> >> >> >> >> >> it in
>>> >> >> >> >> >> >>>> the
>>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
>>> that...no,
>>> >> >> that
>>> >> >> >> >> >> should be
>>> >> >> >> >> >> >>>> >> all. I
>>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
>>> resource.
>>> >> >> >> >> >> >>>> >> >> >
>>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the service
>>> >> >> injection,
>>> >> >> >> >> >> which may
>>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
>>> though.
>>> >> >> >> >> >> >>>> >> >>
>>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
>>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
>>> widget
>>> >> >> >> outside a
>>> >> >> >> >> >> region
>>> >> >> >> >> >> >>>> >> >> outside
>>> >> >> >> >> >> >>>> >> >> > a page?
>>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
>>> proof
>>> >> of
>>> >> >> >> concept
>>> >> >> >> >> >> with
>>> >> >> >> >> >> >>>> the
>>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something simple
>>> >> with
>>> >> >> the
>>> >> >> >> >> >> service and
>>> >> >> >> >> >> >>>> >> >> rest models already in place.
>>> >> >> >> >> >> >>>> >> >>
>>> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
>>> dealing
>>> >> with
>>> >> >> >> >> region
>>> >> >> >> >> >> >>>> widgets
>>> >> >> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...)
>>> over
>>> >> >> just
>>> >> >> >> >> >> dealing
>>> >> >> >> >> >> >>>> with
>>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
>>> pages
>>> >> >> >> >> controller,
>>> >> >> >> >> >> >>>> rather
>>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with resource
>>> >> >> concerns
>>> >> >> >> >> >> separately.
>>> >> >> >> >> >> >>>> >> >>
>>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
>>> >> >> regionwidgets
>>> >> >> >> only
>>> >> >> >> >> >> making
>>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you could say
>>> >> the
>>> >> >> same
>>> >> >> >> >> >> thing for
>>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
>>> >> >> always
>>> >> >> >> >> >> uniquely
>>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
>>> individually?
>>> >> I
>>> >> >> see
>>> >> >> >> an
>>> >> >> >> >> >> upside
>>> >> >> >> >> >> >>>> of
>>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
>>> see no
>>> >> >> >> >> downside.
>>> >> >> >> >> >> >>>> >> >
>>> >> >> >> >> >> >>>> >> >
>>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
>>> >> uniquely
>>> >> >> >> >> >> identified and
>>> >> >> >> >> >> >>>> are
>>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
>>> >> >> longer
>>> >> >> >> >> >> >>>> conversation.
>>> >> >> >> >> >> >>>> >> >
>>> >> >> >> >> >> >>>> >> >>
>>> >> >> >> >> >> >>>> >> >> >
>>> >> >> >> >> >> >>>> >> >> >
>>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
>>> Noe-Payne
>>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>>> >> >> >> >> >> >>>> >> >> >
>>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>>> >> >> >> regionWidgets.
>>> >> >> >> >> I've
>>> >> >> >> >> >> >>>> added
>>> >> >> >> >> >> >>>> >> >> >> the interface and default implementation, and
>>> >> >> created /
>>> >> >> >> >> >> registered
>>> >> >> >> >> >> >>>> >> the
>>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>>> >> >> >> >> >> >>>> >> >> >>
>>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
>>> error:
>>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
>>> >> operation
>>> >> >> >> >> matching
>>> >> >> >> >> >> >>>> request
>>> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
>>> found,
>>> >> >> >> Relative
>>> >> >> >> >> >> Path:
>>> >> >> >> >> >> >>>> /1,
>>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>>> >> >> >> >> >> >>>> >> >> >>
>>> >> >> >> >> >>
>>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more
>>> >> details.
>>> >> >> >> >> >> >>>> >> >> >>
>>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in order
>>> to
>>> >> >> create
>>> >> >> >> and
>>> >> >> >> >> >> >>>> register a
>>> >> >> >> >> >> >>>> >> >> >> new endpoint?
>>> >> >> >> >> >> >>>> >> >> >>
>>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
>>> Noe-Payne
>>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
>>> Geer <
>>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>>> >> >> >> >> >> >>>> >> >> >> wrote:
>>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
>>> >> Noe-Payne <
>>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >> >> >> >> >> >>>> >> >> >> >>
>>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
>>> >> Franklin <
>>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris
>>> >> Geer <
>>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
>>> >> >> Noe-Payne
>>> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would
>>> >> like
>>> >> >> to
>>> >> >> >> >> start
>>> >> >> >> >> >> >>>> >> implementing
>>> >> >> >> >> >> >>>> >> >> >> more
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
>>> foundational
>>> >> for
>>> >> >> >> the
>>> >> >> >> >> >> entire
>>> >> >> >> >> >> >>>> >> angular
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that
>>> the
>>> >> >> current
>>> >> >> >> >> apis
>>> >> >> >> >> >> in
>>> >> >> >> >> >> >>>> trunk
>>> >> >> >> >> >> >>>> >> >> are
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are
>>> not
>>> >> >> tested
>>> >> >> >> and
>>> >> >> >> >> >> much of
>>> >> >> >> >> >> >>>> >> the
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are
>>> any
>>> >> of
>>> >> >> the
>>> >> >> >> >> rest
>>> >> >> >> >> >> api
>>> >> >> >> >> >> >>>> >> >> >> implementations
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
>>> >> example? Is
>>> >> >> >> there
>>> >> >> >> >> >> other
>>> >> >> >> >> >> >>>> >> >> >> documentation
>>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
>>> resource
>>> >> as a
>>> >> >> >> >> >> "reference"
>>> >> >> >> >> >> >>>> of
>>> >> >> >> >> >> >>>> >> how
>>> >> >> >> >> >> >>>> >> >> I'd
>>> >> >> >> >> >> >>>> >> >> >> >>> like
>>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work
>>> in
>>> >> >> >> >> progress. I
>>> >> >> >> >> >> need
>>> >> >> >> >> >> >>>> to
>>> >> >> >> >> >> >>>> >> go
>>> >> >> >> >> >> >>>> >> >> >> back
>>> >> >> >> >> >> >>>> >> >> >> >>> and
>>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>>> >> reimplement
>>> >> >> the
>>> >> >> >> >> >> "fields"
>>> >> >> >> >> >> >>>> >> concept.
>>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
>>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
>>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as
>>> >> flat
>>> >> >> as
>>> >> >> >> >> >> possible
>>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
>>> >> >> nested
>>> >> >> >> >> >> resources to
>>> >> >> >> >> >> >>>> >> get
>>> >> >> >> >> >> >>>> >> >> >> nested
>>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>>> >> >> >> >> >> >>>> regions/1/regionwidgets,
>>> >> >> >> >> >> >>>> >> >> the
>>> >> >> >> >> >> >>>> >> >> >> >>> regions
>>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain an
>>> >> array of
>>> >> >> >> >> >> >>>> regionwidgets)
>>> >> >> >> >> >> >>>> >> >> >> >>> >>
>>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
>>> >> >> support
>>> >> >> >> this
>>> >> >> >> >> >> when
>>> >> >> >> >> >> >>>> >> >> rendering
>>> >> >> >> >> >> >>>> >> >> >> the
>>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
>>> sufficient
>>> >> >> >> number of
>>> >> >> >> >> >> >>>> gadgets,
>>> >> >> >> >> >> >>>> >> >> adding
>>> >> >> >> >> >> >>>> >> >> >> to
>>> >> >> >> >> >> >>>> >> >> >> >>> the
>>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>>> >> >> >> >> >> >>>> >> >> >> >>> >
>>> >> >> >> >> >> >>>> >> >> >> >>>
>>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard"
>>> >> rest
>>> >> >> >> >> >> endpoints for
>>> >> >> >> >> >> >>>> >> crud
>>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>>> >> >> >> >> >> >>>> >>
>>> >> >> >> >> >> >>>>
>>> >> >> >> >> >>
>>> >> >> >> >>
>>> >> >> >>
>>> >> >>
>>> >>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Wed, Jul 24, 2013 at 1:37 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> What about this:
>
> http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders
>

This is referring to a RequestHandler, not a ResponseHandler. In the
request handler the Message object does have correct request uri data,
etc, but I don't have access to the Response object yet.

> The only thing I don't like about not returning Response objects is it
> doesn't let the method set HTTP specific stuff. Which just means we need
> really really good filters. For example, a create should set the Location
> HTTP header field with the proper URL to the newly created object.
>

That's fair. And the controllers could return response objects and
following filters could just iteratively return
Response.fromResponse(). But if we take a step back from filters or
interceptors or whatever implementation approach, here's the problem
I'm trying to solve:

Taking your Location header example - all requests to get or create an
entity should have the location header set to the canonical url of the
resource. Post requests creating a new resource should have a location
header pointing to the newly created resource. That is universally
true, and I should be able to write that code generically. I do not
want to have to set the location header in every controller for every
resource that handles the @POST method. That seems like it should be
doable, and filters or interceptors seemed like the way to do it. Now
I'm not so sure.

So is that a goal worth pursuing, and if yes what is the right approach?

>
> On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> Ok, I'm having trouble setting up filters that are able to access
>> query string parameters to do pagination. I've submitted a review
>> request [1] with my work so far (look at pages, categories, and the
>> filters). My plan was the following workflow -
>>
>> - Request is received and processed by the controller. Controller
>> returns an object <T> or List<T> (Page, Category, etc). For any list
>> resource it gets all entities, and allows the pagination filter to
>> subset.
>> - JsonWrapperResponseFilter process the request and wraps the data
>> object in the wrapper object
>> - PaginationResponseFilter checks if the data object is a list. It
>> retrieves the values of limit and offset QS parameters or sets them to
>> defaults. It then subsets the data and sets appropriate meta fields in
>> the json object.
>>
>> The issue is that the response handler does not give me access (as far
>> as I can tell) to the query string values. Which makes me think I'm
>> missing something, or that this is the wrong way to approach the
>> problem.  Any help or input is appreciated.
>>
>>
>> [1] https://reviews.apache.org/r/12901/
>>
>> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
>> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
>> >
>> >
>> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
>> > <er...@gmail.com>wrote:
>> >
>> >> Slight update on this journey of discovery - it looks like what we
>> >> actually want to use is not interceptors, but jaxrs filters. See:
>> >> http://cxf.apache.org/docs/jax-rs-filters.html
>> >>
>> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>> >> erin.noe.payne@gmail.com>wrote:
>> >> >
>> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> >> wrote:
>> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >
>> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >> >> >> wrote:
>> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> >> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >
>> >> >> >> >> - Simple solution: All rest response models are flat. We ignore
>> >> any
>> >> >> >> >> nested data, and just have separate endpoints to deliver that
>> >> data.
>> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package has
>> >> only
>> >> >> >> >> properties of "primitive" types, with no lists, no other
>> classes.
>> >> >> That
>> >> >> >> >> is NOT currently the case. Then the fields interceptor checks
>> for
>> >> the
>> >> >> >> >> presence of a fields argument. If not present, the object is
>> >> >> delivered
>> >> >> >> >> as is. If present the argument (a string) is split by comma and
>> >> only
>> >> >> >> >> the matched properties are delivered. The fields qs argument
>> only
>> >> has
>> >> >> >> >> to support comma-delimited list of property names.
>> >> >> >> >> Ex: ?fields=name,pageType
>> >> >> >> >> //returns a page or pages with only name and pageType
>> properties
>> >> >> >> >>
>> >> >> >> >
>> >> >> >> > I like the simple solution. I think the CRUD part of the API
>> should
>> >> >> be as
>> >> >> >> > flat as possible like Erin suggested and we have "special" end
>> >> points
>> >> >> to
>> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
>> >> >> >> >
>> >> >> >>
>> >> >> >> Just to make sure we are on the same page, my proposal is that in
>> >> both
>> >> >> >> cases a get request without any special query string will return
>> only
>> >> >> >> flat data. The difference is that in the second case the fields
>> query
>> >> >> >> parameter will support a syntax that CAN deliver nested data in a
>> >> >> >> single request.
>> >> >> >>
>> >> >> >
>> >> >> > That confuses me. I thought the whole point of the "special" end
>> point
>> >> >> was
>> >> >> > to handle things like page rendering in one query which would
>> require
>> >> >> > hierarchical data every time. Why force the use of query string
>> >> params to
>> >> >> > get that?
>> >> >> >
>> >> >>
>> >> >> I was speaking in reference to the standard endpoints. The
>> >> >> page(s)ForRender endpoint is a special endpoint that serves a
>> specific
>> >> >> client need for a complex nested data set. It will always return
>> >> >> hierarchical data, will probably not support field selection at all.
>> >> >>
>> >> >> The standard endpoints will by default return flat data. They will
>> >> >> support field selection. If we choose to implement the more complex
>> >> >> field selection, then they will allow you to request nested data
>> >> >> through the field selection syntax.
>> >> >>
>> >> >
>> >> > ok
>> >> >
>> >> >>
>> >> >> >>
>> >> >> >> >>
>> >> >> >> >> - Complicated solution: All rest response models include
>> >> references
>> >> >> to
>> >> >> >> >> their nested data. This is the currently the case, and can be
>> >> seen in
>> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks
>> for
>> >> >> >> >> presence of fields qs argument. If not present it strips all
>> >> nested
>> >> >> >> >> data from the models and only returns properties. If it is
>> >> present,
>> >> >> it
>> >> >> >> >> parses the argument and updates the data. The fields argument
>> >> needs
>> >> >> to
>> >> >> >> >> support a more complicated syntax that allows the requesting of
>> >> >> nested
>> >> >> >> >> data. I would copy the syntax of facebook's graph search api,
>> >> which
>> >> >> >> >> has a pretty readable solution. You allow for .fields and
>> .limit
>> >> on
>> >> >> >> >> fields, which can be nested.
>> >> >> >> >> Ex:
>> >> >> >> >>
>> >> >> >>
>> >> >>
>> >>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >> >> >> >> //returns a page or pages with name and pageType properties,
>> >> nested
>> >> >> >> >> list of regions (max of 2) with nested list of regionWidgets
>> with
>> >> >> only
>> >> >> >> >> properties of widgetId and locked
>> >> >> >> >>
>> >> >> >> >> In all cases, id should always be returned.
>> >> >> >> >> I think the algorithm in the simple solution is easy.
>> >> >> >> >> In a sense the algorithm in the second should be simple,
>> because
>> >> the
>> >> >> >> >> service layer is already getting all the nested data, and you
>> are
>> >> >> just
>> >> >> >> >> stripping it off. Not sure what the performance implications of
>> >> that
>> >> >> >> >> are though.
>> >> >> >> >>
>> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>> >> chris@cxtsoftware.com>
>> >> >> >> wrote:
>> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >> >> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >> >
>> >> >> >> >> >> Going back to the discussion on field selection - I am
>> >> currently
>> >> >> >> going
>> >> >> >> >> >> through the exercise of writing out the Resource interfaces
>> to
>> >> >> define
>> >> >> >> >> >> our endpoints.  There is a set of generic query string
>> >> parameters
>> >> >> >> that
>> >> >> >> >> >> we wish to support on all or many of the endpoints - fields
>> >> (any
>> >> >> get
>> >> >> >> >> >> request), limit / offset (any get request that returns a
>> list).
>> >> >> >> >> >>
>> >> >> >> >> >> Rather than writing each endpoint to accept QueryParam()'s
>> and
>> >> >> repeat
>> >> >> >> >> >> the appropriate logic, I assume we would want to take
>> >> advantage of
>> >> >> >> cxf
>> >> >> >> >> >> interceptors [1] to intelligently and generically handle
>> those
>> >> qs
>> >> >> >> >> >> arguments?
>> >> >> >> >> >>
>> >> >> >> >> >
>> >> >> >> >> > I like the concept but I'm not sure how we generically
>> filter,
>> >> >> >> especially
>> >> >> >> >> > with nested data. I'd love to see it work that way though.
>> >> >> >> Interceptors
>> >> >> >> >> are
>> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
>> figured
>> >> out
>> >> >> >> yet.
>> >> >> >> >> > Thoughts?
>> >> >> >> >> >
>> >> >> >> >> >>
>> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >> >> >> >> >>
>> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >> >> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
>> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the best
>> >> way
>> >> >> to
>> >> >> >> get
>> >> >> >> >> >> > wrapped responses?
>> >> >> >> >> >> >
>> >> >> >> >> >> > For the next step I would like to start writing out all of
>> >> the
>> >> >> >> >> >> > resource interfaces so that we can begin writing angular
>> >> >> $resource
>> >> >> >> >> >> > services against them.
>> >> >> >> >> >> >
>> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >> >> >> >> >> > <er...@gmail.com> wrote:
>> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured
>> >> that
>> >> >> one
>> >> >> >> >> >> out...
>> >> >> >> >> >> >>
>> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> >> >> >> chris@cxtsoftware.com>
>> >> >> >> >> >> wrote:
>> >> >> >> >> >> >>> Erin,
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple things:
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
>> methods
>> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove
>> the
>> >> >> >> @ParamPath
>> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
>> puts
>> >> >> those
>> >> >> >> in
>> >> >> >> >> >> there
>> >> >> >> >> >> >>> but they cause problems. Only the interface should be
>> >> >> annotated.
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>> Chris
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >> >>>
>> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
>> >> accepting
>> >> >> the
>> >> >> >> >> valid
>> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to the
>> >> >> review.
>> >> >> >> >> >> >>>>
>> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> >> >> >> chris@cxtsoftware.com
>> >> >> >> >> >
>> >> >> >> >> >> wrote:
>> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >> >> >> >> >> >>>> >
>> >> >> >> >> >> >>>> >
>> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >> >>>> >
>> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as expected.
>> I've
>> >> >> posted
>> >> >> >> >> the
>> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a look
>> and
>> >> >> offer
>> >> >> >> >> >> advice -
>> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >> >> >> >> >> >>>> >>
>> >> >> >> >> >> >>>> >> Thanks
>> >> >> >> >> >> >>>> >>
>> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> >> >> >> >> chris@cxtsoftware.com
>> >> >> >> >> >> >
>> >> >> >> >> >> >>>> wrote:
>> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >> >> >> >> >>>> >> >
>> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >> >> >> >> >> chris@cxtsoftware.com
>> >> >> >> >> >> >>>> >> <javascript:;>>
>> >> >> >> >> >> >>>> >> >> wrote:
>> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the bean,
>> then
>> >> >> >> reference
>> >> >> >> >> >> it in
>> >> >> >> >> >> >>>> the
>> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
>> that...no,
>> >> >> that
>> >> >> >> >> >> should be
>> >> >> >> >> >> >>>> >> all. I
>> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
>> resource.
>> >> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the service
>> >> >> injection,
>> >> >> >> >> >> which may
>> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
>> though.
>> >> >> >> >> >> >>>> >> >>
>> >> >> >> >> >> >>>> >> >> > I thought we were going to do
>> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
>> widget
>> >> >> >> outside a
>> >> >> >> >> >> region
>> >> >> >> >> >> >>>> >> >> outside
>> >> >> >> >> >> >>>> >> >> > a page?
>> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
>> proof
>> >> of
>> >> >> >> concept
>> >> >> >> >> >> with
>> >> >> >> >> >> >>>> the
>> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something simple
>> >> with
>> >> >> the
>> >> >> >> >> >> service and
>> >> >> >> >> >> >>>> >> >> rest models already in place.
>> >> >> >> >> >> >>>> >> >>
>> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
>> dealing
>> >> with
>> >> >> >> >> region
>> >> >> >> >> >> >>>> widgets
>> >> >> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...)
>> over
>> >> >> just
>> >> >> >> >> >> dealing
>> >> >> >> >> >> >>>> with
>> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
>> pages
>> >> >> >> >> controller,
>> >> >> >> >> >> >>>> rather
>> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with resource
>> >> >> concerns
>> >> >> >> >> >> separately.
>> >> >> >> >> >> >>>> >> >>
>> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
>> >> >> regionwidgets
>> >> >> >> only
>> >> >> >> >> >> making
>> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you could say
>> >> the
>> >> >> same
>> >> >> >> >> >> thing for
>> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
>> >> >> always
>> >> >> >> >> >> uniquely
>> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
>> individually?
>> >> I
>> >> >> see
>> >> >> >> an
>> >> >> >> >> >> upside
>> >> >> >> >> >> >>>> of
>> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
>> see no
>> >> >> >> >> downside.
>> >> >> >> >> >> >>>> >> >
>> >> >> >> >> >> >>>> >> >
>> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
>> >> uniquely
>> >> >> >> >> >> identified and
>> >> >> >> >> >> >>>> are
>> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
>> >> >> longer
>> >> >> >> >> >> >>>> conversation.
>> >> >> >> >> >> >>>> >> >
>> >> >> >> >> >> >>>> >> >>
>> >> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
>> Noe-Payne
>> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>> >> >> >> regionWidgets.
>> >> >> >> >> I've
>> >> >> >> >> >> >>>> added
>> >> >> >> >> >> >>>> >> >> >> the interface and default implementation, and
>> >> >> created /
>> >> >> >> >> >> registered
>> >> >> >> >> >> >>>> >> the
>> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
>> error:
>> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
>> >> operation
>> >> >> >> >> matching
>> >> >> >> >> >> >>>> request
>> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
>> found,
>> >> >> >> Relative
>> >> >> >> >> >> Path:
>> >> >> >> >> >> >>>> /1,
>> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >>
>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more
>> >> details.
>> >> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in order
>> to
>> >> >> create
>> >> >> >> and
>> >> >> >> >> >> >>>> register a
>> >> >> >> >> >> >>>> >> >> >> new endpoint?
>> >> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
>> Noe-Payne
>> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
>> Geer <
>> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>> >> >> >> >> >> >>>> >> >> >> wrote:
>> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
>> >> Noe-Payne <
>> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >> >>>> >> >> >> >>
>> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
>> >> Franklin <
>> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris
>> >> Geer <
>> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
>> >> >> Noe-Payne
>> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would
>> >> like
>> >> >> to
>> >> >> >> >> start
>> >> >> >> >> >> >>>> >> implementing
>> >> >> >> >> >> >>>> >> >> >> more
>> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
>> foundational
>> >> for
>> >> >> >> the
>> >> >> >> >> >> entire
>> >> >> >> >> >> >>>> >> angular
>> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that
>> the
>> >> >> current
>> >> >> >> >> apis
>> >> >> >> >> >> in
>> >> >> >> >> >> >>>> trunk
>> >> >> >> >> >> >>>> >> >> are
>> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are
>> not
>> >> >> tested
>> >> >> >> and
>> >> >> >> >> >> much of
>> >> >> >> >> >> >>>> >> the
>> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are
>> any
>> >> of
>> >> >> the
>> >> >> >> >> rest
>> >> >> >> >> >> api
>> >> >> >> >> >> >>>> >> >> >> implementations
>> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
>> >> example? Is
>> >> >> >> there
>> >> >> >> >> >> other
>> >> >> >> >> >> >>>> >> >> >> documentation
>> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >> >> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
>> resource
>> >> as a
>> >> >> >> >> >> "reference"
>> >> >> >> >> >> >>>> of
>> >> >> >> >> >> >>>> >> how
>> >> >> >> >> >> >>>> >> >> I'd
>> >> >> >> >> >> >>>> >> >> >> >>> like
>> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work
>> in
>> >> >> >> >> progress. I
>> >> >> >> >> >> need
>> >> >> >> >> >> >>>> to
>> >> >> >> >> >> >>>> >> go
>> >> >> >> >> >> >>>> >> >> >> back
>> >> >> >> >> >> >>>> >> >> >> >>> and
>> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>> >> reimplement
>> >> >> the
>> >> >> >> >> >> "fields"
>> >> >> >> >> >> >>>> >> concept.
>> >> >> >> >> >> >>>> >> >> >> >>> Couple of
>> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as
>> >> flat
>> >> >> as
>> >> >> >> >> >> possible
>> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
>> >> >> nested
>> >> >> >> >> >> resources to
>> >> >> >> >> >> >>>> >> get
>> >> >> >> >> >> >>>> >> >> >> nested
>> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >> >> >> >> >> >>>> regions/1/regionwidgets,
>> >> >> >> >> >> >>>> >> >> the
>> >> >> >> >> >> >>>> >> >> >> >>> regions
>> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain an
>> >> array of
>> >> >> >> >> >> >>>> regionwidgets)
>> >> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
>> >> >> support
>> >> >> >> this
>> >> >> >> >> >> when
>> >> >> >> >> >> >>>> >> >> rendering
>> >> >> >> >> >> >>>> >> >> >> the
>> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
>> sufficient
>> >> >> >> number of
>> >> >> >> >> >> >>>> gadgets,
>> >> >> >> >> >> >>>> >> >> adding
>> >> >> >> >> >> >>>> >> >> >> to
>> >> >> >> >> >> >>>> >> >> >> >>> the
>> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >> >>>> >> >> >> >>>
>> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard"
>> >> rest
>> >> >> >> >> >> endpoints for
>> >> >> >> >> >> >>>> >> crud
>> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>> >> >> >> >> >> >>>> >>
>> >> >> >> >> >> >>>>
>> >> >> >> >> >>
>> >> >> >> >>
>> >> >> >>
>> >> >>
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
What about this:

http://cxf.apache.org/docs/jax-rs-filters.html#JAX-RSFilters-OverridingrequestURI%2Cqueryandheaders

The only thing I don't like about not returning Response objects is it
doesn't let the method set HTTP specific stuff. Which just means we need
really really good filters. For example, a create should set the Location
HTTP header field with the proper URL to the newly created object.


On Wed, Jul 24, 2013 at 9:21 AM, Erin Noe-Payne <er...@gmail.com>wrote:

> Ok, I'm having trouble setting up filters that are able to access
> query string parameters to do pagination. I've submitted a review
> request [1] with my work so far (look at pages, categories, and the
> filters). My plan was the following workflow -
>
> - Request is received and processed by the controller. Controller
> returns an object <T> or List<T> (Page, Category, etc). For any list
> resource it gets all entities, and allows the pagination filter to
> subset.
> - JsonWrapperResponseFilter process the request and wraps the data
> object in the wrapper object
> - PaginationResponseFilter checks if the data object is a list. It
> retrieves the values of limit and offset QS parameters or sets them to
> defaults. It then subsets the data and sets appropriate meta fields in
> the json object.
>
> The issue is that the response handler does not give me access (as far
> as I can tell) to the query string values. Which makes me think I'm
> missing something, or that this is the wrong way to approach the
> problem.  Any help or input is appreciated.
>
>
> [1] https://reviews.apache.org/r/12901/
>
> On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> > Good point...I forgot Rave is using CXF 2.7.x which includes that new
> > stuff. That would be a better choice, plus it wouldn't tie us to CXF.
> >
> >
> > On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
> > <er...@gmail.com>wrote:
> >
> >> Slight update on this journey of discovery - it looks like what we
> >> actually want to use is not interceptors, but jaxrs filters. See:
> >> http://cxf.apache.org/docs/jax-rs-filters.html
> >>
> >> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
> >> erin.noe.payne@gmail.com>wrote:
> >> >
> >> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
> >> >> wrote:
> >> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >
> >> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <
> chris@cxtsoftware.com>
> >> >> >> wrote:
> >> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> >> >> >> > <er...@gmail.com>wrote:
> >> >> >> >
> >> >> >> >> - Simple solution: All rest response models are flat. We ignore
> >> any
> >> >> >> >> nested data, and just have separate endpoints to deliver that
> >> data.
> >> >> >> >> I.E. Every model in the org.apache.rave.rest.model package has
> >> only
> >> >> >> >> properties of "primitive" types, with no lists, no other
> classes.
> >> >> That
> >> >> >> >> is NOT currently the case. Then the fields interceptor checks
> for
> >> the
> >> >> >> >> presence of a fields argument. If not present, the object is
> >> >> delivered
> >> >> >> >> as is. If present the argument (a string) is split by comma and
> >> only
> >> >> >> >> the matched properties are delivered. The fields qs argument
> only
> >> has
> >> >> >> >> to support comma-delimited list of property names.
> >> >> >> >> Ex: ?fields=name,pageType
> >> >> >> >> //returns a page or pages with only name and pageType
> properties
> >> >> >> >>
> >> >> >> >
> >> >> >> > I like the simple solution. I think the CRUD part of the API
> should
> >> >> be as
> >> >> >> > flat as possible like Erin suggested and we have "special" end
> >> points
> >> >> to
> >> >> >> > get back hierarchical data when needed, i.e. page rendering.
> >> >> >> >
> >> >> >>
> >> >> >> Just to make sure we are on the same page, my proposal is that in
> >> both
> >> >> >> cases a get request without any special query string will return
> only
> >> >> >> flat data. The difference is that in the second case the fields
> query
> >> >> >> parameter will support a syntax that CAN deliver nested data in a
> >> >> >> single request.
> >> >> >>
> >> >> >
> >> >> > That confuses me. I thought the whole point of the "special" end
> point
> >> >> was
> >> >> > to handle things like page rendering in one query which would
> require
> >> >> > hierarchical data every time. Why force the use of query string
> >> params to
> >> >> > get that?
> >> >> >
> >> >>
> >> >> I was speaking in reference to the standard endpoints. The
> >> >> page(s)ForRender endpoint is a special endpoint that serves a
> specific
> >> >> client need for a complex nested data set. It will always return
> >> >> hierarchical data, will probably not support field selection at all.
> >> >>
> >> >> The standard endpoints will by default return flat data. They will
> >> >> support field selection. If we choose to implement the more complex
> >> >> field selection, then they will allow you to request nested data
> >> >> through the field selection syntax.
> >> >>
> >> >
> >> > ok
> >> >
> >> >>
> >> >> >>
> >> >> >> >>
> >> >> >> >> - Complicated solution: All rest response models include
> >> references
> >> >> to
> >> >> >> >> their nested data. This is the currently the case, and can be
> >> seen in
> >> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks
> for
> >> >> >> >> presence of fields qs argument. If not present it strips all
> >> nested
> >> >> >> >> data from the models and only returns properties. If it is
> >> present,
> >> >> it
> >> >> >> >> parses the argument and updates the data. The fields argument
> >> needs
> >> >> to
> >> >> >> >> support a more complicated syntax that allows the requesting of
> >> >> nested
> >> >> >> >> data. I would copy the syntax of facebook's graph search api,
> >> which
> >> >> >> >> has a pretty readable solution. You allow for .fields and
> .limit
> >> on
> >> >> >> >> fields, which can be nested.
> >> >> >> >> Ex:
> >> >> >> >>
> >> >> >>
> >> >>
> >>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >> >> >> >> //returns a page or pages with name and pageType properties,
> >> nested
> >> >> >> >> list of regions (max of 2) with nested list of regionWidgets
> with
> >> >> only
> >> >> >> >> properties of widgetId and locked
> >> >> >> >>
> >> >> >> >> In all cases, id should always be returned.
> >> >> >> >> I think the algorithm in the simple solution is easy.
> >> >> >> >> In a sense the algorithm in the second should be simple,
> because
> >> the
> >> >> >> >> service layer is already getting all the nested data, and you
> are
> >> >> just
> >> >> >> >> stripping it off. Not sure what the performance implications of
> >> that
> >> >> >> >> are though.
> >> >> >> >>
> >> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
> >> chris@cxtsoftware.com>
> >> >> >> wrote:
> >> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >> >> >> >> > <er...@gmail.com>wrote:
> >> >> >> >> >
> >> >> >> >> >> Going back to the discussion on field selection - I am
> >> currently
> >> >> >> going
> >> >> >> >> >> through the exercise of writing out the Resource interfaces
> to
> >> >> define
> >> >> >> >> >> our endpoints.  There is a set of generic query string
> >> parameters
> >> >> >> that
> >> >> >> >> >> we wish to support on all or many of the endpoints - fields
> >> (any
> >> >> get
> >> >> >> >> >> request), limit / offset (any get request that returns a
> list).
> >> >> >> >> >>
> >> >> >> >> >> Rather than writing each endpoint to accept QueryParam()'s
> and
> >> >> repeat
> >> >> >> >> >> the appropriate logic, I assume we would want to take
> >> advantage of
> >> >> >> cxf
> >> >> >> >> >> interceptors [1] to intelligently and generically handle
> those
> >> qs
> >> >> >> >> >> arguments?
> >> >> >> >> >>
> >> >> >> >> >
> >> >> >> >> > I like the concept but I'm not sure how we generically
> filter,
> >> >> >> especially
> >> >> >> >> > with nested data. I'd love to see it work that way though.
> >> >> >> Interceptors
> >> >> >> >> are
> >> >> >> >> > pretty easy to use, it's the filter algorithm I haven't
> figured
> >> out
> >> >> >> yet.
> >> >> >> >> > Thoughts?
> >> >> >> >> >
> >> >> >> >> >>
> >> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >> >> >> >> >>
> >> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >> >> >> >> >> <er...@gmail.com> wrote:
> >> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
> >> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the best
> >> way
> >> >> to
> >> >> >> get
> >> >> >> >> >> > wrapped responses?
> >> >> >> >> >> >
> >> >> >> >> >> > For the next step I would like to start writing out all of
> >> the
> >> >> >> >> >> > resource interfaces so that we can begin writing angular
> >> >> $resource
> >> >> >> >> >> > services against them.
> >> >> >> >> >> >
> >> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >> >> >> >> >> > <er...@gmail.com> wrote:
> >> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured
> >> that
> >> >> one
> >> >> >> >> >> out...
> >> >> >> >> >> >>
> >> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> >> >> >> chris@cxtsoftware.com>
> >> >> >> >> >> wrote:
> >> >> >> >> >> >>> Erin,
> >> >> >> >> >> >>>
> >> >> >> >> >> >>> I got it working, at least the CXF part. Couple things:
> >> >> >> >> >> >>>
> >> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET
> methods
> >> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove
> the
> >> >> >> @ParamPath
> >> >> >> >> >> >>> attributes from variable signatures. I know Intellij
> puts
> >> >> those
> >> >> >> in
> >> >> >> >> >> there
> >> >> >> >> >> >>> but they cause problems. Only the interface should be
> >> >> annotated.
> >> >> >> >> >> >>>
> >> >> >> >> >> >>> Chris
> >> >> >> >> >> >>>
> >> >> >> >> >> >>>
> >> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >> >> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >> >>>
> >> >> >> >> >> >>>> Review board is not accepting my patch and is not
> >> accepting
> >> >> the
> >> >> >> >> valid
> >> >> >> >> >> >>>> file paths. I have attached the patch as a file to the
> >> >> review.
> >> >> >> >> >> >>>>
> >> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> >> >> >> chris@cxtsoftware.com
> >> >> >> >> >
> >> >> >> >> >> wrote:
> >> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >> >> >> >> >> >>>> >
> >> >> >> >> >> >>>> >
> >> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >> >>>> >
> >> >> >> >> >> >>>> >> I was never able to hit the endpoint as expected.
> I've
> >> >> posted
> >> >> >> >> the
> >> >> >> >> >> >>>> >> patch on the review board if anyone can take a look
> and
> >> >> offer
> >> >> >> >> >> advice -
> >> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >> >> >> >> >> >>>> >>
> >> >> >> >> >> >>>> >> Thanks
> >> >> >> >> >> >>>> >>
> >> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> >> >> >> >> chris@cxtsoftware.com
> >> >> >> >> >> >
> >> >> >> >> >> >>>> wrote:
> >> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >> >> >> >> >>>> >> >
> >> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >> >> >> >> >> chris@cxtsoftware.com
> >> >> >> >> >> >>>> >> <javascript:;>>
> >> >> >> >> >> >>>> >> >> wrote:
> >> >> >> >> >> >>>> >> >> > In the xml file you need to create the bean,
> then
> >> >> >> reference
> >> >> >> >> >> it in
> >> >> >> >> >> >>>> the
> >> >> >> >> >> >>>> >> >> > server element near the top. Other than
> that...no,
> >> >> that
> >> >> >> >> >> should be
> >> >> >> >> >> >>>> >> all. I
> >> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the
> resource.
> >> >> >> >> >> >>>> >> >> >
> >> >> >> >> >> >>>> >> >> I did. I'm also messing around with the service
> >> >> injection,
> >> >> >> >> >> which may
> >> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet
> though.
> >> >> >> >> >> >>>> >> >>
> >> >> >> >> >> >>>> >> >> > I thought we were going to do
> >> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region
> widget
> >> >> >> outside a
> >> >> >> >> >> region
> >> >> >> >> >> >>>> >> >> outside
> >> >> >> >> >> >>>> >> >> > a page?
> >> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a
> proof
> >> of
> >> >> >> concept
> >> >> >> >> >> with
> >> >> >> >> >> >>>> the
> >> >> >> >> >> >>>> >> >> wrapped json object so I picked something simple
> >> with
> >> >> the
> >> >> >> >> >> service and
> >> >> >> >> >> >>>> >> >> rest models already in place.
> >> >> >> >> >> >>>> >> >>
> >> >> >> >> >> >>>> >> >> In general though I don't see any value to
> dealing
> >> with
> >> >> >> >> region
> >> >> >> >> >> >>>> widgets
> >> >> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...)
> over
> >> >> just
> >> >> >> >> >> dealing
> >> >> >> >> >> >>>> with
> >> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the
> pages
> >> >> >> >> controller,
> >> >> >> >> >> >>>> rather
> >> >> >> >> >> >>>> >> >> than breaking them up and dealing with resource
> >> >> concerns
> >> >> >> >> >> separately.
> >> >> >> >> >> >>>> >> >>
> >> >> >> >> >> >>>> >> >> I get what you're saying about regions and
> >> >> regionwidgets
> >> >> >> only
> >> >> >> >> >> making
> >> >> >> >> >> >>>> >> >> sense in the context of a page, but you could say
> >> the
> >> >> same
> >> >> >> >> >> thing for
> >> >> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
> >> >> always
> >> >> >> >> >> uniquely
> >> >> >> >> >> >>>> >> >> identified, so why not deal with them
> individually?
> >> I
> >> >> see
> >> >> >> an
> >> >> >> >> >> upside
> >> >> >> >> >> >>>> of
> >> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I
> see no
> >> >> >> >> downside.
> >> >> >> >> >> >>>> >> >
> >> >> >> >> >> >>>> >> >
> >> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
> >> uniquely
> >> >> >> >> >> identified and
> >> >> >> >> >> >>>> are
> >> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
> >> >> longer
> >> >> >> >> >> >>>> conversation.
> >> >> >> >> >> >>>> >> >
> >> >> >> >> >> >>>> >> >>
> >> >> >> >> >> >>>> >> >> >
> >> >> >> >> >> >>>> >> >> >
> >> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin
> Noe-Payne
> >> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >> >> >> >> >> >>>> >> >> >
> >> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
> >> >> >> regionWidgets.
> >> >> >> >> I've
> >> >> >> >> >> >>>> added
> >> >> >> >> >> >>>> >> >> >> the interface and default implementation, and
> >> >> created /
> >> >> >> >> >> registered
> >> >> >> >> >> >>>> >> the
> >> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an
> error:
> >> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
> >> operation
> >> >> >> >> matching
> >> >> >> >> >> >>>> request
> >> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is
> found,
> >> >> >> Relative
> >> >> >> >> >> Path:
> >> >> >> >> >> >>>> /1,
> >> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >>
> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more
> >> details.
> >> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in order
> to
> >> >> create
> >> >> >> and
> >> >> >> >> >> >>>> register a
> >> >> >> >> >> >>>> >> >> >> new endpoint?
> >> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin
> Noe-Payne
> >> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris
> Geer <
> >> >> >> >> >> >>>> >> chris@cxtsoftware.com>
> >> >> >> >> >> >>>> >> >> >> wrote:
> >> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
> >> Noe-Payne <
> >> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >> >>>> >> >> >> >>
> >> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
> >> Franklin <
> >> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris
> >> Geer <
> >> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
> >> >> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
> >> >> Noe-Payne
> >> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would
> >> like
> >> >> to
> >> >> >> >> start
> >> >> >> >> >> >>>> >> implementing
> >> >> >> >> >> >>>> >> >> >> more
> >> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is
> foundational
> >> for
> >> >> >> the
> >> >> >> >> >> entire
> >> >> >> >> >> >>>> >> angular
> >> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that
> the
> >> >> current
> >> >> >> >> apis
> >> >> >> >> >> in
> >> >> >> >> >> >>>> trunk
> >> >> >> >> >> >>>> >> >> are
> >> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are
> not
> >> >> tested
> >> >> >> and
> >> >> >> >> >> much of
> >> >> >> >> >> >>>> >> the
> >> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are
> any
> >> of
> >> >> the
> >> >> >> >> rest
> >> >> >> >> >> api
> >> >> >> >> >> >>>> >> >> >> implementations
> >> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
> >> example? Is
> >> >> >> there
> >> >> >> >> >> other
> >> >> >> >> >> >>>> >> >> >> documentation
> >> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
> >> >> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People
> resource
> >> as a
> >> >> >> >> >> "reference"
> >> >> >> >> >> >>>> of
> >> >> >> >> >> >>>> >> how
> >> >> >> >> >> >>>> >> >> I'd
> >> >> >> >> >> >>>> >> >> >> >>> like
> >> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work
> in
> >> >> >> >> progress. I
> >> >> >> >> >> need
> >> >> >> >> >> >>>> to
> >> >> >> >> >> >>>> >> go
> >> >> >> >> >> >>>> >> >> >> back
> >> >> >> >> >> >>>> >> >> >> >>> and
> >> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
> >> reimplement
> >> >> the
> >> >> >> >> >> "fields"
> >> >> >> >> >> >>>> >> concept.
> >> >> >> >> >> >>>> >> >> >> >>> Couple of
> >> >> >> >> >> >>>> >> >> >> >>> >> notes:
> >> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as
> >> flat
> >> >> as
> >> >> >> >> >> possible
> >> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
> >> >> nested
> >> >> >> >> >> resources to
> >> >> >> >> >> >>>> >> get
> >> >> >> >> >> >>>> >> >> >> nested
> >> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >> >> >> >> >> >>>> regions/1/regionwidgets,
> >> >> >> >> >> >>>> >> >> the
> >> >> >> >> >> >>>> >> >> >> >>> regions
> >> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain an
> >> array of
> >> >> >> >> >> >>>> regionwidgets)
> >> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
> >> >> support
> >> >> >> this
> >> >> >> >> >> when
> >> >> >> >> >> >>>> >> >> rendering
> >> >> >> >> >> >>>> >> >> >> the
> >> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a
> sufficient
> >> >> >> number of
> >> >> >> >> >> >>>> gadgets,
> >> >> >> >> >> >>>> >> >> adding
> >> >> >> >> >> >>>> >> >> >> to
> >> >> >> >> >> >>>> >> >> >> >>> the
> >> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
> >> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >> >>>> >> >> >> >>>
> >> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard"
> >> rest
> >> >> >> >> >> endpoints for
> >> >> >> >> >> >>>> >> crud
> >> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
> >> >> >> >> >> >>>> >>
> >> >> >> >> >> >>>>
> >> >> >> >> >>
> >> >> >> >>
> >> >> >>
> >> >>
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Ok, I'm having trouble setting up filters that are able to access
query string parameters to do pagination. I've submitted a review
request [1] with my work so far (look at pages, categories, and the
filters). My plan was the following workflow -

- Request is received and processed by the controller. Controller
returns an object <T> or List<T> (Page, Category, etc). For any list
resource it gets all entities, and allows the pagination filter to
subset.
- JsonWrapperResponseFilter process the request and wraps the data
object in the wrapper object
- PaginationResponseFilter checks if the data object is a list. It
retrieves the values of limit and offset QS parameters or sets them to
defaults. It then subsets the data and sets appropriate meta fields in
the json object.

The issue is that the response handler does not give me access (as far
as I can tell) to the query string values. Which makes me think I'm
missing something, or that this is the wrong way to approach the
problem.  Any help or input is appreciated.


[1] https://reviews.apache.org/r/12901/

On Tue, Jul 23, 2013 at 3:08 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> Good point...I forgot Rave is using CXF 2.7.x which includes that new
> stuff. That would be a better choice, plus it wouldn't tie us to CXF.
>
>
> On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> Slight update on this journey of discovery - it looks like what we
>> actually want to use is not interceptors, but jaxrs filters. See:
>> http://cxf.apache.org/docs/jax-rs-filters.html
>>
>> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >
>> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>> >> erin.noe.payne@gmail.com>wrote:
>> >> >
>> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> >> wrote:
>> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> >> >> > <er...@gmail.com>wrote:
>> >> >> >
>> >> >> >> - Simple solution: All rest response models are flat. We ignore
>> any
>> >> >> >> nested data, and just have separate endpoints to deliver that
>> data.
>> >> >> >> I.E. Every model in the org.apache.rave.rest.model package has
>> only
>> >> >> >> properties of "primitive" types, with no lists, no other classes.
>> >> That
>> >> >> >> is NOT currently the case. Then the fields interceptor checks for
>> the
>> >> >> >> presence of a fields argument. If not present, the object is
>> >> delivered
>> >> >> >> as is. If present the argument (a string) is split by comma and
>> only
>> >> >> >> the matched properties are delivered. The fields qs argument only
>> has
>> >> >> >> to support comma-delimited list of property names.
>> >> >> >> Ex: ?fields=name,pageType
>> >> >> >> //returns a page or pages with only name and pageType properties
>> >> >> >>
>> >> >> >
>> >> >> > I like the simple solution. I think the CRUD part of the API should
>> >> be as
>> >> >> > flat as possible like Erin suggested and we have "special" end
>> points
>> >> to
>> >> >> > get back hierarchical data when needed, i.e. page rendering.
>> >> >> >
>> >> >>
>> >> >> Just to make sure we are on the same page, my proposal is that in
>> both
>> >> >> cases a get request without any special query string will return only
>> >> >> flat data. The difference is that in the second case the fields query
>> >> >> parameter will support a syntax that CAN deliver nested data in a
>> >> >> single request.
>> >> >>
>> >> >
>> >> > That confuses me. I thought the whole point of the "special" end point
>> >> was
>> >> > to handle things like page rendering in one query which would require
>> >> > hierarchical data every time. Why force the use of query string
>> params to
>> >> > get that?
>> >> >
>> >>
>> >> I was speaking in reference to the standard endpoints. The
>> >> page(s)ForRender endpoint is a special endpoint that serves a specific
>> >> client need for a complex nested data set. It will always return
>> >> hierarchical data, will probably not support field selection at all.
>> >>
>> >> The standard endpoints will by default return flat data. They will
>> >> support field selection. If we choose to implement the more complex
>> >> field selection, then they will allow you to request nested data
>> >> through the field selection syntax.
>> >>
>> >
>> > ok
>> >
>> >>
>> >> >>
>> >> >> >>
>> >> >> >> - Complicated solution: All rest response models include
>> references
>> >> to
>> >> >> >> their nested data. This is the currently the case, and can be
>> seen in
>> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
>> >> >> >> presence of fields qs argument. If not present it strips all
>> nested
>> >> >> >> data from the models and only returns properties. If it is
>> present,
>> >> it
>> >> >> >> parses the argument and updates the data. The fields argument
>> needs
>> >> to
>> >> >> >> support a more complicated syntax that allows the requesting of
>> >> nested
>> >> >> >> data. I would copy the syntax of facebook's graph search api,
>> which
>> >> >> >> has a pretty readable solution. You allow for .fields and .limit
>> on
>> >> >> >> fields, which can be nested.
>> >> >> >> Ex:
>> >> >> >>
>> >> >>
>> >>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >> >> >> //returns a page or pages with name and pageType properties,
>> nested
>> >> >> >> list of regions (max of 2) with nested list of regionWidgets with
>> >> only
>> >> >> >> properties of widgetId and locked
>> >> >> >>
>> >> >> >> In all cases, id should always be returned.
>> >> >> >> I think the algorithm in the simple solution is easy.
>> >> >> >> In a sense the algorithm in the second should be simple, because
>> the
>> >> >> >> service layer is already getting all the nested data, and you are
>> >> just
>> >> >> >> stripping it off. Not sure what the performance implications of
>> that
>> >> >> >> are though.
>> >> >> >>
>> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >> >> wrote:
>> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >
>> >> >> >> >> Going back to the discussion on field selection - I am
>> currently
>> >> >> going
>> >> >> >> >> through the exercise of writing out the Resource interfaces to
>> >> define
>> >> >> >> >> our endpoints.  There is a set of generic query string
>> parameters
>> >> >> that
>> >> >> >> >> we wish to support on all or many of the endpoints - fields
>> (any
>> >> get
>> >> >> >> >> request), limit / offset (any get request that returns a list).
>> >> >> >> >>
>> >> >> >> >> Rather than writing each endpoint to accept QueryParam()'s and
>> >> repeat
>> >> >> >> >> the appropriate logic, I assume we would want to take
>> advantage of
>> >> >> cxf
>> >> >> >> >> interceptors [1] to intelligently and generically handle those
>> qs
>> >> >> >> >> arguments?
>> >> >> >> >>
>> >> >> >> >
>> >> >> >> > I like the concept but I'm not sure how we generically filter,
>> >> >> especially
>> >> >> >> > with nested data. I'd love to see it work that way though.
>> >> >> Interceptors
>> >> >> >> are
>> >> >> >> > pretty easy to use, it's the filter algorithm I haven't figured
>> out
>> >> >> yet.
>> >> >> >> > Thoughts?
>> >> >> >> >
>> >> >> >> >>
>> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >> >> >> >>
>> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
>> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the best
>> way
>> >> to
>> >> >> get
>> >> >> >> >> > wrapped responses?
>> >> >> >> >> >
>> >> >> >> >> > For the next step I would like to start writing out all of
>> the
>> >> >> >> >> > resource interfaces so that we can begin writing angular
>> >> $resource
>> >> >> >> >> > services against them.
>> >> >> >> >> >
>> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >> >> >> >> > <er...@gmail.com> wrote:
>> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured
>> that
>> >> one
>> >> >> >> >> out...
>> >> >> >> >> >>
>> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> >> >> chris@cxtsoftware.com>
>> >> >> >> >> wrote:
>> >> >> >> >> >>> Erin,
>> >> >> >> >> >>>
>> >> >> >> >> >>> I got it working, at least the CXF part. Couple things:
>> >> >> >> >> >>>
>> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
>> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
>> >> >> @ParamPath
>> >> >> >> >> >>> attributes from variable signatures. I know Intellij puts
>> >> those
>> >> >> in
>> >> >> >> >> there
>> >> >> >> >> >>> but they cause problems. Only the interface should be
>> >> annotated.
>> >> >> >> >> >>>
>> >> >> >> >> >>> Chris
>> >> >> >> >> >>>
>> >> >> >> >> >>>
>> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >>>
>> >> >> >> >> >>>> Review board is not accepting my patch and is not
>> accepting
>> >> the
>> >> >> >> valid
>> >> >> >> >> >>>> file paths. I have attached the patch as a file to the
>> >> review.
>> >> >> >> >> >>>>
>> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> >> >> chris@cxtsoftware.com
>> >> >> >> >
>> >> >> >> >> wrote:
>> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >> >> >> >> >>>> >
>> >> >> >> >> >>>> >
>> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >>>> >
>> >> >> >> >> >>>> >> I was never able to hit the endpoint as expected. I've
>> >> posted
>> >> >> >> the
>> >> >> >> >> >>>> >> patch on the review board if anyone can take a look and
>> >> offer
>> >> >> >> >> advice -
>> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >> >> >> >> >>>> >>
>> >> >> >> >> >>>> >> Thanks
>> >> >> >> >> >>>> >>
>> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> >> >> >> chris@cxtsoftware.com
>> >> >> >> >> >
>> >> >> >> >> >>>> wrote:
>> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >> >> >> >>>> >> >
>> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >> >> >> >> chris@cxtsoftware.com
>> >> >> >> >> >>>> >> <javascript:;>>
>> >> >> >> >> >>>> >> >> wrote:
>> >> >> >> >> >>>> >> >> > In the xml file you need to create the bean, then
>> >> >> reference
>> >> >> >> >> it in
>> >> >> >> >> >>>> the
>> >> >> >> >> >>>> >> >> > server element near the top. Other than that...no,
>> >> that
>> >> >> >> >> should be
>> >> >> >> >> >>>> >> all. I
>> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
>> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >>>> >> >> I did. I'm also messing around with the service
>> >> injection,
>> >> >> >> >> which may
>> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >> >> >> >> >>>> >> >>
>> >> >> >> >> >>>> >> >> > I thought we were going to do
>> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region widget
>> >> >> outside a
>> >> >> >> >> region
>> >> >> >> >> >>>> >> >> outside
>> >> >> >> >> >>>> >> >> > a page?
>> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof
>> of
>> >> >> concept
>> >> >> >> >> with
>> >> >> >> >> >>>> the
>> >> >> >> >> >>>> >> >> wrapped json object so I picked something simple
>> with
>> >> the
>> >> >> >> >> service and
>> >> >> >> >> >>>> >> >> rest models already in place.
>> >> >> >> >> >>>> >> >>
>> >> >> >> >> >>>> >> >> In general though I don't see any value to dealing
>> with
>> >> >> >> region
>> >> >> >> >> >>>> widgets
>> >> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over
>> >> just
>> >> >> >> >> dealing
>> >> >> >> >> >>>> with
>> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the pages
>> >> >> >> controller,
>> >> >> >> >> >>>> rather
>> >> >> >> >> >>>> >> >> than breaking them up and dealing with resource
>> >> concerns
>> >> >> >> >> separately.
>> >> >> >> >> >>>> >> >>
>> >> >> >> >> >>>> >> >> I get what you're saying about regions and
>> >> regionwidgets
>> >> >> only
>> >> >> >> >> making
>> >> >> >> >> >>>> >> >> sense in the context of a page, but you could say
>> the
>> >> same
>> >> >> >> >> thing for
>> >> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
>> >> always
>> >> >> >> >> uniquely
>> >> >> >> >> >>>> >> >> identified, so why not deal with them individually?
>> I
>> >> see
>> >> >> an
>> >> >> >> >> upside
>> >> >> >> >> >>>> of
>> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
>> >> >> >> downside.
>> >> >> >> >> >>>> >> >
>> >> >> >> >> >>>> >> >
>> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
>> uniquely
>> >> >> >> >> identified and
>> >> >> >> >> >>>> are
>> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
>> >> longer
>> >> >> >> >> >>>> conversation.
>> >> >> >> >> >>>> >> >
>> >> >> >> >> >>>> >> >>
>> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >> >>>> >> >> >
>> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>> >> >> regionWidgets.
>> >> >> >> I've
>> >> >> >> >> >>>> added
>> >> >> >> >> >>>> >> >> >> the interface and default implementation, and
>> >> created /
>> >> >> >> >> registered
>> >> >> >> >> >>>> >> the
>> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
>> operation
>> >> >> >> matching
>> >> >> >> >> >>>> request
>> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
>> >> >> Relative
>> >> >> >> >> Path:
>> >> >> >> >> >>>> /1,
>> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> >> >> >>>> >> >> >>
>> >> >> >> >>
>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more
>> details.
>> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in order to
>> >> create
>> >> >> and
>> >> >> >> >> >>>> register a
>> >> >> >> >> >>>> >> >> >> new endpoint?
>> >> >> >> >> >>>> >> >> >>
>> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >> >> >> >> >>>> >> chris@cxtsoftware.com>
>> >> >> >> >> >>>> >> >> >> wrote:
>> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
>> Noe-Payne <
>> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >> >>>> >> >> >> >>
>> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
>> Franklin <
>> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris
>> Geer <
>> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
>> >> Noe-Payne
>> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would
>> like
>> >> to
>> >> >> >> start
>> >> >> >> >> >>>> >> implementing
>> >> >> >> >> >>>> >> >> >> more
>> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational
>> for
>> >> >> the
>> >> >> >> >> entire
>> >> >> >> >> >>>> >> angular
>> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
>> >> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the
>> >> current
>> >> >> >> apis
>> >> >> >> >> in
>> >> >> >> >> >>>> trunk
>> >> >> >> >> >>>> >> >> are
>> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not
>> >> tested
>> >> >> and
>> >> >> >> >> much of
>> >> >> >> >> >>>> >> the
>> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any
>> of
>> >> the
>> >> >> >> rest
>> >> >> >> >> api
>> >> >> >> >> >>>> >> >> >> implementations
>> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
>> example? Is
>> >> >> there
>> >> >> >> >> other
>> >> >> >> >> >>>> >> >> >> documentation
>> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People resource
>> as a
>> >> >> >> >> "reference"
>> >> >> >> >> >>>> of
>> >> >> >> >> >>>> >> how
>> >> >> >> >> >>>> >> >> I'd
>> >> >> >> >> >>>> >> >> >> >>> like
>> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
>> >> >> >> progress. I
>> >> >> >> >> need
>> >> >> >> >> >>>> to
>> >> >> >> >> >>>> >> go
>> >> >> >> >> >>>> >> >> >> back
>> >> >> >> >> >>>> >> >> >> >>> and
>> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
>> reimplement
>> >> the
>> >> >> >> >> "fields"
>> >> >> >> >> >>>> >> concept.
>> >> >> >> >> >>>> >> >> >> >>> Couple of
>> >> >> >> >> >>>> >> >> >> >>> >> notes:
>> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as
>> flat
>> >> as
>> >> >> >> >> possible
>> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
>> >> nested
>> >> >> >> >> resources to
>> >> >> >> >> >>>> >> get
>> >> >> >> >> >>>> >> >> >> nested
>> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >> >> >> >> >>>> regions/1/regionwidgets,
>> >> >> >> >> >>>> >> >> the
>> >> >> >> >> >>>> >> >> >> >>> regions
>> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain an
>> array of
>> >> >> >> >> >>>> regionwidgets)
>> >> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
>> >> support
>> >> >> this
>> >> >> >> >> when
>> >> >> >> >> >>>> >> >> rendering
>> >> >> >> >> >>>> >> >> >> the
>> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
>> >> >> number of
>> >> >> >> >> >>>> gadgets,
>> >> >> >> >> >>>> >> >> adding
>> >> >> >> >> >>>> >> >> >> to
>> >> >> >> >> >>>> >> >> >> >>> the
>> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >> >>>> >> >> >> >>>
>> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard"
>> rest
>> >> >> >> >> endpoints for
>> >> >> >> >> >>>> >> crud
>> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
>> >> >> >> >> >>>> >>
>> >> >> >> >> >>>>
>> >> >> >> >>
>> >> >> >>
>> >> >>
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
Good point...I forgot Rave is using CXF 2.7.x which includes that new
stuff. That would be a better choice, plus it wouldn't tie us to CXF.


On Tue, Jul 23, 2013 at 11:54 AM, Erin Noe-Payne
<er...@gmail.com>wrote:

> Slight update on this journey of discovery - it looks like what we
> actually want to use is not interceptors, but jaxrs filters. See:
> http://cxf.apache.org/docs/jax-rs-filters.html
>
> On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> > On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >
> >> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
> >> erin.noe.payne@gmail.com>wrote:
> >> >
> >> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
> >> >> wrote:
> >> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> >> >> > <er...@gmail.com>wrote:
> >> >> >
> >> >> >> - Simple solution: All rest response models are flat. We ignore
> any
> >> >> >> nested data, and just have separate endpoints to deliver that
> data.
> >> >> >> I.E. Every model in the org.apache.rave.rest.model package has
> only
> >> >> >> properties of "primitive" types, with no lists, no other classes.
> >> That
> >> >> >> is NOT currently the case. Then the fields interceptor checks for
> the
> >> >> >> presence of a fields argument. If not present, the object is
> >> delivered
> >> >> >> as is. If present the argument (a string) is split by comma and
> only
> >> >> >> the matched properties are delivered. The fields qs argument only
> has
> >> >> >> to support comma-delimited list of property names.
> >> >> >> Ex: ?fields=name,pageType
> >> >> >> //returns a page or pages with only name and pageType properties
> >> >> >>
> >> >> >
> >> >> > I like the simple solution. I think the CRUD part of the API should
> >> be as
> >> >> > flat as possible like Erin suggested and we have "special" end
> points
> >> to
> >> >> > get back hierarchical data when needed, i.e. page rendering.
> >> >> >
> >> >>
> >> >> Just to make sure we are on the same page, my proposal is that in
> both
> >> >> cases a get request without any special query string will return only
> >> >> flat data. The difference is that in the second case the fields query
> >> >> parameter will support a syntax that CAN deliver nested data in a
> >> >> single request.
> >> >>
> >> >
> >> > That confuses me. I thought the whole point of the "special" end point
> >> was
> >> > to handle things like page rendering in one query which would require
> >> > hierarchical data every time. Why force the use of query string
> params to
> >> > get that?
> >> >
> >>
> >> I was speaking in reference to the standard endpoints. The
> >> page(s)ForRender endpoint is a special endpoint that serves a specific
> >> client need for a complex nested data set. It will always return
> >> hierarchical data, will probably not support field selection at all.
> >>
> >> The standard endpoints will by default return flat data. They will
> >> support field selection. If we choose to implement the more complex
> >> field selection, then they will allow you to request nested data
> >> through the field selection syntax.
> >>
> >
> > ok
> >
> >>
> >> >>
> >> >> >>
> >> >> >> - Complicated solution: All rest response models include
> references
> >> to
> >> >> >> their nested data. This is the currently the case, and can be
> seen in
> >> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
> >> >> >> presence of fields qs argument. If not present it strips all
> nested
> >> >> >> data from the models and only returns properties. If it is
> present,
> >> it
> >> >> >> parses the argument and updates the data. The fields argument
> needs
> >> to
> >> >> >> support a more complicated syntax that allows the requesting of
> >> nested
> >> >> >> data. I would copy the syntax of facebook's graph search api,
> which
> >> >> >> has a pretty readable solution. You allow for .fields and .limit
> on
> >> >> >> fields, which can be nested.
> >> >> >> Ex:
> >> >> >>
> >> >>
> >>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >> >> >> //returns a page or pages with name and pageType properties,
> nested
> >> >> >> list of regions (max of 2) with nested list of regionWidgets with
> >> only
> >> >> >> properties of widgetId and locked
> >> >> >>
> >> >> >> In all cases, id should always be returned.
> >> >> >> I think the algorithm in the simple solution is easy.
> >> >> >> In a sense the algorithm in the second should be simple, because
> the
> >> >> >> service layer is already getting all the nested data, and you are
> >> just
> >> >> >> stripping it off. Not sure what the performance implications of
> that
> >> >> >> are though.
> >> >> >>
> >> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <
> chris@cxtsoftware.com>
> >> >> wrote:
> >> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >> >> >> > <er...@gmail.com>wrote:
> >> >> >> >
> >> >> >> >> Going back to the discussion on field selection - I am
> currently
> >> >> going
> >> >> >> >> through the exercise of writing out the Resource interfaces to
> >> define
> >> >> >> >> our endpoints.  There is a set of generic query string
> parameters
> >> >> that
> >> >> >> >> we wish to support on all or many of the endpoints - fields
> (any
> >> get
> >> >> >> >> request), limit / offset (any get request that returns a list).
> >> >> >> >>
> >> >> >> >> Rather than writing each endpoint to accept QueryParam()'s and
> >> repeat
> >> >> >> >> the appropriate logic, I assume we would want to take
> advantage of
> >> >> cxf
> >> >> >> >> interceptors [1] to intelligently and generically handle those
> qs
> >> >> >> >> arguments?
> >> >> >> >>
> >> >> >> >
> >> >> >> > I like the concept but I'm not sure how we generically filter,
> >> >> especially
> >> >> >> > with nested data. I'd love to see it work that way though.
> >> >> Interceptors
> >> >> >> are
> >> >> >> > pretty easy to use, it's the filter algorithm I haven't figured
> out
> >> >> yet.
> >> >> >> > Thoughts?
> >> >> >> >
> >> >> >> >>
> >> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >> >> >> >>
> >> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >> >> >> >> <er...@gmail.com> wrote:
> >> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
> >> >> >> >> > JsonResponseWrapper approach? Does that seem like the best
> way
> >> to
> >> >> get
> >> >> >> >> > wrapped responses?
> >> >> >> >> >
> >> >> >> >> > For the next step I would like to start writing out all of
> the
> >> >> >> >> > resource interfaces so that we can begin writing angular
> >> $resource
> >> >> >> >> > services against them.
> >> >> >> >> >
> >> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >> >> >> >> > <er...@gmail.com> wrote:
> >> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured
> that
> >> one
> >> >> >> >> out...
> >> >> >> >> >>
> >> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> >> >> chris@cxtsoftware.com>
> >> >> >> >> wrote:
> >> >> >> >> >>> Erin,
> >> >> >> >> >>>
> >> >> >> >> >>> I got it working, at least the CXF part. Couple things:
> >> >> >> >> >>>
> >> >> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
> >> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
> >> >> @ParamPath
> >> >> >> >> >>> attributes from variable signatures. I know Intellij puts
> >> those
> >> >> in
> >> >> >> >> there
> >> >> >> >> >>> but they cause problems. Only the interface should be
> >> annotated.
> >> >> >> >> >>>
> >> >> >> >> >>> Chris
> >> >> >> >> >>>
> >> >> >> >> >>>
> >> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >>>
> >> >> >> >> >>>> Review board is not accepting my patch and is not
> accepting
> >> the
> >> >> >> valid
> >> >> >> >> >>>> file paths. I have attached the patch as a file to the
> >> review.
> >> >> >> >> >>>>
> >> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> >> >> chris@cxtsoftware.com
> >> >> >> >
> >> >> >> >> wrote:
> >> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >> >> >> >> >>>> >
> >> >> >> >> >>>> >
> >> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >>>> >
> >> >> >> >> >>>> >> I was never able to hit the endpoint as expected. I've
> >> posted
> >> >> >> the
> >> >> >> >> >>>> >> patch on the review board if anyone can take a look and
> >> offer
> >> >> >> >> advice -
> >> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >> >> >> >> >>>> >>
> >> >> >> >> >>>> >> Thanks
> >> >> >> >> >>>> >>
> >> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> >> >> >> chris@cxtsoftware.com
> >> >> >> >> >
> >> >> >> >> >>>> wrote:
> >> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >> >> >> >>>> >> >
> >> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >> >> >> >> chris@cxtsoftware.com
> >> >> >> >> >>>> >> <javascript:;>>
> >> >> >> >> >>>> >> >> wrote:
> >> >> >> >> >>>> >> >> > In the xml file you need to create the bean, then
> >> >> reference
> >> >> >> >> it in
> >> >> >> >> >>>> the
> >> >> >> >> >>>> >> >> > server element near the top. Other than that...no,
> >> that
> >> >> >> >> should be
> >> >> >> >> >>>> >> all. I
> >> >> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
> >> >> >> >> >>>> >> >> >
> >> >> >> >> >>>> >> >> I did. I'm also messing around with the service
> >> injection,
> >> >> >> >> which may
> >> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >> >> >> >> >>>> >> >>
> >> >> >> >> >>>> >> >> > I thought we were going to do
> >> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >> >> >> >>>> >> >> > since it makes no sense to manage a region widget
> >> >> outside a
> >> >> >> >> region
> >> >> >> >> >>>> >> >> outside
> >> >> >> >> >>>> >> >> > a page?
> >> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof
> of
> >> >> concept
> >> >> >> >> with
> >> >> >> >> >>>> the
> >> >> >> >> >>>> >> >> wrapped json object so I picked something simple
> with
> >> the
> >> >> >> >> service and
> >> >> >> >> >>>> >> >> rest models already in place.
> >> >> >> >> >>>> >> >>
> >> >> >> >> >>>> >> >> In general though I don't see any value to dealing
> with
> >> >> >> region
> >> >> >> >> >>>> widgets
> >> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over
> >> just
> >> >> >> >> dealing
> >> >> >> >> >>>> with
> >> >> >> >> >>>> >> >> them directly. It's just adding weight to the pages
> >> >> >> controller,
> >> >> >> >> >>>> rather
> >> >> >> >> >>>> >> >> than breaking them up and dealing with resource
> >> concerns
> >> >> >> >> separately.
> >> >> >> >> >>>> >> >>
> >> >> >> >> >>>> >> >> I get what you're saying about regions and
> >> regionwidgets
> >> >> only
> >> >> >> >> making
> >> >> >> >> >>>> >> >> sense in the context of a page, but you could say
> the
> >> same
> >> >> >> >> thing for
> >> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
> >> always
> >> >> >> >> uniquely
> >> >> >> >> >>>> >> >> identified, so why not deal with them individually?
> I
> >> see
> >> >> an
> >> >> >> >> upside
> >> >> >> >> >>>> of
> >> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
> >> >> >> downside.
> >> >> >> >> >>>> >> >
> >> >> >> >> >>>> >> >
> >> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't
> uniquely
> >> >> >> >> identified and
> >> >> >> >> >>>> are
> >> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
> >> longer
> >> >> >> >> >>>> conversation.
> >> >> >> >> >>>> >> >
> >> >> >> >> >>>> >> >>
> >> >> >> >> >>>> >> >> >
> >> >> >> >> >>>> >> >> >
> >> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >> >> >> >> >>>> >> >> >
> >> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
> >> >> regionWidgets.
> >> >> >> I've
> >> >> >> >> >>>> added
> >> >> >> >> >>>> >> >> >> the interface and default implementation, and
> >> created /
> >> >> >> >> registered
> >> >> >> >> >>>> >> the
> >> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No
> operation
> >> >> >> matching
> >> >> >> >> >>>> request
> >> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
> >> >> Relative
> >> >> >> >> Path:
> >> >> >> >> >>>> /1,
> >> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> >> >> >>>> >> >> >>
> >> >> >> >>
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more
> details.
> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >>>> >> >> >> Is there anything else I need to do in order to
> >> create
> >> >> and
> >> >> >> >> >>>> register a
> >> >> >> >> >>>> >> >> >> new endpoint?
> >> >> >> >> >>>> >> >> >>
> >> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >> >> >> >> >>>> >> chris@cxtsoftware.com>
> >> >> >> >> >>>> >> >> >> wrote:
> >> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin
> Noe-Payne <
> >> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >> >>>> >> >> >> >>
> >> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt
> Franklin <
> >> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris
> Geer <
> >> >> >> >> >>>> >> >> chris@cxtsoftware.com>
> >> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
> >> Noe-Payne
> >> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would
> like
> >> to
> >> >> >> start
> >> >> >> >> >>>> >> implementing
> >> >> >> >> >>>> >> >> >> more
> >> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational
> for
> >> >> the
> >> >> >> >> entire
> >> >> >> >> >>>> >> angular
> >> >> >> >> >>>> >> >> >> >>> >> > architecture.
> >> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the
> >> current
> >> >> >> apis
> >> >> >> >> in
> >> >> >> >> >>>> trunk
> >> >> >> >> >>>> >> >> are
> >> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not
> >> tested
> >> >> and
> >> >> >> >> much of
> >> >> >> >> >>>> >> the
> >> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any
> of
> >> the
> >> >> >> rest
> >> >> >> >> api
> >> >> >> >> >>>> >> >> >> implementations
> >> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working
> example? Is
> >> >> there
> >> >> >> >> other
> >> >> >> >> >>>> >> >> >> documentation
> >> >> >> >> >>>> >> >> >> >>> >> > we can reference?
> >> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >>>> >> >> >> >>> >> I've been working on the People resource
> as a
> >> >> >> >> "reference"
> >> >> >> >> >>>> of
> >> >> >> >> >>>> >> how
> >> >> >> >> >>>> >> >> I'd
> >> >> >> >> >>>> >> >> >> >>> like
> >> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
> >> >> >> progress. I
> >> >> >> >> need
> >> >> >> >> >>>> to
> >> >> >> >> >>>> >> go
> >> >> >> >> >>>> >> >> >> back
> >> >> >> >> >>>> >> >> >> >>> and
> >> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and
> reimplement
> >> the
> >> >> >> >> "fields"
> >> >> >> >> >>>> >> concept.
> >> >> >> >> >>>> >> >> >> >>> Couple of
> >> >> >> >> >>>> >> >> >> >>> >> notes:
> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as
> flat
> >> as
> >> >> >> >> possible
> >> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
> >> nested
> >> >> >> >> resources to
> >> >> >> >> >>>> >> get
> >> >> >> >> >>>> >> >> >> nested
> >> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >> >> >> >> >>>> regions/1/regionwidgets,
> >> >> >> >> >>>> >> >> the
> >> >> >> >> >>>> >> >> >> >>> regions
> >> >> >> >> >>>> >> >> >> >>> >> representation should not contain an
> array of
> >> >> >> >> >>>> regionwidgets)
> >> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
> >> support
> >> >> this
> >> >> >> >> when
> >> >> >> >> >>>> >> >> rendering
> >> >> >> >> >>>> >> >> >> the
> >> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
> >> >> number of
> >> >> >> >> >>>> gadgets,
> >> >> >> >> >>>> >> >> adding
> >> >> >> >> >>>> >> >> >> to
> >> >> >> >> >>>> >> >> >> >>> the
> >> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
> >> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >> >>>> >> >> >> >>>
> >> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard"
> rest
> >> >> >> >> endpoints for
> >> >> >> >> >>>> >> crud
> >> >> >> >> >>>> >> >> >> >>> operations on resources. We
> >> >> >> >> >>>> >>
> >> >> >> >> >>>>
> >> >> >> >>
> >> >> >>
> >> >>
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Slight update on this journey of discovery - it looks like what we
actually want to use is not interceptors, but jaxrs filters. See:
http://cxf.apache.org/docs/jax-rs-filters.html

On Tue, Jul 23, 2013 at 12:56 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >
>> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> >> > <er...@gmail.com>wrote:
>> >> >
>> >> >> - Simple solution: All rest response models are flat. We ignore any
>> >> >> nested data, and just have separate endpoints to deliver that data.
>> >> >> I.E. Every model in the org.apache.rave.rest.model package has only
>> >> >> properties of "primitive" types, with no lists, no other classes.
>> That
>> >> >> is NOT currently the case. Then the fields interceptor checks for the
>> >> >> presence of a fields argument. If not present, the object is
>> delivered
>> >> >> as is. If present the argument (a string) is split by comma and only
>> >> >> the matched properties are delivered. The fields qs argument only has
>> >> >> to support comma-delimited list of property names.
>> >> >> Ex: ?fields=name,pageType
>> >> >> //returns a page or pages with only name and pageType properties
>> >> >>
>> >> >
>> >> > I like the simple solution. I think the CRUD part of the API should
>> be as
>> >> > flat as possible like Erin suggested and we have "special" end points
>> to
>> >> > get back hierarchical data when needed, i.e. page rendering.
>> >> >
>> >>
>> >> Just to make sure we are on the same page, my proposal is that in both
>> >> cases a get request without any special query string will return only
>> >> flat data. The difference is that in the second case the fields query
>> >> parameter will support a syntax that CAN deliver nested data in a
>> >> single request.
>> >>
>> >
>> > That confuses me. I thought the whole point of the "special" end point
>> was
>> > to handle things like page rendering in one query which would require
>> > hierarchical data every time. Why force the use of query string params to
>> > get that?
>> >
>>
>> I was speaking in reference to the standard endpoints. The
>> page(s)ForRender endpoint is a special endpoint that serves a specific
>> client need for a complex nested data set. It will always return
>> hierarchical data, will probably not support field selection at all.
>>
>> The standard endpoints will by default return flat data. They will
>> support field selection. If we choose to implement the more complex
>> field selection, then they will allow you to request nested data
>> through the field selection syntax.
>>
>
> ok
>
>>
>> >>
>> >> >>
>> >> >> - Complicated solution: All rest response models include references
>> to
>> >> >> their nested data. This is the currently the case, and can be seen in
>> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
>> >> >> presence of fields qs argument. If not present it strips all nested
>> >> >> data from the models and only returns properties. If it is present,
>> it
>> >> >> parses the argument and updates the data. The fields argument needs
>> to
>> >> >> support a more complicated syntax that allows the requesting of
>> nested
>> >> >> data. I would copy the syntax of facebook's graph search api, which
>> >> >> has a pretty readable solution. You allow for .fields and .limit on
>> >> >> fields, which can be nested.
>> >> >> Ex:
>> >> >>
>> >>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >> >> //returns a page or pages with name and pageType properties, nested
>> >> >> list of regions (max of 2) with nested list of regionWidgets with
>> only
>> >> >> properties of widgetId and locked
>> >> >>
>> >> >> In all cases, id should always be returned.
>> >> >> I think the algorithm in the simple solution is easy.
>> >> >> In a sense the algorithm in the second should be simple, because the
>> >> >> service layer is already getting all the nested data, and you are
>> just
>> >> >> stripping it off. Not sure what the performance implications of that
>> >> >> are though.
>> >> >>
>> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >> >> > <er...@gmail.com>wrote:
>> >> >> >
>> >> >> >> Going back to the discussion on field selection - I am currently
>> >> going
>> >> >> >> through the exercise of writing out the Resource interfaces to
>> define
>> >> >> >> our endpoints.  There is a set of generic query string parameters
>> >> that
>> >> >> >> we wish to support on all or many of the endpoints - fields (any
>> get
>> >> >> >> request), limit / offset (any get request that returns a list).
>> >> >> >>
>> >> >> >> Rather than writing each endpoint to accept QueryParam()'s and
>> repeat
>> >> >> >> the appropriate logic, I assume we would want to take advantage of
>> >> cxf
>> >> >> >> interceptors [1] to intelligently and generically handle those qs
>> >> >> >> arguments?
>> >> >> >>
>> >> >> >
>> >> >> > I like the concept but I'm not sure how we generically filter,
>> >> especially
>> >> >> > with nested data. I'd love to see it work that way though.
>> >> Interceptors
>> >> >> are
>> >> >> > pretty easy to use, it's the filter algorithm I haven't figured out
>> >> yet.
>> >> >> > Thoughts?
>> >> >> >
>> >> >> >>
>> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >> >> >>
>> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
>> >> >> >> > JsonResponseWrapper approach? Does that seem like the best way
>> to
>> >> get
>> >> >> >> > wrapped responses?
>> >> >> >> >
>> >> >> >> > For the next step I would like to start writing out all of the
>> >> >> >> > resource interfaces so that we can begin writing angular
>> $resource
>> >> >> >> > services against them.
>> >> >> >> >
>> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >> >> >> > <er...@gmail.com> wrote:
>> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured that
>> one
>> >> >> >> out...
>> >> >> >> >>
>> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> >> chris@cxtsoftware.com>
>> >> >> >> wrote:
>> >> >> >> >>> Erin,
>> >> >> >> >>>
>> >> >> >> >>> I got it working, at least the CXF part. Couple things:
>> >> >> >> >>>
>> >> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
>> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
>> >> @ParamPath
>> >> >> >> >>> attributes from variable signatures. I know Intellij puts
>> those
>> >> in
>> >> >> >> there
>> >> >> >> >>> but they cause problems. Only the interface should be
>> annotated.
>> >> >> >> >>>
>> >> >> >> >>> Chris
>> >> >> >> >>>
>> >> >> >> >>>
>> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >>>
>> >> >> >> >>>> Review board is not accepting my patch and is not accepting
>> the
>> >> >> valid
>> >> >> >> >>>> file paths. I have attached the patch as a file to the
>> review.
>> >> >> >> >>>>
>> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> >> chris@cxtsoftware.com
>> >> >> >
>> >> >> >> wrote:
>> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >> >> >> >>>> >
>> >> >> >> >>>> >
>> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >>>> >
>> >> >> >> >>>> >> I was never able to hit the endpoint as expected. I've
>> posted
>> >> >> the
>> >> >> >> >>>> >> patch on the review board if anyone can take a look and
>> offer
>> >> >> >> advice -
>> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >> >> >> >>>> >>
>> >> >> >> >>>> >> Thanks
>> >> >> >> >>>> >>
>> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> >> >> chris@cxtsoftware.com
>> >> >> >> >
>> >> >> >> >>>> wrote:
>> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >> >> >>>> >> >
>> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >> >> >> chris@cxtsoftware.com
>> >> >> >> >>>> >> <javascript:;>>
>> >> >> >> >>>> >> >> wrote:
>> >> >> >> >>>> >> >> > In the xml file you need to create the bean, then
>> >> reference
>> >> >> >> it in
>> >> >> >> >>>> the
>> >> >> >> >>>> >> >> > server element near the top. Other than that...no,
>> that
>> >> >> >> should be
>> >> >> >> >>>> >> all. I
>> >> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
>> >> >> >> >>>> >> >> >
>> >> >> >> >>>> >> >> I did. I'm also messing around with the service
>> injection,
>> >> >> >> which may
>> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >> >> >> >>>> >> >>
>> >> >> >> >>>> >> >> > I thought we were going to do
>> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >> >> >>>> >> >> > since it makes no sense to manage a region widget
>> >> outside a
>> >> >> >> region
>> >> >> >> >>>> >> >> outside
>> >> >> >> >>>> >> >> > a page?
>> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
>> >> concept
>> >> >> >> with
>> >> >> >> >>>> the
>> >> >> >> >>>> >> >> wrapped json object so I picked something simple with
>> the
>> >> >> >> service and
>> >> >> >> >>>> >> >> rest models already in place.
>> >> >> >> >>>> >> >>
>> >> >> >> >>>> >> >> In general though I don't see any value to dealing with
>> >> >> region
>> >> >> >> >>>> widgets
>> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over
>> just
>> >> >> >> dealing
>> >> >> >> >>>> with
>> >> >> >> >>>> >> >> them directly. It's just adding weight to the pages
>> >> >> controller,
>> >> >> >> >>>> rather
>> >> >> >> >>>> >> >> than breaking them up and dealing with resource
>> concerns
>> >> >> >> separately.
>> >> >> >> >>>> >> >>
>> >> >> >> >>>> >> >> I get what you're saying about regions and
>> regionwidgets
>> >> only
>> >> >> >> making
>> >> >> >> >>>> >> >> sense in the context of a page, but you could say the
>> same
>> >> >> >> thing for
>> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
>> always
>> >> >> >> uniquely
>> >> >> >> >>>> >> >> identified, so why not deal with them individually? I
>> see
>> >> an
>> >> >> >> upside
>> >> >> >> >>>> of
>> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
>> >> >> downside.
>> >> >> >> >>>> >> >
>> >> >> >> >>>> >> >
>> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>> >> >> >> identified and
>> >> >> >> >>>> are
>> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
>> longer
>> >> >> >> >>>> conversation.
>> >> >> >> >>>> >> >
>> >> >> >> >>>> >> >>
>> >> >> >> >>>> >> >> >
>> >> >> >> >>>> >> >> >
>> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >> >> >> >>>> >> >> >
>> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>> >> regionWidgets.
>> >> >> I've
>> >> >> >> >>>> added
>> >> >> >> >>>> >> >> >> the interface and default implementation, and
>> created /
>> >> >> >> registered
>> >> >> >> >>>> >> the
>> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >> >> >>>> >> >> >>
>> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
>> >> >> matching
>> >> >> >> >>>> request
>> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
>> >> Relative
>> >> >> >> Path:
>> >> >> >> >>>> /1,
>> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> >> >>>> >> >> >>
>> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >> >> >> >>>> >> >> >>
>> >> >> >> >>>> >> >> >> Is there anything else I need to do in order to
>> create
>> >> and
>> >> >> >> >>>> register a
>> >> >> >> >>>> >> >> >> new endpoint?
>> >> >> >> >>>> >> >> >>
>> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >> >> >> >>>> >> chris@cxtsoftware.com>
>> >> >> >> >>>> >> >> >> wrote:
>> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >>>> >> >> >> >>
>> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
>> Noe-Payne
>> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like
>> to
>> >> >> start
>> >> >> >> >>>> >> implementing
>> >> >> >> >>>> >> >> >> more
>> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for
>> >> the
>> >> >> >> entire
>> >> >> >> >>>> >> angular
>> >> >> >> >>>> >> >> >> >>> >> > architecture.
>> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the
>> current
>> >> >> apis
>> >> >> >> in
>> >> >> >> >>>> trunk
>> >> >> >> >>>> >> >> are
>> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not
>> tested
>> >> and
>> >> >> >> much of
>> >> >> >> >>>> >> the
>> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of
>> the
>> >> >> rest
>> >> >> >> api
>> >> >> >> >>>> >> >> >> implementations
>> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is
>> >> there
>> >> >> >> other
>> >> >> >> >>>> >> >> >> documentation
>> >> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >> >> >> >>>> >> >> >> >>> >> >
>> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
>> >> >> >> "reference"
>> >> >> >> >>>> of
>> >> >> >> >>>> >> how
>> >> >> >> >>>> >> >> I'd
>> >> >> >> >>>> >> >> >> >>> like
>> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
>> >> >> progress. I
>> >> >> >> need
>> >> >> >> >>>> to
>> >> >> >> >>>> >> go
>> >> >> >> >>>> >> >> >> back
>> >> >> >> >>>> >> >> >> >>> and
>> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement
>> the
>> >> >> >> "fields"
>> >> >> >> >>>> >> concept.
>> >> >> >> >>>> >> >> >> >>> Couple of
>> >> >> >> >>>> >> >> >> >>> >> notes:
>> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as flat
>> as
>> >> >> >> possible
>> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
>> nested
>> >> >> >> resources to
>> >> >> >> >>>> >> get
>> >> >> >> >>>> >> >> >> nested
>> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >> >> >> >>>> regions/1/regionwidgets,
>> >> >> >> >>>> >> >> the
>> >> >> >> >>>> >> >> >> >>> regions
>> >> >> >> >>>> >> >> >> >>> >> representation should not contain an array of
>> >> >> >> >>>> regionwidgets)
>> >> >> >> >>>> >> >> >> >>> >>
>> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
>> support
>> >> this
>> >> >> >> when
>> >> >> >> >>>> >> >> rendering
>> >> >> >> >>>> >> >> >> the
>> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
>> >> number of
>> >> >> >> >>>> gadgets,
>> >> >> >> >>>> >> >> adding
>> >> >> >> >>>> >> >> >> to
>> >> >> >> >>>> >> >> >> >>> the
>> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >> >> >> >>>> >> >> >> >>> >
>> >> >> >> >>>> >> >> >> >>>
>> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>> >> >> >> endpoints for
>> >> >> >> >>>> >> crud
>> >> >> >> >>>> >> >> >> >>> operations on resources. We
>> >> >> >> >>>> >>
>> >> >> >> >>>>
>> >> >> >>
>> >> >>
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Tue, Jul 23, 2013 at 9:55 AM, Erin Noe-Payne <er...@gmail.com>wrote:

> On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> > On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >
> >> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> >> > <er...@gmail.com>wrote:
> >> >
> >> >> - Simple solution: All rest response models are flat. We ignore any
> >> >> nested data, and just have separate endpoints to deliver that data.
> >> >> I.E. Every model in the org.apache.rave.rest.model package has only
> >> >> properties of "primitive" types, with no lists, no other classes.
> That
> >> >> is NOT currently the case. Then the fields interceptor checks for the
> >> >> presence of a fields argument. If not present, the object is
> delivered
> >> >> as is. If present the argument (a string) is split by comma and only
> >> >> the matched properties are delivered. The fields qs argument only has
> >> >> to support comma-delimited list of property names.
> >> >> Ex: ?fields=name,pageType
> >> >> //returns a page or pages with only name and pageType properties
> >> >>
> >> >
> >> > I like the simple solution. I think the CRUD part of the API should
> be as
> >> > flat as possible like Erin suggested and we have "special" end points
> to
> >> > get back hierarchical data when needed, i.e. page rendering.
> >> >
> >>
> >> Just to make sure we are on the same page, my proposal is that in both
> >> cases a get request without any special query string will return only
> >> flat data. The difference is that in the second case the fields query
> >> parameter will support a syntax that CAN deliver nested data in a
> >> single request.
> >>
> >
> > That confuses me. I thought the whole point of the "special" end point
> was
> > to handle things like page rendering in one query which would require
> > hierarchical data every time. Why force the use of query string params to
> > get that?
> >
>
> I was speaking in reference to the standard endpoints. The
> page(s)ForRender endpoint is a special endpoint that serves a specific
> client need for a complex nested data set. It will always return
> hierarchical data, will probably not support field selection at all.
>
> The standard endpoints will by default return flat data. They will
> support field selection. If we choose to implement the more complex
> field selection, then they will allow you to request nested data
> through the field selection syntax.
>

ok

>
> >>
> >> >>
> >> >> - Complicated solution: All rest response models include references
> to
> >> >> their nested data. This is the currently the case, and can be seen in
> >> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
> >> >> presence of fields qs argument. If not present it strips all nested
> >> >> data from the models and only returns properties. If it is present,
> it
> >> >> parses the argument and updates the data. The fields argument needs
> to
> >> >> support a more complicated syntax that allows the requesting of
> nested
> >> >> data. I would copy the syntax of facebook's graph search api, which
> >> >> has a pretty readable solution. You allow for .fields and .limit on
> >> >> fields, which can be nested.
> >> >> Ex:
> >> >>
> >>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >> >> //returns a page or pages with name and pageType properties, nested
> >> >> list of regions (max of 2) with nested list of regionWidgets with
> only
> >> >> properties of widgetId and locked
> >> >>
> >> >> In all cases, id should always be returned.
> >> >> I think the algorithm in the simple solution is easy.
> >> >> In a sense the algorithm in the second should be simple, because the
> >> >> service layer is already getting all the nested data, and you are
> just
> >> >> stripping it off. Not sure what the performance implications of that
> >> >> are though.
> >> >>
> >> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >> >> > <er...@gmail.com>wrote:
> >> >> >
> >> >> >> Going back to the discussion on field selection - I am currently
> >> going
> >> >> >> through the exercise of writing out the Resource interfaces to
> define
> >> >> >> our endpoints.  There is a set of generic query string parameters
> >> that
> >> >> >> we wish to support on all or many of the endpoints - fields (any
> get
> >> >> >> request), limit / offset (any get request that returns a list).
> >> >> >>
> >> >> >> Rather than writing each endpoint to accept QueryParam()'s and
> repeat
> >> >> >> the appropriate logic, I assume we would want to take advantage of
> >> cxf
> >> >> >> interceptors [1] to intelligently and generically handle those qs
> >> >> >> arguments?
> >> >> >>
> >> >> >
> >> >> > I like the concept but I'm not sure how we generically filter,
> >> especially
> >> >> > with nested data. I'd love to see it work that way though.
> >> Interceptors
> >> >> are
> >> >> > pretty easy to use, it's the filter algorithm I haven't figured out
> >> yet.
> >> >> > Thoughts?
> >> >> >
> >> >> >>
> >> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >> >> >>
> >> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >> >> >> <er...@gmail.com> wrote:
> >> >> >> > Ok, so the endpoint is now working. Any thoughts about the
> >> >> >> > JsonResponseWrapper approach? Does that seem like the best way
> to
> >> get
> >> >> >> > wrapped responses?
> >> >> >> >
> >> >> >> > For the next step I would like to start writing out all of the
> >> >> >> > resource interfaces so that we can begin writing angular
> $resource
> >> >> >> > services against them.
> >> >> >> >
> >> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >> >> >> > <er...@gmail.com> wrote:
> >> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured that
> one
> >> >> >> out...
> >> >> >> >>
> >> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> >> chris@cxtsoftware.com>
> >> >> >> wrote:
> >> >> >> >>> Erin,
> >> >> >> >>>
> >> >> >> >>> I got it working, at least the CXF part. Couple things:
> >> >> >> >>>
> >> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
> >> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
> >> @ParamPath
> >> >> >> >>> attributes from variable signatures. I know Intellij puts
> those
> >> in
> >> >> >> there
> >> >> >> >>> but they cause problems. Only the interface should be
> annotated.
> >> >> >> >>>
> >> >> >> >>> Chris
> >> >> >> >>>
> >> >> >> >>>
> >> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >>>
> >> >> >> >>>> Review board is not accepting my patch and is not accepting
> the
> >> >> valid
> >> >> >> >>>> file paths. I have attached the patch as a file to the
> review.
> >> >> >> >>>>
> >> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> >> chris@cxtsoftware.com
> >> >> >
> >> >> >> wrote:
> >> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >> >> >> >>>> >
> >> >> >> >>>> >
> >> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >> >> >> >>>> >
> >> >> >> >>>> >> I was never able to hit the endpoint as expected. I've
> posted
> >> >> the
> >> >> >> >>>> >> patch on the review board if anyone can take a look and
> offer
> >> >> >> advice -
> >> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >> >> >> >>>> >>
> >> >> >> >>>> >> Thanks
> >> >> >> >>>> >>
> >> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> >> >> chris@cxtsoftware.com
> >> >> >> >
> >> >> >> >>>> wrote:
> >> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >> >> >>>> >> >
> >> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >> >> >> chris@cxtsoftware.com
> >> >> >> >>>> >> <javascript:;>>
> >> >> >> >>>> >> >> wrote:
> >> >> >> >>>> >> >> > In the xml file you need to create the bean, then
> >> reference
> >> >> >> it in
> >> >> >> >>>> the
> >> >> >> >>>> >> >> > server element near the top. Other than that...no,
> that
> >> >> >> should be
> >> >> >> >>>> >> all. I
> >> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
> >> >> >> >>>> >> >> >
> >> >> >> >>>> >> >> I did. I'm also messing around with the service
> injection,
> >> >> >> which may
> >> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >> >> >> >>>> >> >>
> >> >> >> >>>> >> >> > I thought we were going to do
> >> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >> >> >>>> >> >> > since it makes no sense to manage a region widget
> >> outside a
> >> >> >> region
> >> >> >> >>>> >> >> outside
> >> >> >> >>>> >> >> > a page?
> >> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
> >> concept
> >> >> >> with
> >> >> >> >>>> the
> >> >> >> >>>> >> >> wrapped json object so I picked something simple with
> the
> >> >> >> service and
> >> >> >> >>>> >> >> rest models already in place.
> >> >> >> >>>> >> >>
> >> >> >> >>>> >> >> In general though I don't see any value to dealing with
> >> >> region
> >> >> >> >>>> widgets
> >> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over
> just
> >> >> >> dealing
> >> >> >> >>>> with
> >> >> >> >>>> >> >> them directly. It's just adding weight to the pages
> >> >> controller,
> >> >> >> >>>> rather
> >> >> >> >>>> >> >> than breaking them up and dealing with resource
> concerns
> >> >> >> separately.
> >> >> >> >>>> >> >>
> >> >> >> >>>> >> >> I get what you're saying about regions and
> regionwidgets
> >> only
> >> >> >> making
> >> >> >> >>>> >> >> sense in the context of a page, but you could say the
> same
> >> >> >> thing for
> >> >> >> >>>> >> >> any 1-many associated resource. Both entities are
> always
> >> >> >> uniquely
> >> >> >> >>>> >> >> identified, so why not deal with them individually? I
> see
> >> an
> >> >> >> upside
> >> >> >> >>>> of
> >> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
> >> >> downside.
> >> >> >> >>>> >> >
> >> >> >> >>>> >> >
> >> >> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
> >> >> >> identified and
> >> >> >> >>>> are
> >> >> >> >>>> >> > really sun objects unlike JPA today. But that is a
> longer
> >> >> >> >>>> conversation.
> >> >> >> >>>> >> >
> >> >> >> >>>> >> >>
> >> >> >> >>>> >> >> >
> >> >> >> >>>> >> >> >
> >> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >> >> >> >>>> >> >> >
> >> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
> >> regionWidgets.
> >> >> I've
> >> >> >> >>>> added
> >> >> >> >>>> >> >> >> the interface and default implementation, and
> created /
> >> >> >> registered
> >> >> >> >>>> >> the
> >> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >> >> >> >>>> >> >> >>
> >> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
> >> >> matching
> >> >> >> >>>> request
> >> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
> >> Relative
> >> >> >> Path:
> >> >> >> >>>> /1,
> >> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> >> >>>> >> >> >>
> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
> >> >> >> >>>> >> >> >>
> >> >> >> >>>> >> >> >> Is there anything else I need to do in order to
> create
> >> and
> >> >> >> >>>> register a
> >> >> >> >>>> >> >> >> new endpoint?
> >> >> >> >>>> >> >> >>
> >> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >> >> >> >>>> >> chris@cxtsoftware.com>
> >> >> >> >>>> >> >> >> wrote:
> >> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >>>> >> >> >> >>
> >> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >> >> >> >>>> >> >> chris@cxtsoftware.com>
> >> >> >> >>>> >> >> >> >>> wrote:
> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin
> Noe-Payne
> >> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like
> to
> >> >> start
> >> >> >> >>>> >> implementing
> >> >> >> >>>> >> >> >> more
> >> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for
> >> the
> >> >> >> entire
> >> >> >> >>>> >> angular
> >> >> >> >>>> >> >> >> >>> >> > architecture.
> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the
> current
> >> >> apis
> >> >> >> in
> >> >> >> >>>> trunk
> >> >> >> >>>> >> >> are
> >> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not
> tested
> >> and
> >> >> >> much of
> >> >> >> >>>> >> the
> >> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of
> the
> >> >> rest
> >> >> >> api
> >> >> >> >>>> >> >> >> implementations
> >> >> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is
> >> there
> >> >> >> other
> >> >> >> >>>> >> >> >> documentation
> >> >> >> >>>> >> >> >> >>> >> > we can reference?
> >> >> >> >>>> >> >> >> >>> >> >
> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
> >> >> >> "reference"
> >> >> >> >>>> of
> >> >> >> >>>> >> how
> >> >> >> >>>> >> >> I'd
> >> >> >> >>>> >> >> >> >>> like
> >> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
> >> >> progress. I
> >> >> >> need
> >> >> >> >>>> to
> >> >> >> >>>> >> go
> >> >> >> >>>> >> >> >> back
> >> >> >> >>>> >> >> >> >>> and
> >> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement
> the
> >> >> >> "fields"
> >> >> >> >>>> >> concept.
> >> >> >> >>>> >> >> >> >>> Couple of
> >> >> >> >>>> >> >> >> >>> >> notes:
> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >>>> >> >> >> >>> >>  - Object representations should be as flat
> as
> >> >> >> possible
> >> >> >> >>>> >> >> >> >>> >> and separate requests should be made to
> nested
> >> >> >> resources to
> >> >> >> >>>> >> get
> >> >> >> >>>> >> >> >> nested
> >> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >> >> >> >>>> regions/1/regionwidgets,
> >> >> >> >>>> >> >> the
> >> >> >> >>>> >> >> >> >>> regions
> >> >> >> >>>> >> >> >> >>> >> representation should not contain an array of
> >> >> >> >>>> regionwidgets)
> >> >> >> >>>> >> >> >> >>> >>
> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to
> support
> >> this
> >> >> >> when
> >> >> >> >>>> >> >> rendering
> >> >> >> >>>> >> >> >> the
> >> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
> >> number of
> >> >> >> >>>> gadgets,
> >> >> >> >>>> >> >> adding
> >> >> >> >>>> >> >> >> to
> >> >> >> >>>> >> >> >> >>> the
> >> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
> >> >> >> >>>> >> >> >> >>> >
> >> >> >> >>>> >> >> >> >>>
> >> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
> >> >> >> endpoints for
> >> >> >> >>>> >> crud
> >> >> >> >>>> >> >> >> >>> operations on resources. We
> >> >> >> >>>> >>
> >> >> >> >>>>
> >> >> >>
> >> >>
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Tue, Jul 23, 2013 at 12:14 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
>> > <er...@gmail.com>wrote:
>> >
>> >> - Simple solution: All rest response models are flat. We ignore any
>> >> nested data, and just have separate endpoints to deliver that data.
>> >> I.E. Every model in the org.apache.rave.rest.model package has only
>> >> properties of "primitive" types, with no lists, no other classes. That
>> >> is NOT currently the case. Then the fields interceptor checks for the
>> >> presence of a fields argument. If not present, the object is delivered
>> >> as is. If present the argument (a string) is split by comma and only
>> >> the matched properties are delivered. The fields qs argument only has
>> >> to support comma-delimited list of property names.
>> >> Ex: ?fields=name,pageType
>> >> //returns a page or pages with only name and pageType properties
>> >>
>> >
>> > I like the simple solution. I think the CRUD part of the API should be as
>> > flat as possible like Erin suggested and we have "special" end points to
>> > get back hierarchical data when needed, i.e. page rendering.
>> >
>>
>> Just to make sure we are on the same page, my proposal is that in both
>> cases a get request without any special query string will return only
>> flat data. The difference is that in the second case the fields query
>> parameter will support a syntax that CAN deliver nested data in a
>> single request.
>>
>
> That confuses me. I thought the whole point of the "special" end point was
> to handle things like page rendering in one query which would require
> hierarchical data every time. Why force the use of query string params to
> get that?
>

I was speaking in reference to the standard endpoints. The
page(s)ForRender endpoint is a special endpoint that serves a specific
client need for a complex nested data set. It will always return
hierarchical data, will probably not support field selection at all.

The standard endpoints will by default return flat data. They will
support field selection. If we choose to implement the more complex
field selection, then they will allow you to request nested data
through the field selection syntax.

>>
>> >>
>> >> - Complicated solution: All rest response models include references to
>> >> their nested data. This is the currently the case, and can be seen in
>> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
>> >> presence of fields qs argument. If not present it strips all nested
>> >> data from the models and only returns properties. If it is present, it
>> >> parses the argument and updates the data. The fields argument needs to
>> >> support a more complicated syntax that allows the requesting of nested
>> >> data. I would copy the syntax of facebook's graph search api, which
>> >> has a pretty readable solution. You allow for .fields and .limit on
>> >> fields, which can be nested.
>> >> Ex:
>> >>
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> >> //returns a page or pages with name and pageType properties, nested
>> >> list of regions (max of 2) with nested list of regionWidgets with only
>> >> properties of widgetId and locked
>> >>
>> >> In all cases, id should always be returned.
>> >> I think the algorithm in the simple solution is easy.
>> >> In a sense the algorithm in the second should be simple, because the
>> >> service layer is already getting all the nested data, and you are just
>> >> stripping it off. Not sure what the performance implications of that
>> >> are though.
>> >>
>> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >> > <er...@gmail.com>wrote:
>> >> >
>> >> >> Going back to the discussion on field selection - I am currently
>> going
>> >> >> through the exercise of writing out the Resource interfaces to define
>> >> >> our endpoints.  There is a set of generic query string parameters
>> that
>> >> >> we wish to support on all or many of the endpoints - fields (any get
>> >> >> request), limit / offset (any get request that returns a list).
>> >> >>
>> >> >> Rather than writing each endpoint to accept QueryParam()'s and repeat
>> >> >> the appropriate logic, I assume we would want to take advantage of
>> cxf
>> >> >> interceptors [1] to intelligently and generically handle those qs
>> >> >> arguments?
>> >> >>
>> >> >
>> >> > I like the concept but I'm not sure how we generically filter,
>> especially
>> >> > with nested data. I'd love to see it work that way though.
>> Interceptors
>> >> are
>> >> > pretty easy to use, it's the filter algorithm I haven't figured out
>> yet.
>> >> > Thoughts?
>> >> >
>> >> >>
>> >> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >> >>
>> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >> >> <er...@gmail.com> wrote:
>> >> >> > Ok, so the endpoint is now working. Any thoughts about the
>> >> >> > JsonResponseWrapper approach? Does that seem like the best way to
>> get
>> >> >> > wrapped responses?
>> >> >> >
>> >> >> > For the next step I would like to start writing out all of the
>> >> >> > resource interfaces so that we can begin writing angular $resource
>> >> >> > services against them.
>> >> >> >
>> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >> >> > <er...@gmail.com> wrote:
>> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>> >> >> out...
>> >> >> >>
>> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >> >> wrote:
>> >> >> >>> Erin,
>> >> >> >>>
>> >> >> >>> I got it working, at least the CXF part. Couple things:
>> >> >> >>>
>> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
>> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
>> @ParamPath
>> >> >> >>> attributes from variable signatures. I know Intellij puts those
>> in
>> >> >> there
>> >> >> >>> but they cause problems. Only the interface should be annotated.
>> >> >> >>>
>> >> >> >>> Chris
>> >> >> >>>
>> >> >> >>>
>> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >>>
>> >> >> >>>> Review board is not accepting my patch and is not accepting the
>> >> valid
>> >> >> >>>> file paths. I have attached the patch as a file to the review.
>> >> >> >>>>
>> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >> >
>> >> >> wrote:
>> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >> >> >>>> >
>> >> >> >>>> >
>> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >> >> >>>> >
>> >> >> >>>> >> I was never able to hit the endpoint as expected. I've posted
>> >> the
>> >> >> >>>> >> patch on the review board if anyone can take a look and offer
>> >> >> advice -
>> >> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >> >> >>>> >>
>> >> >> >>>> >> Thanks
>> >> >> >>>> >>
>> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> >> chris@cxtsoftware.com
>> >> >> >
>> >> >> >>>> wrote:
>> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >> >>>> >> >
>> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >> >> chris@cxtsoftware.com
>> >> >> >>>> >> <javascript:;>>
>> >> >> >>>> >> >> wrote:
>> >> >> >>>> >> >> > In the xml file you need to create the bean, then
>> reference
>> >> >> it in
>> >> >> >>>> the
>> >> >> >>>> >> >> > server element near the top. Other than that...no, that
>> >> >> should be
>> >> >> >>>> >> all. I
>> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
>> >> >> >>>> >> >> >
>> >> >> >>>> >> >> I did. I'm also messing around with the service injection,
>> >> >> which may
>> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >> >> >>>> >> >>
>> >> >> >>>> >> >> > I thought we were going to do
>> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >> >>>> >> >> > since it makes no sense to manage a region widget
>> outside a
>> >> >> region
>> >> >> >>>> >> >> outside
>> >> >> >>>> >> >> > a page?
>> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
>> concept
>> >> >> with
>> >> >> >>>> the
>> >> >> >>>> >> >> wrapped json object so I picked something simple with the
>> >> >> service and
>> >> >> >>>> >> >> rest models already in place.
>> >> >> >>>> >> >>
>> >> >> >>>> >> >> In general though I don't see any value to dealing with
>> >> region
>> >> >> >>>> widgets
>> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>> >> >> dealing
>> >> >> >>>> with
>> >> >> >>>> >> >> them directly. It's just adding weight to the pages
>> >> controller,
>> >> >> >>>> rather
>> >> >> >>>> >> >> than breaking them up and dealing with resource concerns
>> >> >> separately.
>> >> >> >>>> >> >>
>> >> >> >>>> >> >> I get what you're saying about regions and regionwidgets
>> only
>> >> >> making
>> >> >> >>>> >> >> sense in the context of a page, but you could say the same
>> >> >> thing for
>> >> >> >>>> >> >> any 1-many associated resource. Both entities are always
>> >> >> uniquely
>> >> >> >>>> >> >> identified, so why not deal with them individually? I see
>> an
>> >> >> upside
>> >> >> >>>> of
>> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
>> >> downside.
>> >> >> >>>> >> >
>> >> >> >>>> >> >
>> >> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>> >> >> identified and
>> >> >> >>>> are
>> >> >> >>>> >> > really sun objects unlike JPA today. But that is a longer
>> >> >> >>>> conversation.
>> >> >> >>>> >> >
>> >> >> >>>> >> >>
>> >> >> >>>> >> >> >
>> >> >> >>>> >> >> >
>> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >> >> >>>> >> >> >
>> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
>> regionWidgets.
>> >> I've
>> >> >> >>>> added
>> >> >> >>>> >> >> >> the interface and default implementation, and created /
>> >> >> registered
>> >> >> >>>> >> the
>> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >> >>>> >> >> >>
>> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
>> >> matching
>> >> >> >>>> request
>> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
>> Relative
>> >> >> Path:
>> >> >> >>>> /1,
>> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> >>>> >> >> >>
>> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >> >> >>>> >> >> >>
>> >> >> >>>> >> >> >> Is there anything else I need to do in order to create
>> and
>> >> >> >>>> register a
>> >> >> >>>> >> >> >> new endpoint?
>> >> >> >>>> >> >> >>
>> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >> >> >>>> >> chris@cxtsoftware.com>
>> >> >> >>>> >> >> >> wrote:
>> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >>>> >> >> >> >>
>> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >> >> >>>> >> >> chris@cxtsoftware.com>
>> >> >> >>>> >> >> >> >>> wrote:
>> >> >> >>>> >> >> >> >>> >
>> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >>>> >> >> >> >>> >>
>> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
>> >> start
>> >> >> >>>> >> implementing
>> >> >> >>>> >> >> >> more
>> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for
>> the
>> >> >> entire
>> >> >> >>>> >> angular
>> >> >> >>>> >> >> >> >>> >> > architecture.
>> >> >> >>>> >> >> >> >>> >> >
>> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
>> >> apis
>> >> >> in
>> >> >> >>>> trunk
>> >> >> >>>> >> >> are
>> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested
>> and
>> >> >> much of
>> >> >> >>>> >> the
>> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
>> >> rest
>> >> >> api
>> >> >> >>>> >> >> >> implementations
>> >> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is
>> there
>> >> >> other
>> >> >> >>>> >> >> >> documentation
>> >> >> >>>> >> >> >> >>> >> > we can reference?
>> >> >> >>>> >> >> >> >>> >> >
>> >> >> >>>> >> >> >> >>> >>
>> >> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
>> >> >> "reference"
>> >> >> >>>> of
>> >> >> >>>> >> how
>> >> >> >>>> >> >> I'd
>> >> >> >>>> >> >> >> >>> like
>> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
>> >> progress. I
>> >> >> need
>> >> >> >>>> to
>> >> >> >>>> >> go
>> >> >> >>>> >> >> >> back
>> >> >> >>>> >> >> >> >>> and
>> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>> >> >> "fields"
>> >> >> >>>> >> concept.
>> >> >> >>>> >> >> >> >>> Couple of
>> >> >> >>>> >> >> >> >>> >> notes:
>> >> >> >>>> >> >> >> >>> >>
>> >> >> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>> >> >> possible
>> >> >> >>>> >> >> >> >>> >> and separate requests should be made to nested
>> >> >> resources to
>> >> >> >>>> >> get
>> >> >> >>>> >> >> >> nested
>> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >> >> >>>> regions/1/regionwidgets,
>> >> >> >>>> >> >> the
>> >> >> >>>> >> >> >> >>> regions
>> >> >> >>>> >> >> >> >>> >> representation should not contain an array of
>> >> >> >>>> regionwidgets)
>> >> >> >>>> >> >> >> >>> >>
>> >> >> >>>> >> >> >> >>> >
>> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to support
>> this
>> >> >> when
>> >> >> >>>> >> >> rendering
>> >> >> >>>> >> >> >> the
>> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
>> number of
>> >> >> >>>> gadgets,
>> >> >> >>>> >> >> adding
>> >> >> >>>> >> >> >> to
>> >> >> >>>> >> >> >> >>> the
>> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >> >> >>>> >> >> >> >>> >
>> >> >> >>>> >> >> >> >>>
>> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>> >> >> endpoints for
>> >> >> >>>> >> crud
>> >> >> >>>> >> >> >> >>> operations on resources. We
>> >> >> >>>> >>
>> >> >> >>>>
>> >> >>
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Mon, Jul 22, 2013 at 9:04 PM, Erin Noe-Payne <er...@gmail.com>wrote:

> On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> > On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> > <er...@gmail.com>wrote:
> >
> >> - Simple solution: All rest response models are flat. We ignore any
> >> nested data, and just have separate endpoints to deliver that data.
> >> I.E. Every model in the org.apache.rave.rest.model package has only
> >> properties of "primitive" types, with no lists, no other classes. That
> >> is NOT currently the case. Then the fields interceptor checks for the
> >> presence of a fields argument. If not present, the object is delivered
> >> as is. If present the argument (a string) is split by comma and only
> >> the matched properties are delivered. The fields qs argument only has
> >> to support comma-delimited list of property names.
> >> Ex: ?fields=name,pageType
> >> //returns a page or pages with only name and pageType properties
> >>
> >
> > I like the simple solution. I think the CRUD part of the API should be as
> > flat as possible like Erin suggested and we have "special" end points to
> > get back hierarchical data when needed, i.e. page rendering.
> >
>
> Just to make sure we are on the same page, my proposal is that in both
> cases a get request without any special query string will return only
> flat data. The difference is that in the second case the fields query
> parameter will support a syntax that CAN deliver nested data in a
> single request.
>

That confuses me. I thought the whole point of the "special" end point was
to handle things like page rendering in one query which would require
hierarchical data every time. Why force the use of query string params to
get that?

>
> >>
> >> - Complicated solution: All rest response models include references to
> >> their nested data. This is the currently the case, and can be seen in
> >> org.apache.rave.rest.model.Page. The fields interceptor checks for
> >> presence of fields qs argument. If not present it strips all nested
> >> data from the models and only returns properties. If it is present, it
> >> parses the argument and updates the data. The fields argument needs to
> >> support a more complicated syntax that allows the requesting of nested
> >> data. I would copy the syntax of facebook's graph search api, which
> >> has a pretty readable solution. You allow for .fields and .limit on
> >> fields, which can be nested.
> >> Ex:
> >>
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> >> //returns a page or pages with name and pageType properties, nested
> >> list of regions (max of 2) with nested list of regionWidgets with only
> >> properties of widgetId and locked
> >>
> >> In all cases, id should always be returned.
> >> I think the algorithm in the simple solution is easy.
> >> In a sense the algorithm in the second should be simple, because the
> >> service layer is already getting all the nested data, and you are just
> >> stripping it off. Not sure what the performance implications of that
> >> are though.
> >>
> >> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >> > <er...@gmail.com>wrote:
> >> >
> >> >> Going back to the discussion on field selection - I am currently
> going
> >> >> through the exercise of writing out the Resource interfaces to define
> >> >> our endpoints.  There is a set of generic query string parameters
> that
> >> >> we wish to support on all or many of the endpoints - fields (any get
> >> >> request), limit / offset (any get request that returns a list).
> >> >>
> >> >> Rather than writing each endpoint to accept QueryParam()'s and repeat
> >> >> the appropriate logic, I assume we would want to take advantage of
> cxf
> >> >> interceptors [1] to intelligently and generically handle those qs
> >> >> arguments?
> >> >>
> >> >
> >> > I like the concept but I'm not sure how we generically filter,
> especially
> >> > with nested data. I'd love to see it work that way though.
> Interceptors
> >> are
> >> > pretty easy to use, it's the filter algorithm I haven't figured out
> yet.
> >> > Thoughts?
> >> >
> >> >>
> >> >> [1] http://cxf.apache.org/docs/interceptors.html
> >> >>
> >> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >> >> <er...@gmail.com> wrote:
> >> >> > Ok, so the endpoint is now working. Any thoughts about the
> >> >> > JsonResponseWrapper approach? Does that seem like the best way to
> get
> >> >> > wrapped responses?
> >> >> >
> >> >> > For the next step I would like to start writing out all of the
> >> >> > resource interfaces so that we can begin writing angular $resource
> >> >> > services against them.
> >> >> >
> >> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >> >> > <er...@gmail.com> wrote:
> >> >> >> Awesome, thanks Chris. Not sure I would have ever figured that one
> >> >> out...
> >> >> >>
> >> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <
> chris@cxtsoftware.com>
> >> >> wrote:
> >> >> >>> Erin,
> >> >> >>>
> >> >> >>> I got it working, at least the CXF part. Couple things:
> >> >> >>>
> >> >> >>> 1) In the interface, make sure to annotate the @GET methods
> >> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the
> @ParamPath
> >> >> >>> attributes from variable signatures. I know Intellij puts those
> in
> >> >> there
> >> >> >>> but they cause problems. Only the interface should be annotated.
> >> >> >>>
> >> >> >>> Chris
> >> >> >>>
> >> >> >>>
> >> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >>>
> >> >> >>>> Review board is not accepting my patch and is not accepting the
> >> valid
> >> >> >>>> file paths. I have attached the patch as a file to the review.
> >> >> >>>>
> >> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> chris@cxtsoftware.com
> >> >
> >> >> wrote:
> >> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >> >> >>>> >
> >> >> >>>> >
> >> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >> >> >>>> erin.noe.payne@gmail.com>wrote:
> >> >> >>>> >
> >> >> >>>> >> I was never able to hit the endpoint as expected. I've posted
> >> the
> >> >> >>>> >> patch on the review board if anyone can take a look and offer
> >> >> advice -
> >> >> >>>> >> https://reviews.apache.org/r/12777/.
> >> >> >>>> >>
> >> >> >>>> >> Thanks
> >> >> >>>> >>
> >> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> >> chris@cxtsoftware.com
> >> >> >
> >> >> >>>> wrote:
> >> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >> >>>> >> >
> >> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >> >> chris@cxtsoftware.com
> >> >> >>>> >> <javascript:;>>
> >> >> >>>> >> >> wrote:
> >> >> >>>> >> >> > In the xml file you need to create the bean, then
> reference
> >> >> it in
> >> >> >>>> the
> >> >> >>>> >> >> > server element near the top. Other than that...no, that
> >> >> should be
> >> >> >>>> >> all. I
> >> >> >>>> >> >> > assume you set the Path attribute on the resource.
> >> >> >>>> >> >> >
> >> >> >>>> >> >> I did. I'm also messing around with the service injection,
> >> >> which may
> >> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >> >> >>>> >> >>
> >> >> >>>> >> >> > I thought we were going to do
> >> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >> >>>> >> >> > since it makes no sense to manage a region widget
> outside a
> >> >> region
> >> >> >>>> >> >> outside
> >> >> >>>> >> >> > a page?
> >> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
> concept
> >> >> with
> >> >> >>>> the
> >> >> >>>> >> >> wrapped json object so I picked something simple with the
> >> >> service and
> >> >> >>>> >> >> rest models already in place.
> >> >> >>>> >> >>
> >> >> >>>> >> >> In general though I don't see any value to dealing with
> >> region
> >> >> >>>> widgets
> >> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
> >> >> dealing
> >> >> >>>> with
> >> >> >>>> >> >> them directly. It's just adding weight to the pages
> >> controller,
> >> >> >>>> rather
> >> >> >>>> >> >> than breaking them up and dealing with resource concerns
> >> >> separately.
> >> >> >>>> >> >>
> >> >> >>>> >> >> I get what you're saying about regions and regionwidgets
> only
> >> >> making
> >> >> >>>> >> >> sense in the context of a page, but you could say the same
> >> >> thing for
> >> >> >>>> >> >> any 1-many associated resource. Both entities are always
> >> >> uniquely
> >> >> >>>> >> >> identified, so why not deal with them individually? I see
> an
> >> >> upside
> >> >> >>>> of
> >> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
> >> downside.
> >> >> >>>> >> >
> >> >> >>>> >> >
> >> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
> >> >> identified and
> >> >> >>>> are
> >> >> >>>> >> > really sun objects unlike JPA today. But that is a longer
> >> >> >>>> conversation.
> >> >> >>>> >> >
> >> >> >>>> >> >>
> >> >> >>>> >> >> >
> >> >> >>>> >> >> >
> >> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> >> >>>> >> >> > <er...@gmail.com>wrote:
> >> >> >>>> >> >> >
> >> >> >>>> >> >> >> I'm trying to register a new endpoint for
> regionWidgets.
> >> I've
> >> >> >>>> added
> >> >> >>>> >> >> >> the interface and default implementation, and created /
> >> >> registered
> >> >> >>>> >> the
> >> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >> >> >>>> >> >> >>
> >> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
> >> matching
> >> >> >>>> request
> >> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
> Relative
> >> >> Path:
> >> >> >>>> /1,
> >> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> >>>> >> >> >>
> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
> >> >> >>>> >> >> >>
> >> >> >>>> >> >> >> Is there anything else I need to do in order to create
> and
> >> >> >>>> register a
> >> >> >>>> >> >> >> new endpoint?
> >> >> >>>> >> >> >>
> >> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >> >> >>>> >> chris@cxtsoftware.com>
> >> >> >>>> >> >> >> wrote:
> >> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >>>> >> >> >> >>
> >> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >> >> >>>> >> >> >> >>> wrote:
> >> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >> >> >>>> >> >> chris@cxtsoftware.com>
> >> >> >>>> >> >> >> >>> wrote:
> >> >> >>>> >> >> >> >>> >
> >> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >>>> >> >> >> >>> >>
> >> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
> >> start
> >> >> >>>> >> implementing
> >> >> >>>> >> >> >> more
> >> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for
> the
> >> >> entire
> >> >> >>>> >> angular
> >> >> >>>> >> >> >> >>> >> > architecture.
> >> >> >>>> >> >> >> >>> >> >
> >> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
> >> apis
> >> >> in
> >> >> >>>> trunk
> >> >> >>>> >> >> are
> >> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested
> and
> >> >> much of
> >> >> >>>> >> the
> >> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
> >> rest
> >> >> api
> >> >> >>>> >> >> >> implementations
> >> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is
> there
> >> >> other
> >> >> >>>> >> >> >> documentation
> >> >> >>>> >> >> >> >>> >> > we can reference?
> >> >> >>>> >> >> >> >>> >> >
> >> >> >>>> >> >> >> >>> >>
> >> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
> >> >> "reference"
> >> >> >>>> of
> >> >> >>>> >> how
> >> >> >>>> >> >> I'd
> >> >> >>>> >> >> >> >>> like
> >> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
> >> progress. I
> >> >> need
> >> >> >>>> to
> >> >> >>>> >> go
> >> >> >>>> >> >> >> back
> >> >> >>>> >> >> >> >>> and
> >> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
> >> >> "fields"
> >> >> >>>> >> concept.
> >> >> >>>> >> >> >> >>> Couple of
> >> >> >>>> >> >> >> >>> >> notes:
> >> >> >>>> >> >> >> >>> >>
> >> >> >>>> >> >> >> >>> >>  - Object representations should be as flat as
> >> >> possible
> >> >> >>>> >> >> >> >>> >> and separate requests should be made to nested
> >> >> resources to
> >> >> >>>> >> get
> >> >> >>>> >> >> >> nested
> >> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >> >> >>>> regions/1/regionwidgets,
> >> >> >>>> >> >> the
> >> >> >>>> >> >> >> >>> regions
> >> >> >>>> >> >> >> >>> >> representation should not contain an array of
> >> >> >>>> regionwidgets)
> >> >> >>>> >> >> >> >>> >>
> >> >> >>>> >> >> >> >>> >
> >> >> >>>> >> >> >> >>> > I am concerned about the round trips to support
> this
> >> >> when
> >> >> >>>> >> >> rendering
> >> >> >>>> >> >> >> the
> >> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient
> number of
> >> >> >>>> gadgets,
> >> >> >>>> >> >> adding
> >> >> >>>> >> >> >> to
> >> >> >>>> >> >> >> >>> the
> >> >> >>>> >> >> >> >>> > number of requests becomes problematic.
> >> >> >>>> >> >> >> >>> >
> >> >> >>>> >> >> >> >>>
> >> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
> >> >> endpoints for
> >> >> >>>> >> crud
> >> >> >>>> >> >> >> >>> operations on resources. We
> >> >> >>>> >>
> >> >> >>>>
> >> >>
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Mon, Jul 22, 2013 at 11:56 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> - Simple solution: All rest response models are flat. We ignore any
>> nested data, and just have separate endpoints to deliver that data.
>> I.E. Every model in the org.apache.rave.rest.model package has only
>> properties of "primitive" types, with no lists, no other classes. That
>> is NOT currently the case. Then the fields interceptor checks for the
>> presence of a fields argument. If not present, the object is delivered
>> as is. If present the argument (a string) is split by comma and only
>> the matched properties are delivered. The fields qs argument only has
>> to support comma-delimited list of property names.
>> Ex: ?fields=name,pageType
>> //returns a page or pages with only name and pageType properties
>>
>
> I like the simple solution. I think the CRUD part of the API should be as
> flat as possible like Erin suggested and we have "special" end points to
> get back hierarchical data when needed, i.e. page rendering.
>

Just to make sure we are on the same page, my proposal is that in both
cases a get request without any special query string will return only
flat data. The difference is that in the second case the fields query
parameter will support a syntax that CAN deliver nested data in a
single request.

>>
>> - Complicated solution: All rest response models include references to
>> their nested data. This is the currently the case, and can be seen in
>> org.apache.rave.rest.model.Page. The fields interceptor checks for
>> presence of fields qs argument. If not present it strips all nested
>> data from the models and only returns properties. If it is present, it
>> parses the argument and updates the data. The fields argument needs to
>> support a more complicated syntax that allows the requesting of nested
>> data. I would copy the syntax of facebook's graph search api, which
>> has a pretty readable solution. You allow for .fields and .limit on
>> fields, which can be nested.
>> Ex:
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> //returns a page or pages with name and pageType properties, nested
>> list of regions (max of 2) with nested list of regionWidgets with only
>> properties of widgetId and locked
>>
>> In all cases, id should always be returned.
>> I think the algorithm in the simple solution is easy.
>> In a sense the algorithm in the second should be simple, because the
>> service layer is already getting all the nested data, and you are just
>> stripping it off. Not sure what the performance implications of that
>> are though.
>>
>> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> > <er...@gmail.com>wrote:
>> >
>> >> Going back to the discussion on field selection - I am currently going
>> >> through the exercise of writing out the Resource interfaces to define
>> >> our endpoints.  There is a set of generic query string parameters that
>> >> we wish to support on all or many of the endpoints - fields (any get
>> >> request), limit / offset (any get request that returns a list).
>> >>
>> >> Rather than writing each endpoint to accept QueryParam()'s and repeat
>> >> the appropriate logic, I assume we would want to take advantage of cxf
>> >> interceptors [1] to intelligently and generically handle those qs
>> >> arguments?
>> >>
>> >
>> > I like the concept but I'm not sure how we generically filter, especially
>> > with nested data. I'd love to see it work that way though. Interceptors
>> are
>> > pretty easy to use, it's the filter algorithm I haven't figured out yet.
>> > Thoughts?
>> >
>> >>
>> >> [1] http://cxf.apache.org/docs/interceptors.html
>> >>
>> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >> <er...@gmail.com> wrote:
>> >> > Ok, so the endpoint is now working. Any thoughts about the
>> >> > JsonResponseWrapper approach? Does that seem like the best way to get
>> >> > wrapped responses?
>> >> >
>> >> > For the next step I would like to start writing out all of the
>> >> > resource interfaces so that we can begin writing angular $resource
>> >> > services against them.
>> >> >
>> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >> > <er...@gmail.com> wrote:
>> >> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>> >> out...
>> >> >>
>> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> >>> Erin,
>> >> >>>
>> >> >>> I got it working, at least the CXF part. Couple things:
>> >> >>>
>> >> >>> 1) In the interface, make sure to annotate the @GET methods
>> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>> >> >>> attributes from variable signatures. I know Intellij puts those in
>> >> there
>> >> >>> but they cause problems. Only the interface should be annotated.
>> >> >>>
>> >> >>> Chris
>> >> >>>
>> >> >>>
>> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >> erin.noe.payne@gmail.com>wrote:
>> >> >>>
>> >> >>>> Review board is not accepting my patch and is not accepting the
>> valid
>> >> >>>> file paths. I have attached the patch as a file to the review.
>> >> >>>>
>> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <chris@cxtsoftware.com
>> >
>> >> wrote:
>> >> >>>> > Erin, I'm not seeing a patch posted up there.
>> >> >>>> >
>> >> >>>> >
>> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >> >>>> erin.noe.payne@gmail.com>wrote:
>> >> >>>> >
>> >> >>>> >> I was never able to hit the endpoint as expected. I've posted
>> the
>> >> >>>> >> patch on the review board if anyone can take a look and offer
>> >> advice -
>> >> >>>> >> https://reviews.apache.org/r/12777/.
>> >> >>>> >>
>> >> >>>> >> Thanks
>> >> >>>> >>
>> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >> >
>> >> >>>> wrote:
>> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >>>> >> >
>> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >> chris@cxtsoftware.com
>> >> >>>> >> <javascript:;>>
>> >> >>>> >> >> wrote:
>> >> >>>> >> >> > In the xml file you need to create the bean, then reference
>> >> it in
>> >> >>>> the
>> >> >>>> >> >> > server element near the top. Other than that...no, that
>> >> should be
>> >> >>>> >> all. I
>> >> >>>> >> >> > assume you set the Path attribute on the resource.
>> >> >>>> >> >> >
>> >> >>>> >> >> I did. I'm also messing around with the service injection,
>> >> which may
>> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >> >>>> >> >>
>> >> >>>> >> >> > I thought we were going to do
>> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >>>> >> >> > since it makes no sense to manage a region widget outside a
>> >> region
>> >> >>>> >> >> outside
>> >> >>>> >> >> > a page?
>> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
>> >> with
>> >> >>>> the
>> >> >>>> >> >> wrapped json object so I picked something simple with the
>> >> service and
>> >> >>>> >> >> rest models already in place.
>> >> >>>> >> >>
>> >> >>>> >> >> In general though I don't see any value to dealing with
>> region
>> >> >>>> widgets
>> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>> >> dealing
>> >> >>>> with
>> >> >>>> >> >> them directly. It's just adding weight to the pages
>> controller,
>> >> >>>> rather
>> >> >>>> >> >> than breaking them up and dealing with resource concerns
>> >> separately.
>> >> >>>> >> >>
>> >> >>>> >> >> I get what you're saying about regions and regionwidgets only
>> >> making
>> >> >>>> >> >> sense in the context of a page, but you could say the same
>> >> thing for
>> >> >>>> >> >> any 1-many associated resource. Both entities are always
>> >> uniquely
>> >> >>>> >> >> identified, so why not deal with them individually? I see an
>> >> upside
>> >> >>>> of
>> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
>> downside.
>> >> >>>> >> >
>> >> >>>> >> >
>> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>> >> identified and
>> >> >>>> are
>> >> >>>> >> > really sun objects unlike JPA today. But that is a longer
>> >> >>>> conversation.
>> >> >>>> >> >
>> >> >>>> >> >>
>> >> >>>> >> >> >
>> >> >>>> >> >> >
>> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> >>>> >> >> > <er...@gmail.com>wrote:
>> >> >>>> >> >> >
>> >> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets.
>> I've
>> >> >>>> added
>> >> >>>> >> >> >> the interface and default implementation, and created /
>> >> registered
>> >> >>>> >> the
>> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >>>> >> >> >>
>> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
>> matching
>> >> >>>> request
>> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
>> >> Path:
>> >> >>>> /1,
>> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >>>> >> >> >>
>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >> >>>> >> >> >>
>> >> >>>> >> >> >> Is there anything else I need to do in order to create and
>> >> >>>> register a
>> >> >>>> >> >> >> new endpoint?
>> >> >>>> >> >> >>
>> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >>>> >> >> >> <er...@gmail.com> wrote:
>> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >> >>>> >> chris@cxtsoftware.com>
>> >> >>>> >> >> >> wrote:
>> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >>>> >> >> >> >>
>> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >> >>>> >> >> >> >>> wrote:
>> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >> >>>> >> >> chris@cxtsoftware.com>
>> >> >>>> >> >> >> >>> wrote:
>> >> >>>> >> >> >> >>> >
>> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >>>> >> >> >> >>> >>
>> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
>> start
>> >> >>>> >> implementing
>> >> >>>> >> >> >> more
>> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
>> >> entire
>> >> >>>> >> angular
>> >> >>>> >> >> >> >>> >> > architecture.
>> >> >>>> >> >> >> >>> >> >
>> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
>> apis
>> >> in
>> >> >>>> trunk
>> >> >>>> >> >> are
>> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
>> >> much of
>> >> >>>> >> the
>> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
>> rest
>> >> api
>> >> >>>> >> >> >> implementations
>> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
>> >> other
>> >> >>>> >> >> >> documentation
>> >> >>>> >> >> >> >>> >> > we can reference?
>> >> >>>> >> >> >> >>> >> >
>> >> >>>> >> >> >> >>> >>
>> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
>> >> "reference"
>> >> >>>> of
>> >> >>>> >> how
>> >> >>>> >> >> I'd
>> >> >>>> >> >> >> >>> like
>> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
>> progress. I
>> >> need
>> >> >>>> to
>> >> >>>> >> go
>> >> >>>> >> >> >> back
>> >> >>>> >> >> >> >>> and
>> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>> >> "fields"
>> >> >>>> >> concept.
>> >> >>>> >> >> >> >>> Couple of
>> >> >>>> >> >> >> >>> >> notes:
>> >> >>>> >> >> >> >>> >>
>> >> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>> >> possible
>> >> >>>> >> >> >> >>> >> and separate requests should be made to nested
>> >> resources to
>> >> >>>> >> get
>> >> >>>> >> >> >> nested
>> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >> >>>> regions/1/regionwidgets,
>> >> >>>> >> >> the
>> >> >>>> >> >> >> >>> regions
>> >> >>>> >> >> >> >>> >> representation should not contain an array of
>> >> >>>> regionwidgets)
>> >> >>>> >> >> >> >>> >>
>> >> >>>> >> >> >> >>> >
>> >> >>>> >> >> >> >>> > I am concerned about the round trips to support this
>> >> when
>> >> >>>> >> >> rendering
>> >> >>>> >> >> >> the
>> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>> >> >>>> gadgets,
>> >> >>>> >> >> adding
>> >> >>>> >> >> >> to
>> >> >>>> >> >> >> >>> the
>> >> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >> >>>> >> >> >> >>> >
>> >> >>>> >> >> >> >>>
>> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>> >> endpoints for
>> >> >>>> >> crud
>> >> >>>> >> >> >> >>> operations on resources. We
>> >> >>>> >>
>> >> >>>>
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Mon, Jul 22, 2013 at 12:58 PM, Erin Noe-Payne
<er...@gmail.com>wrote:

> - Simple solution: All rest response models are flat. We ignore any
> nested data, and just have separate endpoints to deliver that data.
> I.E. Every model in the org.apache.rave.rest.model package has only
> properties of "primitive" types, with no lists, no other classes. That
> is NOT currently the case. Then the fields interceptor checks for the
> presence of a fields argument. If not present, the object is delivered
> as is. If present the argument (a string) is split by comma and only
> the matched properties are delivered. The fields qs argument only has
> to support comma-delimited list of property names.
> Ex: ?fields=name,pageType
> //returns a page or pages with only name and pageType properties
>

I like the simple solution. I think the CRUD part of the API should be as
flat as possible like Erin suggested and we have "special" end points to
get back hierarchical data when needed, i.e. page rendering.

>
> - Complicated solution: All rest response models include references to
> their nested data. This is the currently the case, and can be seen in
> org.apache.rave.rest.model.Page. The fields interceptor checks for
> presence of fields qs argument. If not present it strips all nested
> data from the models and only returns properties. If it is present, it
> parses the argument and updates the data. The fields argument needs to
> support a more complicated syntax that allows the requesting of nested
> data. I would copy the syntax of facebook's graph search api, which
> has a pretty readable solution. You allow for .fields and .limit on
> fields, which can be nested.
> Ex:
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> //returns a page or pages with name and pageType properties, nested
> list of regions (max of 2) with nested list of regionWidgets with only
> properties of widgetId and locked
>
> In all cases, id should always be returned.
> I think the algorithm in the simple solution is easy.
> In a sense the algorithm in the second should be simple, because the
> service layer is already getting all the nested data, and you are just
> stripping it off. Not sure what the performance implications of that
> are though.
>
> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> > On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> > <er...@gmail.com>wrote:
> >
> >> Going back to the discussion on field selection - I am currently going
> >> through the exercise of writing out the Resource interfaces to define
> >> our endpoints.  There is a set of generic query string parameters that
> >> we wish to support on all or many of the endpoints - fields (any get
> >> request), limit / offset (any get request that returns a list).
> >>
> >> Rather than writing each endpoint to accept QueryParam()'s and repeat
> >> the appropriate logic, I assume we would want to take advantage of cxf
> >> interceptors [1] to intelligently and generically handle those qs
> >> arguments?
> >>
> >
> > I like the concept but I'm not sure how we generically filter, especially
> > with nested data. I'd love to see it work that way though. Interceptors
> are
> > pretty easy to use, it's the filter algorithm I haven't figured out yet.
> > Thoughts?
> >
> >>
> >> [1] http://cxf.apache.org/docs/interceptors.html
> >>
> >> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >> <er...@gmail.com> wrote:
> >> > Ok, so the endpoint is now working. Any thoughts about the
> >> > JsonResponseWrapper approach? Does that seem like the best way to get
> >> > wrapped responses?
> >> >
> >> > For the next step I would like to start writing out all of the
> >> > resource interfaces so that we can begin writing angular $resource
> >> > services against them.
> >> >
> >> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >> > <er...@gmail.com> wrote:
> >> >> Awesome, thanks Chris. Not sure I would have ever figured that one
> >> out...
> >> >>
> >> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> >>> Erin,
> >> >>>
> >> >>> I got it working, at least the CXF part. Couple things:
> >> >>>
> >> >>> 1) In the interface, make sure to annotate the @GET methods
> >> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
> >> >>> attributes from variable signatures. I know Intellij puts those in
> >> there
> >> >>> but they cause problems. Only the interface should be annotated.
> >> >>>
> >> >>> Chris
> >> >>>
> >> >>>
> >> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >> erin.noe.payne@gmail.com>wrote:
> >> >>>
> >> >>>> Review board is not accepting my patch and is not accepting the
> valid
> >> >>>> file paths. I have attached the patch as a file to the review.
> >> >>>>
> >> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <chris@cxtsoftware.com
> >
> >> wrote:
> >> >>>> > Erin, I'm not seeing a patch posted up there.
> >> >>>> >
> >> >>>> >
> >> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >> >>>> erin.noe.payne@gmail.com>wrote:
> >> >>>> >
> >> >>>> >> I was never able to hit the endpoint as expected. I've posted
> the
> >> >>>> >> patch on the review board if anyone can take a look and offer
> >> advice -
> >> >>>> >> https://reviews.apache.org/r/12777/.
> >> >>>> >>
> >> >>>> >> Thanks
> >> >>>> >>
> >> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> chris@cxtsoftware.com
> >> >
> >> >>>> wrote:
> >> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >>>> >> >
> >> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >> chris@cxtsoftware.com
> >> >>>> >> <javascript:;>>
> >> >>>> >> >> wrote:
> >> >>>> >> >> > In the xml file you need to create the bean, then reference
> >> it in
> >> >>>> the
> >> >>>> >> >> > server element near the top. Other than that...no, that
> >> should be
> >> >>>> >> all. I
> >> >>>> >> >> > assume you set the Path attribute on the resource.
> >> >>>> >> >> >
> >> >>>> >> >> I did. I'm also messing around with the service injection,
> >> which may
> >> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >> >>>> >> >>
> >> >>>> >> >> > I thought we were going to do
> >> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >>>> >> >> > since it makes no sense to manage a region widget outside a
> >> region
> >> >>>> >> >> outside
> >> >>>> >> >> > a page?
> >> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
> >> with
> >> >>>> the
> >> >>>> >> >> wrapped json object so I picked something simple with the
> >> service and
> >> >>>> >> >> rest models already in place.
> >> >>>> >> >>
> >> >>>> >> >> In general though I don't see any value to dealing with
> region
> >> >>>> widgets
> >> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
> >> dealing
> >> >>>> with
> >> >>>> >> >> them directly. It's just adding weight to the pages
> controller,
> >> >>>> rather
> >> >>>> >> >> than breaking them up and dealing with resource concerns
> >> separately.
> >> >>>> >> >>
> >> >>>> >> >> I get what you're saying about regions and regionwidgets only
> >> making
> >> >>>> >> >> sense in the context of a page, but you could say the same
> >> thing for
> >> >>>> >> >> any 1-many associated resource. Both entities are always
> >> uniquely
> >> >>>> >> >> identified, so why not deal with them individually? I see an
> >> upside
> >> >>>> of
> >> >>>> >> >> simpler code, consistent api endpoints, and I see no
> downside.
> >> >>>> >> >
> >> >>>> >> >
> >> >>>> >> > Honestly, my hope is that someday they aren't uniquely
> >> identified and
> >> >>>> are
> >> >>>> >> > really sun objects unlike JPA today. But that is a longer
> >> >>>> conversation.
> >> >>>> >> >
> >> >>>> >> >>
> >> >>>> >> >> >
> >> >>>> >> >> >
> >> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> >>>> >> >> > <er...@gmail.com>wrote:
> >> >>>> >> >> >
> >> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets.
> I've
> >> >>>> added
> >> >>>> >> >> >> the interface and default implementation, and created /
> >> registered
> >> >>>> >> the
> >> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >> >>>> >> >> >>
> >> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
> matching
> >> >>>> request
> >> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
> >> Path:
> >> >>>> /1,
> >> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >>>> >> >> >>
> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
> >> >>>> >> >> >>
> >> >>>> >> >> >> Is there anything else I need to do in order to create and
> >> >>>> register a
> >> >>>> >> >> >> new endpoint?
> >> >>>> >> >> >>
> >> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >>>> >> >> >> <er...@gmail.com> wrote:
> >> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >> >>>> >> chris@cxtsoftware.com>
> >> >>>> >> >> >> wrote:
> >> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >>>> >> >> >> >>
> >> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> >>>> >> >> >> m.ben.franklin@gmail.com>
> >> >>>> >> >> >> >>> wrote:
> >> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >> >>>> >> >> chris@cxtsoftware.com>
> >> >>>> >> >> >> >>> wrote:
> >> >>>> >> >> >> >>> >
> >> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >>>> >> >> >> >>> >>
> >> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
> start
> >> >>>> >> implementing
> >> >>>> >> >> >> more
> >> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
> >> entire
> >> >>>> >> angular
> >> >>>> >> >> >> >>> >> > architecture.
> >> >>>> >> >> >> >>> >> >
> >> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
> apis
> >> in
> >> >>>> trunk
> >> >>>> >> >> are
> >> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
> >> much of
> >> >>>> >> the
> >> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
> rest
> >> api
> >> >>>> >> >> >> implementations
> >> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
> >> other
> >> >>>> >> >> >> documentation
> >> >>>> >> >> >> >>> >> > we can reference?
> >> >>>> >> >> >> >>> >> >
> >> >>>> >> >> >> >>> >>
> >> >>>> >> >> >> >>> >> I've been working on the People resource as a
> >> "reference"
> >> >>>> of
> >> >>>> >> how
> >> >>>> >> >> I'd
> >> >>>> >> >> >> >>> like
> >> >>>> >> >> >> >>> >> to see them done but it's still a work in
> progress. I
> >> need
> >> >>>> to
> >> >>>> >> go
> >> >>>> >> >> >> back
> >> >>>> >> >> >> >>> and
> >> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
> >> "fields"
> >> >>>> >> concept.
> >> >>>> >> >> >> >>> Couple of
> >> >>>> >> >> >> >>> >> notes:
> >> >>>> >> >> >> >>> >>
> >> >>>> >> >> >> >>> >>  - Object representations should be as flat as
> >> possible
> >> >>>> >> >> >> >>> >> and separate requests should be made to nested
> >> resources to
> >> >>>> >> get
> >> >>>> >> >> >> nested
> >> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >> >>>> regions/1/regionwidgets,
> >> >>>> >> >> the
> >> >>>> >> >> >> >>> regions
> >> >>>> >> >> >> >>> >> representation should not contain an array of
> >> >>>> regionwidgets)
> >> >>>> >> >> >> >>> >>
> >> >>>> >> >> >> >>> >
> >> >>>> >> >> >> >>> > I am concerned about the round trips to support this
> >> when
> >> >>>> >> >> rendering
> >> >>>> >> >> >> the
> >> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
> >> >>>> gadgets,
> >> >>>> >> >> adding
> >> >>>> >> >> >> to
> >> >>>> >> >> >> >>> the
> >> >>>> >> >> >> >>> > number of requests becomes problematic.
> >> >>>> >> >> >> >>> >
> >> >>>> >> >> >> >>>
> >> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
> >> endpoints for
> >> >>>> >> crud
> >> >>>> >> >> >> >>> operations on resources. We
> >> >>>> >>
> >> >>>>
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Mon, Jul 22, 2013 at 11:24 PM, Matt Franklin
<m....@gmail.com> wrote:
>
>
>> On Jul 22, 2013, at 15:39, Erin Noe-Payne <er...@gmail.com> wrote:
>>
>> The cxf interceptors model is very powerful though, because it lets us
>> reduce the weight of each controller significantly. Rather than
>> returning a Response, each controller can return an instance of the
>> object that it acts upon (Page or List<Page>, User or List<User> and
>> so on).
>>
>> We can have a series of interceptors that do any common tasks...
>> Incoming:
>> - On Post / Put responses check for correctly formed attached data,
>> and return a 400 with meaningful error message on bad format
>>
>> Outgoing:
>> - If response is null return 404 with meaningful error
>> - Field selector support
>> - Pagination for List<T> responses
>> - Wrapping of objects in the JsonResponseWrapper
>
> +1.  This seems like the cleanest approach and makes injecting new Apis much simpler.  Ie provider specific extension Apis

Quick question regarding performance, since I'm not up on how the Java
persistence layer / caching works. Which of these makes more sense:
- For paginated list results, run 1 query against the db to get all
results. I now have a list of all results, and the pagination
interceptor can operate that list to get the count, subset, and move
on.
- Run two queries, one to get only the paginated data set and one to
retrieve the count.

>
>>
>> On Mon, Jul 22, 2013 at 4:15 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>>> I would also point out that we don't have a pressing need to actually
>>> implement fields support. Our first use case - the angular client -
>>> does not particularly need it since we will be using a
>>> client-optimized "pagesForRender" endpoint anyway.
>>>
>>> As long as we ensure that our approach can be extended to support
>>> fields selection in the future without refactor, that should be good
>>> enough.
>>>
>>> On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
>>> <er...@gmail.com> wrote:
>>>> - Simple solution: All rest response models are flat. We ignore any
>>>> nested data, and just have separate endpoints to deliver that data.
>>>> I.E. Every model in the org.apache.rave.rest.model package has only
>>>> properties of "primitive" types, with no lists, no other classes. That
>>>> is NOT currently the case. Then the fields interceptor checks for the
>>>> presence of a fields argument. If not present, the object is delivered
>>>> as is. If present the argument (a string) is split by comma and only
>>>> the matched properties are delivered. The fields qs argument only has
>>>> to support comma-delimited list of property names.
>>>> Ex: ?fields=name,pageType
>>>> //returns a page or pages with only name and pageType properties
>>>>
>>>> - Complicated solution: All rest response models include references to
>>>> their nested data. This is the currently the case, and can be seen in
>>>> org.apache.rave.rest.model.Page. The fields interceptor checks for
>>>> presence of fields qs argument. If not present it strips all nested
>>>> data from the models and only returns properties. If it is present, it
>>>> parses the argument and updates the data. The fields argument needs to
>>>> support a more complicated syntax that allows the requesting of nested
>>>> data. I would copy the syntax of facebook's graph search api, which
>>>> has a pretty readable solution. You allow for .fields and .limit on
>>>> fields, which can be nested.
>>>> Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>>>> //returns a page or pages with name and pageType properties, nested
>>>> list of regions (max of 2) with nested list of regionWidgets with only
>>>> properties of widgetId and locked
>>>>
>>>> In all cases, id should always be returned.
>>>> I think the algorithm in the simple solution is easy.
>>>> In a sense the algorithm in the second should be simple, because the
>>>> service layer is already getting all the nested data, and you are just
>>>> stripping it off. Not sure what the performance implications of that
>>>> are though.
>>>>
>>>>> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>>>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>>>>> <er...@gmail.com>wrote:
>>>>>
>>>>>> Going back to the discussion on field selection - I am currently going
>>>>>> through the exercise of writing out the Resource interfaces to define
>>>>>> our endpoints.  There is a set of generic query string parameters that
>>>>>> we wish to support on all or many of the endpoints - fields (any get
>>>>>> request), limit / offset (any get request that returns a list).
>>>>>>
>>>>>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>>>>>> the appropriate logic, I assume we would want to take advantage of cxf
>>>>>> interceptors [1] to intelligently and generically handle those qs
>>>>>> arguments?
>>>>>
>>>>> I like the concept but I'm not sure how we generically filter, especially
>>>>> with nested data. I'd love to see it work that way though. Interceptors are
>>>>> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>>>>> Thoughts?
>>>>>
>>>>>>
>>>>>> [1] http://cxf.apache.org/docs/interceptors.html
>>>>>>
>>>>>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>>>>> <er...@gmail.com> wrote:
>>>>>>> Ok, so the endpoint is now working. Any thoughts about the
>>>>>>> JsonResponseWrapper approach? Does that seem like the best way to get
>>>>>>> wrapped responses?
>>>>>>>
>>>>>>> For the next step I would like to start writing out all of the
>>>>>>> resource interfaces so that we can begin writing angular $resource
>>>>>>> services against them.
>>>>>>>
>>>>>>> On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>>>>>> <er...@gmail.com> wrote:
>>>>>>>> Awesome, thanks Chris. Not sure I would have ever figured that one
>>>>>> out...
>>>>>>>>
>>>>>>>> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>>>>>> wrote:
>>>>>>>>> Erin,
>>>>>>>>>
>>>>>>>>> I got it working, at least the CXF part. Couple things:
>>>>>>>>>
>>>>>>>>> 1) In the interface, make sure to annotate the @GET methods
>>>>>>>>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>>>>>>>> attributes from variable signatures. I know Intellij puts those in
>>>>>> there
>>>>>>>>> but they cause problems. Only the interface should be annotated.
>>>>>>>>>
>>>>>>>>> Chris
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>
>>>>>>>>>> Review board is not accepting my patch and is not accepting the valid
>>>>>>>>>> file paths. I have attached the patch as a file to the review.
>>>>>>>>>>
>>>>>>>>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>>>>>> wrote:
>>>>>>>>>>> Erin, I'm not seeing a patch posted up there.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>>>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I was never able to hit the endpoint as expected. I've posted the
>>>>>>>>>>>> patch on the review board if anyone can take a look and offer
>>>>>> advice -
>>>>>>>>>>>> https://reviews.apache.org/r/12777/.
>>>>>>>>>>>>
>>>>>>>>>>>> Thanks
>>>>>>>>>>>>
>>>>>>>>>>>> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>>>>>>>
>>>>>>>>>> wrote:
>>>>>>>>>>>>>> On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>>>>> chris@cxtsoftware.com
>>>>>>>>>>>> <javascript:;>>
>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>> In the xml file you need to create the bean, then reference
>>>>>> it in
>>>>>>>>>> the
>>>>>>>>>>>>>>> server element near the top. Other than that...no, that
>>>>>> should be
>>>>>>>>>>>> all. I
>>>>>>>>>>>>>>> assume you set the Path attribute on the resource.
>>>>>>>>>>>>>> I did. I'm also messing around with the service injection,
>>>>>> which may
>>>>>>>>>>>>>> be the issue. Haven't gotten it to work yet though.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I thought we were going to do
>>>>>>>>>>>> pages/<id>/regions/<id>/regionwidgets/<id>
>>>>>>>>>>>>>>> since it makes no sense to manage a region widget outside a
>>>>>> region
>>>>>>>>>>>>>> outside
>>>>>>>>>>>>>>> a page?
>>>>>>>>>>>>>> Possibly. Right now I'm just trying to do a proof of concept
>>>>>> with
>>>>>>>>>> the
>>>>>>>>>>>>>> wrapped json object so I picked something simple with the
>>>>>> service and
>>>>>>>>>>>>>> rest models already in place.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> In general though I don't see any value to dealing with region
>>>>>>>>>> widgets
>>>>>>>>>>>>>> as a nested resource (pages/:id/regions/:id...) over just
>>>>>> dealing
>>>>>>>>>> with
>>>>>>>>>>>>>> them directly. It's just adding weight to the pages controller,
>>>>>>>>>> rather
>>>>>>>>>>>>>> than breaking them up and dealing with resource concerns
>>>>>> separately.
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> I get what you're saying about regions and regionwidgets only
>>>>>> making
>>>>>>>>>>>>>> sense in the context of a page, but you could say the same
>>>>>> thing for
>>>>>>>>>>>>>> any 1-many associated resource. Both entities are always
>>>>>> uniquely
>>>>>>>>>>>>>> identified, so why not deal with them individually? I see an
>>>>>> upside
>>>>>>>>>> of
>>>>>>>>>>>>>> simpler code, consistent api endpoints, and I see no downside.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Honestly, my hope is that someday they aren't uniquely
>>>>>> identified and
>>>>>>>>>> are
>>>>>>>>>>>>> really sun objects unlike JPA today. But that is a longer
>>>>>>>>>> conversation.
>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>>>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm trying to register a new endpoint for regionWidgets. I've
>>>>>>>>>> added
>>>>>>>>>>>>>>>> the interface and default implementation, and created /
>>>>>> registered
>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> bean in cxf-applicationContext.xml.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> However, when I hit the endpoint I get an error:
>>>>>>>>>>>>>>>> [INFO] [talledLocalContainer] WARN :
>>>>>>>>>>>>>>>> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>>>>>>>>> request
>>>>>>>>>>>>>>>> path "/portal/api/rest/regionWidgets/1" is found, Relative
>>>>>> Path:
>>>>>>>>>> /1,
>>>>>>>>>>>>>>>> HTTP Method: GET, ContentType: */*, Accept:
>>>>>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>>>>>>>>>>>>>>> Please enable FINE/TRACE log level for more details.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Is there anything else I need to do in order to create and
>>>>>>>>>> register a
>>>>>>>>>>>>>>>> new endpoint?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>>>>>>>>>>>>>>> <er...@gmail.com> wrote:
>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>>>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>>>>>>>>>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>>>>>>>>>>>>>>> m.ben.franklin@gmail.com>
>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>>>>>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>>>>>>>>>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> Any further discussion here? I would like to start
>>>>>>>>>>>> implementing
>>>>>>>>>>>>>>>> more
>>>>>>>>>>>>>>>>>>>>>> of the REST APIs, as it is foundational for the
>>>>>> entire
>>>>>>>>>>>> angular
>>>>>>>>>>>>>>>>>>>>>> architecture.
>>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>>> My understanding from Matt is that the current apis
>>>>>> in
>>>>>>>>>> trunk
>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>>>>>> mostly proof of concept - they are not tested and
>>>>>> much of
>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>>> functionality is just stubbed. Are any of the rest
>>>>>> api
>>>>>>>>>>>>>>>> implementations
>>>>>>>>>>>>>>>>>>>>>> in the code base a good working example? Is there
>>>>>> other
>>>>>>>>>>>>>>>> documentation
>>>>>>>>>>>>>>>>>>>>>> we can reference?
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> I've been working on the People resource as a
>>>>>> "reference"
>>>>>>>>>> of
>>>>>>>>>>>> how
>>>>>>>>>>>>>> I'd
>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>>> to see them done but it's still a work in progress. I
>>>>>> need
>>>>>>>>>> to
>>>>>>>>>>>> go
>>>>>>>>>>>>>>>> back
>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>>> pull out the JSONView stuff and reimplement the
>>>>>> "fields"
>>>>>>>>>>>> concept.
>>>>>>>>>>>>>>>>>>> Couple of
>>>>>>>>>>>>>>>>>>>>> notes:
>>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>> - Object representations should be as flat as
>>>>>> possible
>>>>>>>>>>>>>>>>>>>>> and separate requests should be made to nested
>>>>>> resources to
>>>>>>>>>>>> get
>>>>>>>>>>>>>>>> nested
>>>>>>>>>>>>>>>>>>>>> details (i.e. if you have regions and
>>>>>>>>>> regions/1/regionwidgets,
>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> regions
>>>>>>>>>>>>>>>>>>>>> representation should not contain an array of
>>>>>>>>>> regionwidgets)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I am concerned about the round trips to support this
>>>>>> when
>>>>>>>>>>>>>> rendering
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> page.  With any page that has a sufficient number of
>>>>>>>>>> gadgets,
>>>>>>>>>>>>>> adding
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> number of requests becomes problematic.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I see that rule applying to the "standard" rest
>>>>>> endpoints for
>>>>>>>>>>>> crud
>>>>>>>>>>>>>>>>>>> operations on resources. We
>>>>>>

Re: [Proposal] REST API interface

Posted by Matt Franklin <m....@gmail.com>.

> On Jul 22, 2013, at 15:39, Erin Noe-Payne <er...@gmail.com> wrote:
> 
> The cxf interceptors model is very powerful though, because it lets us
> reduce the weight of each controller significantly. Rather than
> returning a Response, each controller can return an instance of the
> object that it acts upon (Page or List<Page>, User or List<User> and
> so on).
> 
> We can have a series of interceptors that do any common tasks...
> Incoming:
> - On Post / Put responses check for correctly formed attached data,
> and return a 400 with meaningful error message on bad format
> 
> Outgoing:
> - If response is null return 404 with meaningful error
> - Field selector support
> - Pagination for List<T> responses
> - Wrapping of objects in the JsonResponseWrapper

+1.  This seems like the cleanest approach and makes injecting new Apis much simpler.  Ie provider specific extension Apis

> 
> On Mon, Jul 22, 2013 at 4:15 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
>> I would also point out that we don't have a pressing need to actually
>> implement fields support. Our first use case - the angular client -
>> does not particularly need it since we will be using a
>> client-optimized "pagesForRender" endpoint anyway.
>> 
>> As long as we ensure that our approach can be extended to support
>> fields selection in the future without refactor, that should be good
>> enough.
>> 
>> On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>>> - Simple solution: All rest response models are flat. We ignore any
>>> nested data, and just have separate endpoints to deliver that data.
>>> I.E. Every model in the org.apache.rave.rest.model package has only
>>> properties of "primitive" types, with no lists, no other classes. That
>>> is NOT currently the case. Then the fields interceptor checks for the
>>> presence of a fields argument. If not present, the object is delivered
>>> as is. If present the argument (a string) is split by comma and only
>>> the matched properties are delivered. The fields qs argument only has
>>> to support comma-delimited list of property names.
>>> Ex: ?fields=name,pageType
>>> //returns a page or pages with only name and pageType properties
>>> 
>>> - Complicated solution: All rest response models include references to
>>> their nested data. This is the currently the case, and can be seen in
>>> org.apache.rave.rest.model.Page. The fields interceptor checks for
>>> presence of fields qs argument. If not present it strips all nested
>>> data from the models and only returns properties. If it is present, it
>>> parses the argument and updates the data. The fields argument needs to
>>> support a more complicated syntax that allows the requesting of nested
>>> data. I would copy the syntax of facebook's graph search api, which
>>> has a pretty readable solution. You allow for .fields and .limit on
>>> fields, which can be nested.
>>> Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>>> //returns a page or pages with name and pageType properties, nested
>>> list of regions (max of 2) with nested list of regionWidgets with only
>>> properties of widgetId and locked
>>> 
>>> In all cases, id should always be returned.
>>> I think the algorithm in the simple solution is easy.
>>> In a sense the algorithm in the second should be simple, because the
>>> service layer is already getting all the nested data, and you are just
>>> stripping it off. Not sure what the performance implications of that
>>> are though.
>>> 
>>>> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>>>> <er...@gmail.com>wrote:
>>>> 
>>>>> Going back to the discussion on field selection - I am currently going
>>>>> through the exercise of writing out the Resource interfaces to define
>>>>> our endpoints.  There is a set of generic query string parameters that
>>>>> we wish to support on all or many of the endpoints - fields (any get
>>>>> request), limit / offset (any get request that returns a list).
>>>>> 
>>>>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>>>>> the appropriate logic, I assume we would want to take advantage of cxf
>>>>> interceptors [1] to intelligently and generically handle those qs
>>>>> arguments?
>>>> 
>>>> I like the concept but I'm not sure how we generically filter, especially
>>>> with nested data. I'd love to see it work that way though. Interceptors are
>>>> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>>>> Thoughts?
>>>> 
>>>>> 
>>>>> [1] http://cxf.apache.org/docs/interceptors.html
>>>>> 
>>>>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>>>> <er...@gmail.com> wrote:
>>>>>> Ok, so the endpoint is now working. Any thoughts about the
>>>>>> JsonResponseWrapper approach? Does that seem like the best way to get
>>>>>> wrapped responses?
>>>>>> 
>>>>>> For the next step I would like to start writing out all of the
>>>>>> resource interfaces so that we can begin writing angular $resource
>>>>>> services against them.
>>>>>> 
>>>>>> On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>>>>> <er...@gmail.com> wrote:
>>>>>>> Awesome, thanks Chris. Not sure I would have ever figured that one
>>>>> out...
>>>>>>> 
>>>>>>> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>>>>> wrote:
>>>>>>>> Erin,
>>>>>>>> 
>>>>>>>> I got it working, at least the CXF part. Couple things:
>>>>>>>> 
>>>>>>>> 1) In the interface, make sure to annotate the @GET methods
>>>>>>>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>>>>>>> attributes from variable signatures. I know Intellij puts those in
>>>>> there
>>>>>>>> but they cause problems. Only the interface should be annotated.
>>>>>>>> 
>>>>>>>> Chris
>>>>>>>> 
>>>>>>>> 
>>>>>>>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>> 
>>>>>>>>> Review board is not accepting my patch and is not accepting the valid
>>>>>>>>> file paths. I have attached the patch as a file to the review.
>>>>>>>>> 
>>>>>>>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>>>>> wrote:
>>>>>>>>>> Erin, I'm not seeing a patch posted up there.
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>> 
>>>>>>>>>>> I was never able to hit the endpoint as expected. I've posted the
>>>>>>>>>>> patch on the review board if anyone can take a look and offer
>>>>> advice -
>>>>>>>>>>> https://reviews.apache.org/r/12777/.
>>>>>>>>>>> 
>>>>>>>>>>> Thanks
>>>>>>>>>>> 
>>>>>>>>>>> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>>>>>> 
>>>>>>>>> wrote:
>>>>>>>>>>>>> On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>>>>>>>>>>>> 
>>>>>>>>>>>>> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>>>> chris@cxtsoftware.com
>>>>>>>>>>> <javascript:;>>
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>> In the xml file you need to create the bean, then reference
>>>>> it in
>>>>>>>>> the
>>>>>>>>>>>>>> server element near the top. Other than that...no, that
>>>>> should be
>>>>>>>>>>> all. I
>>>>>>>>>>>>>> assume you set the Path attribute on the resource.
>>>>>>>>>>>>> I did. I'm also messing around with the service injection,
>>>>> which may
>>>>>>>>>>>>> be the issue. Haven't gotten it to work yet though.
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> I thought we were going to do
>>>>>>>>>>> pages/<id>/regions/<id>/regionwidgets/<id>
>>>>>>>>>>>>>> since it makes no sense to manage a region widget outside a
>>>>> region
>>>>>>>>>>>>> outside
>>>>>>>>>>>>>> a page?
>>>>>>>>>>>>> Possibly. Right now I'm just trying to do a proof of concept
>>>>> with
>>>>>>>>> the
>>>>>>>>>>>>> wrapped json object so I picked something simple with the
>>>>> service and
>>>>>>>>>>>>> rest models already in place.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> In general though I don't see any value to dealing with region
>>>>>>>>> widgets
>>>>>>>>>>>>> as a nested resource (pages/:id/regions/:id...) over just
>>>>> dealing
>>>>>>>>> with
>>>>>>>>>>>>> them directly. It's just adding weight to the pages controller,
>>>>>>>>> rather
>>>>>>>>>>>>> than breaking them up and dealing with resource concerns
>>>>> separately.
>>>>>>>>>>>>> 
>>>>>>>>>>>>> I get what you're saying about regions and regionwidgets only
>>>>> making
>>>>>>>>>>>>> sense in the context of a page, but you could say the same
>>>>> thing for
>>>>>>>>>>>>> any 1-many associated resource. Both entities are always
>>>>> uniquely
>>>>>>>>>>>>> identified, so why not deal with them individually? I see an
>>>>> upside
>>>>>>>>> of
>>>>>>>>>>>>> simpler code, consistent api endpoints, and I see no downside.
>>>>>>>>>>>> 
>>>>>>>>>>>> 
>>>>>>>>>>>> Honestly, my hope is that someday they aren't uniquely
>>>>> identified and
>>>>>>>>> are
>>>>>>>>>>>> really sun objects unlike JPA today. But that is a longer
>>>>>>>>> conversation.
>>>>>>>>>>>> 
>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>> On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> I'm trying to register a new endpoint for regionWidgets. I've
>>>>>>>>> added
>>>>>>>>>>>>>>> the interface and default implementation, and created /
>>>>> registered
>>>>>>>>>>> the
>>>>>>>>>>>>>>> bean in cxf-applicationContext.xml.
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> However, when I hit the endpoint I get an error:
>>>>>>>>>>>>>>> [INFO] [talledLocalContainer] WARN :
>>>>>>>>>>>>>>> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>>>>>>>> request
>>>>>>>>>>>>>>> path "/portal/api/rest/regionWidgets/1" is found, Relative
>>>>> Path:
>>>>>>>>> /1,
>>>>>>>>>>>>>>> HTTP Method: GET, ContentType: */*, Accept:
>>>>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>>>>>>>>>>>>>> Please enable FINE/TRACE log level for more details.
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> Is there anything else I need to do in order to create and
>>>>>>>>> register a
>>>>>>>>>>>>>>> new endpoint?
>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>>>>>>>>>>>>>> <er...@gmail.com> wrote:
>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>>>>>>>>>>>>>> erin.noe.payne@gmail.com>wrote:
>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>>>>>>>>>>>>>> m.ben.franklin@gmail.com>
>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>>>>>>>>>>>> chris@cxtsoftware.com>
>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>>>>>>>>>>>>>>>>>>> <er...@gmail.com>wrote:
>>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>>> Any further discussion here? I would like to start
>>>>>>>>>>> implementing
>>>>>>>>>>>>>>> more
>>>>>>>>>>>>>>>>>>>>> of the REST APIs, as it is foundational for the
>>>>> entire
>>>>>>>>>>> angular
>>>>>>>>>>>>>>>>>>>>> architecture.
>>>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>>> My understanding from Matt is that the current apis
>>>>> in
>>>>>>>>> trunk
>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>>>>> mostly proof of concept - they are not tested and
>>>>> much of
>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>>> functionality is just stubbed. Are any of the rest
>>>>> api
>>>>>>>>>>>>>>> implementations
>>>>>>>>>>>>>>>>>>>>> in the code base a good working example? Is there
>>>>> other
>>>>>>>>>>>>>>> documentation
>>>>>>>>>>>>>>>>>>>>> we can reference?
>>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>> I've been working on the People resource as a
>>>>> "reference"
>>>>>>>>> of
>>>>>>>>>>> how
>>>>>>>>>>>>> I'd
>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>> to see them done but it's still a work in progress. I
>>>>> need
>>>>>>>>> to
>>>>>>>>>>> go
>>>>>>>>>>>>>>> back
>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> pull out the JSONView stuff and reimplement the
>>>>> "fields"
>>>>>>>>>>> concept.
>>>>>>>>>>>>>>>>>> Couple of
>>>>>>>>>>>>>>>>>>>> notes:
>>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>>> - Object representations should be as flat as
>>>>> possible
>>>>>>>>>>>>>>>>>>>> and separate requests should be made to nested
>>>>> resources to
>>>>>>>>>>> get
>>>>>>>>>>>>>>> nested
>>>>>>>>>>>>>>>>>>>> details (i.e. if you have regions and
>>>>>>>>> regions/1/regionwidgets,
>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> regions
>>>>>>>>>>>>>>>>>>>> representation should not contain an array of
>>>>>>>>> regionwidgets)
>>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>>> I am concerned about the round trips to support this
>>>>> when
>>>>>>>>>>>>> rendering
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> page.  With any page that has a sufficient number of
>>>>>>>>> gadgets,
>>>>>>>>>>>>> adding
>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> number of requests becomes problematic.
>>>>>>>>>>>>>>>>>> 
>>>>>>>>>>>>>>>>>> I see that rule applying to the "standard" rest
>>>>> endpoints for
>>>>>>>>>>> crud
>>>>>>>>>>>>>>>>>> operations on resources. We
>>>>> 

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
The cxf interceptors model is very powerful though, because it lets us
reduce the weight of each controller significantly. Rather than
returning a Response, each controller can return an instance of the
object that it acts upon (Page or List<Page>, User or List<User> and
so on).

We can have a series of interceptors that do any common tasks...
Incoming:
- On Post / Put responses check for correctly formed attached data,
and return a 400 with meaningful error message on bad format

Outgoing:
- If response is null return 404 with meaningful error
- Field selector support
- Pagination for List<T> responses
- Wrapping of objects in the JsonResponseWrapper

On Mon, Jul 22, 2013 at 4:15 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> I would also point out that we don't have a pressing need to actually
> implement fields support. Our first use case - the angular client -
> does not particularly need it since we will be using a
> client-optimized "pagesForRender" endpoint anyway.
>
> As long as we ensure that our approach can be extended to support
> fields selection in the future without refactor, that should be good
> enough.
>
> On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
>> - Simple solution: All rest response models are flat. We ignore any
>> nested data, and just have separate endpoints to deliver that data.
>> I.E. Every model in the org.apache.rave.rest.model package has only
>> properties of "primitive" types, with no lists, no other classes. That
>> is NOT currently the case. Then the fields interceptor checks for the
>> presence of a fields argument. If not present, the object is delivered
>> as is. If present the argument (a string) is split by comma and only
>> the matched properties are delivered. The fields qs argument only has
>> to support comma-delimited list of property names.
>> Ex: ?fields=name,pageType
>> //returns a page or pages with only name and pageType properties
>>
>> - Complicated solution: All rest response models include references to
>> their nested data. This is the currently the case, and can be seen in
>> org.apache.rave.rest.model.Page. The fields interceptor checks for
>> presence of fields qs argument. If not present it strips all nested
>> data from the models and only returns properties. If it is present, it
>> parses the argument and updates the data. The fields argument needs to
>> support a more complicated syntax that allows the requesting of nested
>> data. I would copy the syntax of facebook's graph search api, which
>> has a pretty readable solution. You allow for .fields and .limit on
>> fields, which can be nested.
>> Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> //returns a page or pages with name and pageType properties, nested
>> list of regions (max of 2) with nested list of regionWidgets with only
>> properties of widgetId and locked
>>
>> In all cases, id should always be returned.
>> I think the algorithm in the simple solution is easy.
>> In a sense the algorithm in the second should be simple, because the
>> service layer is already getting all the nested data, and you are just
>> stripping it off. Not sure what the performance implications of that
>> are though.
>>
>> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>>> <er...@gmail.com>wrote:
>>>
>>>> Going back to the discussion on field selection - I am currently going
>>>> through the exercise of writing out the Resource interfaces to define
>>>> our endpoints.  There is a set of generic query string parameters that
>>>> we wish to support on all or many of the endpoints - fields (any get
>>>> request), limit / offset (any get request that returns a list).
>>>>
>>>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>>>> the appropriate logic, I assume we would want to take advantage of cxf
>>>> interceptors [1] to intelligently and generically handle those qs
>>>> arguments?
>>>>
>>>
>>> I like the concept but I'm not sure how we generically filter, especially
>>> with nested data. I'd love to see it work that way though. Interceptors are
>>> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>>> Thoughts?
>>>
>>>>
>>>> [1] http://cxf.apache.org/docs/interceptors.html
>>>>
>>>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>>> <er...@gmail.com> wrote:
>>>> > Ok, so the endpoint is now working. Any thoughts about the
>>>> > JsonResponseWrapper approach? Does that seem like the best way to get
>>>> > wrapped responses?
>>>> >
>>>> > For the next step I would like to start writing out all of the
>>>> > resource interfaces so that we can begin writing angular $resource
>>>> > services against them.
>>>> >
>>>> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>>> > <er...@gmail.com> wrote:
>>>> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>>>> out...
>>>> >>
>>>> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>>>> wrote:
>>>> >>> Erin,
>>>> >>>
>>>> >>> I got it working, at least the CXF part. Couple things:
>>>> >>>
>>>> >>> 1) In the interface, make sure to annotate the @GET methods
>>>> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>>> >>> attributes from variable signatures. I know Intellij puts those in
>>>> there
>>>> >>> but they cause problems. Only the interface should be annotated.
>>>> >>>
>>>> >>> Chris
>>>> >>>
>>>> >>>
>>>> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>>> erin.noe.payne@gmail.com>wrote:
>>>> >>>
>>>> >>>> Review board is not accepting my patch and is not accepting the valid
>>>> >>>> file paths. I have attached the patch as a file to the review.
>>>> >>>>
>>>> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>>>> wrote:
>>>> >>>> > Erin, I'm not seeing a patch posted up there.
>>>> >>>> >
>>>> >>>> >
>>>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>>> >>>> erin.noe.payne@gmail.com>wrote:
>>>> >>>> >
>>>> >>>> >> I was never able to hit the endpoint as expected. I've posted the
>>>> >>>> >> patch on the review board if anyone can take a look and offer
>>>> advice -
>>>> >>>> >> https://reviews.apache.org/r/12777/.
>>>> >>>> >>
>>>> >>>> >> Thanks
>>>> >>>> >>
>>>> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>>>> >
>>>> >>>> wrote:
>>>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>>> >>>> >> >
>>>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>>> chris@cxtsoftware.com
>>>> >>>> >> <javascript:;>>
>>>> >>>> >> >> wrote:
>>>> >>>> >> >> > In the xml file you need to create the bean, then reference
>>>> it in
>>>> >>>> the
>>>> >>>> >> >> > server element near the top. Other than that...no, that
>>>> should be
>>>> >>>> >> all. I
>>>> >>>> >> >> > assume you set the Path attribute on the resource.
>>>> >>>> >> >> >
>>>> >>>> >> >> I did. I'm also messing around with the service injection,
>>>> which may
>>>> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>>>> >>>> >> >>
>>>> >>>> >> >> > I thought we were going to do
>>>> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>>> >>>> >> >> > since it makes no sense to manage a region widget outside a
>>>> region
>>>> >>>> >> >> outside
>>>> >>>> >> >> > a page?
>>>> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
>>>> with
>>>> >>>> the
>>>> >>>> >> >> wrapped json object so I picked something simple with the
>>>> service and
>>>> >>>> >> >> rest models already in place.
>>>> >>>> >> >>
>>>> >>>> >> >> In general though I don't see any value to dealing with region
>>>> >>>> widgets
>>>> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>>>> dealing
>>>> >>>> with
>>>> >>>> >> >> them directly. It's just adding weight to the pages controller,
>>>> >>>> rather
>>>> >>>> >> >> than breaking them up and dealing with resource concerns
>>>> separately.
>>>> >>>> >> >>
>>>> >>>> >> >> I get what you're saying about regions and regionwidgets only
>>>> making
>>>> >>>> >> >> sense in the context of a page, but you could say the same
>>>> thing for
>>>> >>>> >> >> any 1-many associated resource. Both entities are always
>>>> uniquely
>>>> >>>> >> >> identified, so why not deal with them individually? I see an
>>>> upside
>>>> >>>> of
>>>> >>>> >> >> simpler code, consistent api endpoints, and I see no downside.
>>>> >>>> >> >
>>>> >>>> >> >
>>>> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>>>> identified and
>>>> >>>> are
>>>> >>>> >> > really sun objects unlike JPA today. But that is a longer
>>>> >>>> conversation.
>>>> >>>> >> >
>>>> >>>> >> >>
>>>> >>>> >> >> >
>>>> >>>> >> >> >
>>>> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>>> >>>> >> >> > <er...@gmail.com>wrote:
>>>> >>>> >> >> >
>>>> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>>>> >>>> added
>>>> >>>> >> >> >> the interface and default implementation, and created /
>>>> registered
>>>> >>>> >> the
>>>> >>>> >> >> >> bean in cxf-applicationContext.xml.
>>>> >>>> >> >> >>
>>>> >>>> >> >> >> However, when I hit the endpoint I get an error:
>>>> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>>> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>>> >>>> request
>>>> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
>>>> Path:
>>>> >>>> /1,
>>>> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>>>> >>>> >> >> >>
>>>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>>> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>>>> >>>> >> >> >>
>>>> >>>> >> >> >> Is there anything else I need to do in order to create and
>>>> >>>> register a
>>>> >>>> >> >> >> new endpoint?
>>>> >>>> >> >> >>
>>>> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>>> >>>> >> >> >> <er...@gmail.com> wrote:
>>>> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>>> >>>> >> chris@cxtsoftware.com>
>>>> >>>> >> >> >> wrote:
>>>> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>>> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>>> >>>> >> >> >> >>
>>>> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>>> >>>> >> >> >> m.ben.franklin@gmail.com>
>>>> >>>> >> >> >> >>> wrote:
>>>> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>>> >>>> >> >> chris@cxtsoftware.com>
>>>> >>>> >> >> >> >>> wrote:
>>>> >>>> >> >> >> >>> >
>>>> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>>> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>>> >>>> >> >> >> >>> >>
>>>> >>>> >> >> >> >>> >> > Any further discussion here? I would like to start
>>>> >>>> >> implementing
>>>> >>>> >> >> >> more
>>>> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
>>>> entire
>>>> >>>> >> angular
>>>> >>>> >> >> >> >>> >> > architecture.
>>>> >>>> >> >> >> >>> >> >
>>>> >>>> >> >> >> >>> >> > My understanding from Matt is that the current apis
>>>> in
>>>> >>>> trunk
>>>> >>>> >> >> are
>>>> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
>>>> much of
>>>> >>>> >> the
>>>> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest
>>>> api
>>>> >>>> >> >> >> implementations
>>>> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
>>>> other
>>>> >>>> >> >> >> documentation
>>>> >>>> >> >> >> >>> >> > we can reference?
>>>> >>>> >> >> >> >>> >> >
>>>> >>>> >> >> >> >>> >>
>>>> >>>> >> >> >> >>> >> I've been working on the People resource as a
>>>> "reference"
>>>> >>>> of
>>>> >>>> >> how
>>>> >>>> >> >> I'd
>>>> >>>> >> >> >> >>> like
>>>> >>>> >> >> >> >>> >> to see them done but it's still a work in progress. I
>>>> need
>>>> >>>> to
>>>> >>>> >> go
>>>> >>>> >> >> >> back
>>>> >>>> >> >> >> >>> and
>>>> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>>>> "fields"
>>>> >>>> >> concept.
>>>> >>>> >> >> >> >>> Couple of
>>>> >>>> >> >> >> >>> >> notes:
>>>> >>>> >> >> >> >>> >>
>>>> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>>>> possible
>>>> >>>> >> >> >> >>> >> and separate requests should be made to nested
>>>> resources to
>>>> >>>> >> get
>>>> >>>> >> >> >> nested
>>>> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>>>> >>>> regions/1/regionwidgets,
>>>> >>>> >> >> the
>>>> >>>> >> >> >> >>> regions
>>>> >>>> >> >> >> >>> >> representation should not contain an array of
>>>> >>>> regionwidgets)
>>>> >>>> >> >> >> >>> >>
>>>> >>>> >> >> >> >>> >
>>>> >>>> >> >> >> >>> > I am concerned about the round trips to support this
>>>> when
>>>> >>>> >> >> rendering
>>>> >>>> >> >> >> the
>>>> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>>>> >>>> gadgets,
>>>> >>>> >> >> adding
>>>> >>>> >> >> >> to
>>>> >>>> >> >> >> >>> the
>>>> >>>> >> >> >> >>> > number of requests becomes problematic.
>>>> >>>> >> >> >> >>> >
>>>> >>>> >> >> >> >>>
>>>> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>>>> endpoints for
>>>> >>>> >> crud
>>>> >>>> >> >> >> >>> operations on resources. We
>>>> >>>> >>
>>>> >>>>
>>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Mon, Jul 22, 2013 at 11:50 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Mon, Jul 22, 2013 at 1:15 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> I would also point out that we don't have a pressing need to actually
>> implement fields support. Our first use case - the angular client -
>> does not particularly need it since we will be using a
>> client-optimized "pagesForRender" endpoint anyway.
>>
>
> My only argument with this is on People. Right now you always get the full
> person record. I really think when you are searching for people you should
> get limited data (like facebook) and only see more detailed information
> when they are actually friends (and probably never see some data).
>

I would agree but that's not about supporting field selection through
the query string, thats about a more robust roles / permissions model
that has property granularity.

>>
>> As long as we ensure that our approach can be extended to support
>> fields selection in the future without refactor, that should be good
>> enough.
>>
>> On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > - Simple solution: All rest response models are flat. We ignore any
>> > nested data, and just have separate endpoints to deliver that data.
>> > I.E. Every model in the org.apache.rave.rest.model package has only
>> > properties of "primitive" types, with no lists, no other classes. That
>> > is NOT currently the case. Then the fields interceptor checks for the
>> > presence of a fields argument. If not present, the object is delivered
>> > as is. If present the argument (a string) is split by comma and only
>> > the matched properties are delivered. The fields qs argument only has
>> > to support comma-delimited list of property names.
>> > Ex: ?fields=name,pageType
>> > //returns a page or pages with only name and pageType properties
>> >
>> > - Complicated solution: All rest response models include references to
>> > their nested data. This is the currently the case, and can be seen in
>> > org.apache.rave.rest.model.Page. The fields interceptor checks for
>> > presence of fields qs argument. If not present it strips all nested
>> > data from the models and only returns properties. If it is present, it
>> > parses the argument and updates the data. The fields argument needs to
>> > support a more complicated syntax that allows the requesting of nested
>> > data. I would copy the syntax of facebook's graph search api, which
>> > has a pretty readable solution. You allow for .fields and .limit on
>> > fields, which can be nested.
>> > Ex:
>> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
>> > //returns a page or pages with name and pageType properties, nested
>> > list of regions (max of 2) with nested list of regionWidgets with only
>> > properties of widgetId and locked
>> >
>> > In all cases, id should always be returned.
>> > I think the algorithm in the simple solution is easy.
>> > In a sense the algorithm in the second should be simple, because the
>> > service layer is already getting all the nested data, and you are just
>> > stripping it off. Not sure what the performance implications of that
>> > are though.
>> >
>> > On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> >> <er...@gmail.com>wrote:
>> >>
>> >>> Going back to the discussion on field selection - I am currently going
>> >>> through the exercise of writing out the Resource interfaces to define
>> >>> our endpoints.  There is a set of generic query string parameters that
>> >>> we wish to support on all or many of the endpoints - fields (any get
>> >>> request), limit / offset (any get request that returns a list).
>> >>>
>> >>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>> >>> the appropriate logic, I assume we would want to take advantage of cxf
>> >>> interceptors [1] to intelligently and generically handle those qs
>> >>> arguments?
>> >>>
>> >>
>> >> I like the concept but I'm not sure how we generically filter,
>> especially
>> >> with nested data. I'd love to see it work that way though. Interceptors
>> are
>> >> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>> >> Thoughts?
>> >>
>> >>>
>> >>> [1] http://cxf.apache.org/docs/interceptors.html
>> >>>
>> >>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> >>> <er...@gmail.com> wrote:
>> >>> > Ok, so the endpoint is now working. Any thoughts about the
>> >>> > JsonResponseWrapper approach? Does that seem like the best way to get
>> >>> > wrapped responses?
>> >>> >
>> >>> > For the next step I would like to start writing out all of the
>> >>> > resource interfaces so that we can begin writing angular $resource
>> >>> > services against them.
>> >>> >
>> >>> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> >>> > <er...@gmail.com> wrote:
>> >>> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>> >>> out...
>> >>> >>
>> >>> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>> >>> wrote:
>> >>> >>> Erin,
>> >>> >>>
>> >>> >>> I got it working, at least the CXF part. Couple things:
>> >>> >>>
>> >>> >>> 1) In the interface, make sure to annotate the @GET methods
>> >>> >>> 2) In your DefaultRegionWidgetsResource class, remove the
>> @ParamPath
>> >>> >>> attributes from variable signatures. I know Intellij puts those in
>> >>> there
>> >>> >>> but they cause problems. Only the interface should be annotated.
>> >>> >>>
>> >>> >>> Chris
>> >>> >>>
>> >>> >>>
>> >>> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> >>> erin.noe.payne@gmail.com>wrote:
>> >>> >>>
>> >>> >>>> Review board is not accepting my patch and is not accepting the
>> valid
>> >>> >>>> file paths. I have attached the patch as a file to the review.
>> >>> >>>>
>> >>> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >>> wrote:
>> >>> >>>> > Erin, I'm not seeing a patch posted up there.
>> >>> >>>> >
>> >>> >>>> >
>> >>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >>> >>>> erin.noe.payne@gmail.com>wrote:
>> >>> >>>> >
>> >>> >>>> >> I was never able to hit the endpoint as expected. I've posted
>> the
>> >>> >>>> >> patch on the review board if anyone can take a look and offer
>> >>> advice -
>> >>> >>>> >> https://reviews.apache.org/r/12777/.
>> >>> >>>> >>
>> >>> >>>> >> Thanks
>> >>> >>>> >>
>> >>> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >>> >
>> >>> >>>> wrote:
>> >>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >>> >>>> >> >
>> >>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> >>> chris@cxtsoftware.com
>> >>> >>>> >> <javascript:;>>
>> >>> >>>> >> >> wrote:
>> >>> >>>> >> >> > In the xml file you need to create the bean, then
>> reference
>> >>> it in
>> >>> >>>> the
>> >>> >>>> >> >> > server element near the top. Other than that...no, that
>> >>> should be
>> >>> >>>> >> all. I
>> >>> >>>> >> >> > assume you set the Path attribute on the resource.
>> >>> >>>> >> >> >
>> >>> >>>> >> >> I did. I'm also messing around with the service injection,
>> >>> which may
>> >>> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >>> >>>> >> >>
>> >>> >>>> >> >> > I thought we were going to do
>> >>> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >>> >>>> >> >> > since it makes no sense to manage a region widget outside
>> a
>> >>> region
>> >>> >>>> >> >> outside
>> >>> >>>> >> >> > a page?
>> >>> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
>> concept
>> >>> with
>> >>> >>>> the
>> >>> >>>> >> >> wrapped json object so I picked something simple with the
>> >>> service and
>> >>> >>>> >> >> rest models already in place.
>> >>> >>>> >> >>
>> >>> >>>> >> >> In general though I don't see any value to dealing with
>> region
>> >>> >>>> widgets
>> >>> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>> >>> dealing
>> >>> >>>> with
>> >>> >>>> >> >> them directly. It's just adding weight to the pages
>> controller,
>> >>> >>>> rather
>> >>> >>>> >> >> than breaking them up and dealing with resource concerns
>> >>> separately.
>> >>> >>>> >> >>
>> >>> >>>> >> >> I get what you're saying about regions and regionwidgets
>> only
>> >>> making
>> >>> >>>> >> >> sense in the context of a page, but you could say the same
>> >>> thing for
>> >>> >>>> >> >> any 1-many associated resource. Both entities are always
>> >>> uniquely
>> >>> >>>> >> >> identified, so why not deal with them individually? I see an
>> >>> upside
>> >>> >>>> of
>> >>> >>>> >> >> simpler code, consistent api endpoints, and I see no
>> downside.
>> >>> >>>> >> >
>> >>> >>>> >> >
>> >>> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>> >>> identified and
>> >>> >>>> are
>> >>> >>>> >> > really sun objects unlike JPA today. But that is a longer
>> >>> >>>> conversation.
>> >>> >>>> >> >
>> >>> >>>> >> >>
>> >>> >>>> >> >> >
>> >>> >>>> >> >> >
>> >>> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >>> >>>> >> >> > <er...@gmail.com>wrote:
>> >>> >>>> >> >> >
>> >>> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets.
>> I've
>> >>> >>>> added
>> >>> >>>> >> >> >> the interface and default implementation, and created /
>> >>> registered
>> >>> >>>> >> the
>> >>> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >>> >>>> >> >> >>
>> >>> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >>> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >>> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
>> matching
>> >>> >>>> request
>> >>> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
>> Relative
>> >>> Path:
>> >>> >>>> /1,
>> >>> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >>> >>>> >> >> >>
>> >>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >>> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >>> >>>> >> >> >>
>> >>> >>>> >> >> >> Is there anything else I need to do in order to create
>> and
>> >>> >>>> register a
>> >>> >>>> >> >> >> new endpoint?
>> >>> >>>> >> >> >>
>> >>> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >>> >>>> >> >> >> <er...@gmail.com> wrote:
>> >>> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >>> >>>> >> chris@cxtsoftware.com>
>> >>> >>>> >> >> >> wrote:
>> >>> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >>> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>> >>>> >> >> >> >>
>> >>> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >>> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >>> >>>> >> >> >> >>> wrote:
>> >>> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >>> >>>> >> >> chris@cxtsoftware.com>
>> >>> >>>> >> >> >> >>> wrote:
>> >>> >>>> >> >> >> >>> >
>> >>> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >>> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >>> >>>> >> >> >> >>> >>
>> >>> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
>> start
>> >>> >>>> >> implementing
>> >>> >>>> >> >> >> more
>> >>> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
>> >>> entire
>> >>> >>>> >> angular
>> >>> >>>> >> >> >> >>> >> > architecture.
>> >>> >>>> >> >> >> >>> >> >
>> >>> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
>> apis
>> >>> in
>> >>> >>>> trunk
>> >>> >>>> >> >> are
>> >>> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested
>> and
>> >>> much of
>> >>> >>>> >> the
>> >>> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
>> rest
>> >>> api
>> >>> >>>> >> >> >> implementations
>> >>> >>>> >> >> >> >>> >> > in the code base a good working example? Is
>> there
>> >>> other
>> >>> >>>> >> >> >> documentation
>> >>> >>>> >> >> >> >>> >> > we can reference?
>> >>> >>>> >> >> >> >>> >> >
>> >>> >>>> >> >> >> >>> >>
>> >>> >>>> >> >> >> >>> >> I've been working on the People resource as a
>> >>> "reference"
>> >>> >>>> of
>> >>> >>>> >> how
>> >>> >>>> >> >> I'd
>> >>> >>>> >> >> >> >>> like
>> >>> >>>> >> >> >> >>> >> to see them done but it's still a work in
>> progress. I
>> >>> need
>> >>> >>>> to
>> >>> >>>> >> go
>> >>> >>>> >> >> >> back
>> >>> >>>> >> >> >> >>> and
>> >>> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>> >>> "fields"
>> >>> >>>> >> concept.
>> >>> >>>> >> >> >> >>> Couple of
>> >>> >>>> >> >> >> >>> >> notes:
>> >>> >>>> >> >> >> >>> >>
>> >>> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>> >>> possible
>> >>> >>>> >> >> >> >>> >> and separate requests should be made to nested
>> >>> resources to
>> >>> >>>> >> get
>> >>> >>>> >> >> >> nested
>> >>> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >>> >>>> regions/1/regionwidgets,
>> >>> >>>> >> >> the
>> >>> >>>> >> >> >> >>> regions
>> >>> >>>> >> >> >> >>> >> representation should not contain an array of
>> >>> >>>> regionwidgets)
>> >>> >>>> >> >> >> >>> >>
>> >>> >>>> >> >> >> >>> >
>> >>> >>>> >> >> >> >>> > I am concerned about the round trips to support
>> this
>> >>> when
>> >>> >>>> >> >> rendering
>> >>> >>>> >> >> >> the
>> >>> >>>> >> >> >> >>> > page.  With any page that has a sufficient number
>> of
>> >>> >>>> gadgets,
>> >>> >>>> >> >> adding
>> >>> >>>> >> >> >> to
>> >>> >>>> >> >> >> >>> the
>> >>> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >>> >>>> >> >> >> >>> >
>> >>> >>>> >> >> >> >>>
>> >>> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>> >>> endpoints for
>> >>> >>>> >> crud
>> >>> >>>> >> >> >> >>> operations on resources. We
>> >>> >>>> >>
>> >>> >>>>
>> >>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Mon, Jul 22, 2013 at 1:15 PM, Erin Noe-Payne <er...@gmail.com>wrote:

> I would also point out that we don't have a pressing need to actually
> implement fields support. Our first use case - the angular client -
> does not particularly need it since we will be using a
> client-optimized "pagesForRender" endpoint anyway.
>

My only argument with this is on People. Right now you always get the full
person record. I really think when you are searching for people you should
get limited data (like facebook) and only see more detailed information
when they are actually friends (and probably never see some data).

>
> As long as we ensure that our approach can be extended to support
> fields selection in the future without refactor, that should be good
> enough.
>
> On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > - Simple solution: All rest response models are flat. We ignore any
> > nested data, and just have separate endpoints to deliver that data.
> > I.E. Every model in the org.apache.rave.rest.model package has only
> > properties of "primitive" types, with no lists, no other classes. That
> > is NOT currently the case. Then the fields interceptor checks for the
> > presence of a fields argument. If not present, the object is delivered
> > as is. If present the argument (a string) is split by comma and only
> > the matched properties are delivered. The fields qs argument only has
> > to support comma-delimited list of property names.
> > Ex: ?fields=name,pageType
> > //returns a page or pages with only name and pageType properties
> >
> > - Complicated solution: All rest response models include references to
> > their nested data. This is the currently the case, and can be seen in
> > org.apache.rave.rest.model.Page. The fields interceptor checks for
> > presence of fields qs argument. If not present it strips all nested
> > data from the models and only returns properties. If it is present, it
> > parses the argument and updates the data. The fields argument needs to
> > support a more complicated syntax that allows the requesting of nested
> > data. I would copy the syntax of facebook's graph search api, which
> > has a pretty readable solution. You allow for .fields and .limit on
> > fields, which can be nested.
> > Ex:
> ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> > //returns a page or pages with name and pageType properties, nested
> > list of regions (max of 2) with nested list of regionWidgets with only
> > properties of widgetId and locked
> >
> > In all cases, id should always be returned.
> > I think the algorithm in the simple solution is easy.
> > In a sense the algorithm in the second should be simple, because the
> > service layer is already getting all the nested data, and you are just
> > stripping it off. Not sure what the performance implications of that
> > are though.
> >
> > On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> >> <er...@gmail.com>wrote:
> >>
> >>> Going back to the discussion on field selection - I am currently going
> >>> through the exercise of writing out the Resource interfaces to define
> >>> our endpoints.  There is a set of generic query string parameters that
> >>> we wish to support on all or many of the endpoints - fields (any get
> >>> request), limit / offset (any get request that returns a list).
> >>>
> >>> Rather than writing each endpoint to accept QueryParam()'s and repeat
> >>> the appropriate logic, I assume we would want to take advantage of cxf
> >>> interceptors [1] to intelligently and generically handle those qs
> >>> arguments?
> >>>
> >>
> >> I like the concept but I'm not sure how we generically filter,
> especially
> >> with nested data. I'd love to see it work that way though. Interceptors
> are
> >> pretty easy to use, it's the filter algorithm I haven't figured out yet.
> >> Thoughts?
> >>
> >>>
> >>> [1] http://cxf.apache.org/docs/interceptors.html
> >>>
> >>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> >>> <er...@gmail.com> wrote:
> >>> > Ok, so the endpoint is now working. Any thoughts about the
> >>> > JsonResponseWrapper approach? Does that seem like the best way to get
> >>> > wrapped responses?
> >>> >
> >>> > For the next step I would like to start writing out all of the
> >>> > resource interfaces so that we can begin writing angular $resource
> >>> > services against them.
> >>> >
> >>> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> >>> > <er...@gmail.com> wrote:
> >>> >> Awesome, thanks Chris. Not sure I would have ever figured that one
> >>> out...
> >>> >>
> >>> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
> >>> wrote:
> >>> >>> Erin,
> >>> >>>
> >>> >>> I got it working, at least the CXF part. Couple things:
> >>> >>>
> >>> >>> 1) In the interface, make sure to annotate the @GET methods
> >>> >>> 2) In your DefaultRegionWidgetsResource class, remove the
> @ParamPath
> >>> >>> attributes from variable signatures. I know Intellij puts those in
> >>> there
> >>> >>> but they cause problems. Only the interface should be annotated.
> >>> >>>
> >>> >>> Chris
> >>> >>>
> >>> >>>
> >>> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> >>> erin.noe.payne@gmail.com>wrote:
> >>> >>>
> >>> >>>> Review board is not accepting my patch and is not accepting the
> valid
> >>> >>>> file paths. I have attached the patch as a file to the review.
> >>> >>>>
> >>> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <
> chris@cxtsoftware.com>
> >>> wrote:
> >>> >>>> > Erin, I'm not seeing a patch posted up there.
> >>> >>>> >
> >>> >>>> >
> >>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >>> >>>> erin.noe.payne@gmail.com>wrote:
> >>> >>>> >
> >>> >>>> >> I was never able to hit the endpoint as expected. I've posted
> the
> >>> >>>> >> patch on the review board if anyone can take a look and offer
> >>> advice -
> >>> >>>> >> https://reviews.apache.org/r/12777/.
> >>> >>>> >>
> >>> >>>> >> Thanks
> >>> >>>> >>
> >>> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <
> chris@cxtsoftware.com
> >>> >
> >>> >>>> wrote:
> >>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >>> >>>> >> >
> >>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> >>> chris@cxtsoftware.com
> >>> >>>> >> <javascript:;>>
> >>> >>>> >> >> wrote:
> >>> >>>> >> >> > In the xml file you need to create the bean, then
> reference
> >>> it in
> >>> >>>> the
> >>> >>>> >> >> > server element near the top. Other than that...no, that
> >>> should be
> >>> >>>> >> all. I
> >>> >>>> >> >> > assume you set the Path attribute on the resource.
> >>> >>>> >> >> >
> >>> >>>> >> >> I did. I'm also messing around with the service injection,
> >>> which may
> >>> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >>> >>>> >> >>
> >>> >>>> >> >> > I thought we were going to do
> >>> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >>> >>>> >> >> > since it makes no sense to manage a region widget outside
> a
> >>> region
> >>> >>>> >> >> outside
> >>> >>>> >> >> > a page?
> >>> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of
> concept
> >>> with
> >>> >>>> the
> >>> >>>> >> >> wrapped json object so I picked something simple with the
> >>> service and
> >>> >>>> >> >> rest models already in place.
> >>> >>>> >> >>
> >>> >>>> >> >> In general though I don't see any value to dealing with
> region
> >>> >>>> widgets
> >>> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
> >>> dealing
> >>> >>>> with
> >>> >>>> >> >> them directly. It's just adding weight to the pages
> controller,
> >>> >>>> rather
> >>> >>>> >> >> than breaking them up and dealing with resource concerns
> >>> separately.
> >>> >>>> >> >>
> >>> >>>> >> >> I get what you're saying about regions and regionwidgets
> only
> >>> making
> >>> >>>> >> >> sense in the context of a page, but you could say the same
> >>> thing for
> >>> >>>> >> >> any 1-many associated resource. Both entities are always
> >>> uniquely
> >>> >>>> >> >> identified, so why not deal with them individually? I see an
> >>> upside
> >>> >>>> of
> >>> >>>> >> >> simpler code, consistent api endpoints, and I see no
> downside.
> >>> >>>> >> >
> >>> >>>> >> >
> >>> >>>> >> > Honestly, my hope is that someday they aren't uniquely
> >>> identified and
> >>> >>>> are
> >>> >>>> >> > really sun objects unlike JPA today. But that is a longer
> >>> >>>> conversation.
> >>> >>>> >> >
> >>> >>>> >> >>
> >>> >>>> >> >> >
> >>> >>>> >> >> >
> >>> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >>> >>>> >> >> > <er...@gmail.com>wrote:
> >>> >>>> >> >> >
> >>> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets.
> I've
> >>> >>>> added
> >>> >>>> >> >> >> the interface and default implementation, and created /
> >>> registered
> >>> >>>> >> the
> >>> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >>> >>>> >> >> >>
> >>> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >>> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >>> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation
> matching
> >>> >>>> request
> >>> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found,
> Relative
> >>> Path:
> >>> >>>> /1,
> >>> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >>> >>>> >> >> >>
> >>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >>> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
> >>> >>>> >> >> >>
> >>> >>>> >> >> >> Is there anything else I need to do in order to create
> and
> >>> >>>> register a
> >>> >>>> >> >> >> new endpoint?
> >>> >>>> >> >> >>
> >>> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >>> >>>> >> >> >> <er...@gmail.com> wrote:
> >>> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >>> >>>> >> chris@cxtsoftware.com>
> >>> >>>> >> >> >> wrote:
> >>> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >>> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>> >>>> >> >> >> >>
> >>> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >>> >>>> >> >> >> m.ben.franklin@gmail.com>
> >>> >>>> >> >> >> >>> wrote:
> >>> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >>> >>>> >> >> chris@cxtsoftware.com>
> >>> >>>> >> >> >> >>> wrote:
> >>> >>>> >> >> >> >>> >
> >>> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >>> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >>> >>>> >> >> >> >>> >>
> >>> >>>> >> >> >> >>> >> > Any further discussion here? I would like to
> start
> >>> >>>> >> implementing
> >>> >>>> >> >> >> more
> >>> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
> >>> entire
> >>> >>>> >> angular
> >>> >>>> >> >> >> >>> >> > architecture.
> >>> >>>> >> >> >> >>> >> >
> >>> >>>> >> >> >> >>> >> > My understanding from Matt is that the current
> apis
> >>> in
> >>> >>>> trunk
> >>> >>>> >> >> are
> >>> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested
> and
> >>> much of
> >>> >>>> >> the
> >>> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the
> rest
> >>> api
> >>> >>>> >> >> >> implementations
> >>> >>>> >> >> >> >>> >> > in the code base a good working example? Is
> there
> >>> other
> >>> >>>> >> >> >> documentation
> >>> >>>> >> >> >> >>> >> > we can reference?
> >>> >>>> >> >> >> >>> >> >
> >>> >>>> >> >> >> >>> >>
> >>> >>>> >> >> >> >>> >> I've been working on the People resource as a
> >>> "reference"
> >>> >>>> of
> >>> >>>> >> how
> >>> >>>> >> >> I'd
> >>> >>>> >> >> >> >>> like
> >>> >>>> >> >> >> >>> >> to see them done but it's still a work in
> progress. I
> >>> need
> >>> >>>> to
> >>> >>>> >> go
> >>> >>>> >> >> >> back
> >>> >>>> >> >> >> >>> and
> >>> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
> >>> "fields"
> >>> >>>> >> concept.
> >>> >>>> >> >> >> >>> Couple of
> >>> >>>> >> >> >> >>> >> notes:
> >>> >>>> >> >> >> >>> >>
> >>> >>>> >> >> >> >>> >>  - Object representations should be as flat as
> >>> possible
> >>> >>>> >> >> >> >>> >> and separate requests should be made to nested
> >>> resources to
> >>> >>>> >> get
> >>> >>>> >> >> >> nested
> >>> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >>> >>>> regions/1/regionwidgets,
> >>> >>>> >> >> the
> >>> >>>> >> >> >> >>> regions
> >>> >>>> >> >> >> >>> >> representation should not contain an array of
> >>> >>>> regionwidgets)
> >>> >>>> >> >> >> >>> >>
> >>> >>>> >> >> >> >>> >
> >>> >>>> >> >> >> >>> > I am concerned about the round trips to support
> this
> >>> when
> >>> >>>> >> >> rendering
> >>> >>>> >> >> >> the
> >>> >>>> >> >> >> >>> > page.  With any page that has a sufficient number
> of
> >>> >>>> gadgets,
> >>> >>>> >> >> adding
> >>> >>>> >> >> >> to
> >>> >>>> >> >> >> >>> the
> >>> >>>> >> >> >> >>> > number of requests becomes problematic.
> >>> >>>> >> >> >> >>> >
> >>> >>>> >> >> >> >>>
> >>> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
> >>> endpoints for
> >>> >>>> >> crud
> >>> >>>> >> >> >> >>> operations on resources. We
> >>> >>>> >>
> >>> >>>>
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
I would also point out that we don't have a pressing need to actually
implement fields support. Our first use case - the angular client -
does not particularly need it since we will be using a
client-optimized "pagesForRender" endpoint anyway.

As long as we ensure that our approach can be extended to support
fields selection in the future without refactor, that should be good
enough.

On Mon, Jul 22, 2013 at 3:58 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> - Simple solution: All rest response models are flat. We ignore any
> nested data, and just have separate endpoints to deliver that data.
> I.E. Every model in the org.apache.rave.rest.model package has only
> properties of "primitive" types, with no lists, no other classes. That
> is NOT currently the case. Then the fields interceptor checks for the
> presence of a fields argument. If not present, the object is delivered
> as is. If present the argument (a string) is split by comma and only
> the matched properties are delivered. The fields qs argument only has
> to support comma-delimited list of property names.
> Ex: ?fields=name,pageType
> //returns a page or pages with only name and pageType properties
>
> - Complicated solution: All rest response models include references to
> their nested data. This is the currently the case, and can be seen in
> org.apache.rave.rest.model.Page. The fields interceptor checks for
> presence of fields qs argument. If not present it strips all nested
> data from the models and only returns properties. If it is present, it
> parses the argument and updates the data. The fields argument needs to
> support a more complicated syntax that allows the requesting of nested
> data. I would copy the syntax of facebook's graph search api, which
> has a pretty readable solution. You allow for .fields and .limit on
> fields, which can be nested.
> Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
> //returns a page or pages with name and pageType properties, nested
> list of regions (max of 2) with nested list of regionWidgets with only
> properties of widgetId and locked
>
> In all cases, id should always be returned.
> I think the algorithm in the simple solution is easy.
> In a sense the algorithm in the second should be simple, because the
> service layer is already getting all the nested data, and you are just
> stripping it off. Not sure what the performance implications of that
> are though.
>
> On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
>> <er...@gmail.com>wrote:
>>
>>> Going back to the discussion on field selection - I am currently going
>>> through the exercise of writing out the Resource interfaces to define
>>> our endpoints.  There is a set of generic query string parameters that
>>> we wish to support on all or many of the endpoints - fields (any get
>>> request), limit / offset (any get request that returns a list).
>>>
>>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>>> the appropriate logic, I assume we would want to take advantage of cxf
>>> interceptors [1] to intelligently and generically handle those qs
>>> arguments?
>>>
>>
>> I like the concept but I'm not sure how we generically filter, especially
>> with nested data. I'd love to see it work that way though. Interceptors are
>> pretty easy to use, it's the filter algorithm I haven't figured out yet.
>> Thoughts?
>>
>>>
>>> [1] http://cxf.apache.org/docs/interceptors.html
>>>
>>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>>> <er...@gmail.com> wrote:
>>> > Ok, so the endpoint is now working. Any thoughts about the
>>> > JsonResponseWrapper approach? Does that seem like the best way to get
>>> > wrapped responses?
>>> >
>>> > For the next step I would like to start writing out all of the
>>> > resource interfaces so that we can begin writing angular $resource
>>> > services against them.
>>> >
>>> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>>> > <er...@gmail.com> wrote:
>>> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>>> out...
>>> >>
>>> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >>> Erin,
>>> >>>
>>> >>> I got it working, at least the CXF part. Couple things:
>>> >>>
>>> >>> 1) In the interface, make sure to annotate the @GET methods
>>> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>> >>> attributes from variable signatures. I know Intellij puts those in
>>> there
>>> >>> but they cause problems. Only the interface should be annotated.
>>> >>>
>>> >>> Chris
>>> >>>
>>> >>>
>>> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>>> erin.noe.payne@gmail.com>wrote:
>>> >>>
>>> >>>> Review board is not accepting my patch and is not accepting the valid
>>> >>>> file paths. I have attached the patch as a file to the review.
>>> >>>>
>>> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >>>> > Erin, I'm not seeing a patch posted up there.
>>> >>>> >
>>> >>>> >
>>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>> >>>> erin.noe.payne@gmail.com>wrote:
>>> >>>> >
>>> >>>> >> I was never able to hit the endpoint as expected. I've posted the
>>> >>>> >> patch on the review board if anyone can take a look and offer
>>> advice -
>>> >>>> >> https://reviews.apache.org/r/12777/.
>>> >>>> >>
>>> >>>> >> Thanks
>>> >>>> >>
>>> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>>> >
>>> >>>> wrote:
>>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>> >>>> >> >
>>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>>> chris@cxtsoftware.com
>>> >>>> >> <javascript:;>>
>>> >>>> >> >> wrote:
>>> >>>> >> >> > In the xml file you need to create the bean, then reference
>>> it in
>>> >>>> the
>>> >>>> >> >> > server element near the top. Other than that...no, that
>>> should be
>>> >>>> >> all. I
>>> >>>> >> >> > assume you set the Path attribute on the resource.
>>> >>>> >> >> >
>>> >>>> >> >> I did. I'm also messing around with the service injection,
>>> which may
>>> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>>> >>>> >> >>
>>> >>>> >> >> > I thought we were going to do
>>> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>> >>>> >> >> > since it makes no sense to manage a region widget outside a
>>> region
>>> >>>> >> >> outside
>>> >>>> >> >> > a page?
>>> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
>>> with
>>> >>>> the
>>> >>>> >> >> wrapped json object so I picked something simple with the
>>> service and
>>> >>>> >> >> rest models already in place.
>>> >>>> >> >>
>>> >>>> >> >> In general though I don't see any value to dealing with region
>>> >>>> widgets
>>> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>>> dealing
>>> >>>> with
>>> >>>> >> >> them directly. It's just adding weight to the pages controller,
>>> >>>> rather
>>> >>>> >> >> than breaking them up and dealing with resource concerns
>>> separately.
>>> >>>> >> >>
>>> >>>> >> >> I get what you're saying about regions and regionwidgets only
>>> making
>>> >>>> >> >> sense in the context of a page, but you could say the same
>>> thing for
>>> >>>> >> >> any 1-many associated resource. Both entities are always
>>> uniquely
>>> >>>> >> >> identified, so why not deal with them individually? I see an
>>> upside
>>> >>>> of
>>> >>>> >> >> simpler code, consistent api endpoints, and I see no downside.
>>> >>>> >> >
>>> >>>> >> >
>>> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>>> identified and
>>> >>>> are
>>> >>>> >> > really sun objects unlike JPA today. But that is a longer
>>> >>>> conversation.
>>> >>>> >> >
>>> >>>> >> >>
>>> >>>> >> >> >
>>> >>>> >> >> >
>>> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>> >>>> >> >> > <er...@gmail.com>wrote:
>>> >>>> >> >> >
>>> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>>> >>>> added
>>> >>>> >> >> >> the interface and default implementation, and created /
>>> registered
>>> >>>> >> the
>>> >>>> >> >> >> bean in cxf-applicationContext.xml.
>>> >>>> >> >> >>
>>> >>>> >> >> >> However, when I hit the endpoint I get an error:
>>> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>> >>>> request
>>> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
>>> Path:
>>> >>>> /1,
>>> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>>> >>>> >> >> >>
>>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>>> >>>> >> >> >>
>>> >>>> >> >> >> Is there anything else I need to do in order to create and
>>> >>>> register a
>>> >>>> >> >> >> new endpoint?
>>> >>>> >> >> >>
>>> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>> >>>> >> >> >> <er...@gmail.com> wrote:
>>> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>> >>>> >> chris@cxtsoftware.com>
>>> >>>> >> >> >> wrote:
>>> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >>>> >> >> >> >>
>>> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>> >>>> >> >> >> m.ben.franklin@gmail.com>
>>> >>>> >> >> >> >>> wrote:
>>> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>> >>>> >> >> chris@cxtsoftware.com>
>>> >>>> >> >> >> >>> wrote:
>>> >>>> >> >> >> >>> >
>>> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>> >>>> >> >> >> >>> >>
>>> >>>> >> >> >> >>> >> > Any further discussion here? I would like to start
>>> >>>> >> implementing
>>> >>>> >> >> >> more
>>> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
>>> entire
>>> >>>> >> angular
>>> >>>> >> >> >> >>> >> > architecture.
>>> >>>> >> >> >> >>> >> >
>>> >>>> >> >> >> >>> >> > My understanding from Matt is that the current apis
>>> in
>>> >>>> trunk
>>> >>>> >> >> are
>>> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
>>> much of
>>> >>>> >> the
>>> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest
>>> api
>>> >>>> >> >> >> implementations
>>> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
>>> other
>>> >>>> >> >> >> documentation
>>> >>>> >> >> >> >>> >> > we can reference?
>>> >>>> >> >> >> >>> >> >
>>> >>>> >> >> >> >>> >>
>>> >>>> >> >> >> >>> >> I've been working on the People resource as a
>>> "reference"
>>> >>>> of
>>> >>>> >> how
>>> >>>> >> >> I'd
>>> >>>> >> >> >> >>> like
>>> >>>> >> >> >> >>> >> to see them done but it's still a work in progress. I
>>> need
>>> >>>> to
>>> >>>> >> go
>>> >>>> >> >> >> back
>>> >>>> >> >> >> >>> and
>>> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>>> "fields"
>>> >>>> >> concept.
>>> >>>> >> >> >> >>> Couple of
>>> >>>> >> >> >> >>> >> notes:
>>> >>>> >> >> >> >>> >>
>>> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>>> possible
>>> >>>> >> >> >> >>> >> and separate requests should be made to nested
>>> resources to
>>> >>>> >> get
>>> >>>> >> >> >> nested
>>> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>>> >>>> regions/1/regionwidgets,
>>> >>>> >> >> the
>>> >>>> >> >> >> >>> regions
>>> >>>> >> >> >> >>> >> representation should not contain an array of
>>> >>>> regionwidgets)
>>> >>>> >> >> >> >>> >>
>>> >>>> >> >> >> >>> >
>>> >>>> >> >> >> >>> > I am concerned about the round trips to support this
>>> when
>>> >>>> >> >> rendering
>>> >>>> >> >> >> the
>>> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>>> >>>> gadgets,
>>> >>>> >> >> adding
>>> >>>> >> >> >> to
>>> >>>> >> >> >> >>> the
>>> >>>> >> >> >> >>> > number of requests becomes problematic.
>>> >>>> >> >> >> >>> >
>>> >>>> >> >> >> >>>
>>> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>>> endpoints for
>>> >>>> >> crud
>>> >>>> >> >> >> >>> operations on resources. We
>>> >>>> >>
>>> >>>>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
- Simple solution: All rest response models are flat. We ignore any
nested data, and just have separate endpoints to deliver that data.
I.E. Every model in the org.apache.rave.rest.model package has only
properties of "primitive" types, with no lists, no other classes. That
is NOT currently the case. Then the fields interceptor checks for the
presence of a fields argument. If not present, the object is delivered
as is. If present the argument (a string) is split by comma and only
the matched properties are delivered. The fields qs argument only has
to support comma-delimited list of property names.
Ex: ?fields=name,pageType
//returns a page or pages with only name and pageType properties

- Complicated solution: All rest response models include references to
their nested data. This is the currently the case, and can be seen in
org.apache.rave.rest.model.Page. The fields interceptor checks for
presence of fields qs argument. If not present it strips all nested
data from the models and only returns properties. If it is present, it
parses the argument and updates the data. The fields argument needs to
support a more complicated syntax that allows the requesting of nested
data. I would copy the syntax of facebook's graph search api, which
has a pretty readable solution. You allow for .fields and .limit on
fields, which can be nested.
Ex: ?fields=name,pageType,regions.limit(2).fields(regionWidgets.fields(widgetId,locked))
//returns a page or pages with name and pageType properties, nested
list of regions (max of 2) with nested list of regionWidgets with only
properties of widgetId and locked

In all cases, id should always be returned.
I think the algorithm in the simple solution is easy.
In a sense the algorithm in the second should be simple, because the
service layer is already getting all the nested data, and you are just
stripping it off. Not sure what the performance implications of that
are though.

On Mon, Jul 22, 2013 at 3:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> Going back to the discussion on field selection - I am currently going
>> through the exercise of writing out the Resource interfaces to define
>> our endpoints.  There is a set of generic query string parameters that
>> we wish to support on all or many of the endpoints - fields (any get
>> request), limit / offset (any get request that returns a list).
>>
>> Rather than writing each endpoint to accept QueryParam()'s and repeat
>> the appropriate logic, I assume we would want to take advantage of cxf
>> interceptors [1] to intelligently and generically handle those qs
>> arguments?
>>
>
> I like the concept but I'm not sure how we generically filter, especially
> with nested data. I'd love to see it work that way though. Interceptors are
> pretty easy to use, it's the filter algorithm I haven't figured out yet.
> Thoughts?
>
>>
>> [1] http://cxf.apache.org/docs/interceptors.html
>>
>> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > Ok, so the endpoint is now working. Any thoughts about the
>> > JsonResponseWrapper approach? Does that seem like the best way to get
>> > wrapped responses?
>> >
>> > For the next step I would like to start writing out all of the
>> > resource interfaces so that we can begin writing angular $resource
>> > services against them.
>> >
>> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
>> > <er...@gmail.com> wrote:
>> >> Awesome, thanks Chris. Not sure I would have ever figured that one
>> out...
>> >>
>> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >>> Erin,
>> >>>
>> >>> I got it working, at least the CXF part. Couple things:
>> >>>
>> >>> 1) In the interface, make sure to annotate the @GET methods
>> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>> >>> attributes from variable signatures. I know Intellij puts those in
>> there
>> >>> but they cause problems. Only the interface should be annotated.
>> >>>
>> >>> Chris
>> >>>
>> >>>
>> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >>>
>> >>>> Review board is not accepting my patch and is not accepting the valid
>> >>>> file paths. I have attached the patch as a file to the review.
>> >>>>
>> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >>>> > Erin, I'm not seeing a patch posted up there.
>> >>>> >
>> >>>> >
>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> >>>> erin.noe.payne@gmail.com>wrote:
>> >>>> >
>> >>>> >> I was never able to hit the endpoint as expected. I've posted the
>> >>>> >> patch on the review board if anyone can take a look and offer
>> advice -
>> >>>> >> https://reviews.apache.org/r/12777/.
>> >>>> >>
>> >>>> >> Thanks
>> >>>> >>
>> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
>> >
>> >>>> wrote:
>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >>>> >> >
>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >>>> >> <javascript:;>>
>> >>>> >> >> wrote:
>> >>>> >> >> > In the xml file you need to create the bean, then reference
>> it in
>> >>>> the
>> >>>> >> >> > server element near the top. Other than that...no, that
>> should be
>> >>>> >> all. I
>> >>>> >> >> > assume you set the Path attribute on the resource.
>> >>>> >> >> >
>> >>>> >> >> I did. I'm also messing around with the service injection,
>> which may
>> >>>> >> >> be the issue. Haven't gotten it to work yet though.
>> >>>> >> >>
>> >>>> >> >> > I thought we were going to do
>> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >>>> >> >> > since it makes no sense to manage a region widget outside a
>> region
>> >>>> >> >> outside
>> >>>> >> >> > a page?
>> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
>> with
>> >>>> the
>> >>>> >> >> wrapped json object so I picked something simple with the
>> service and
>> >>>> >> >> rest models already in place.
>> >>>> >> >>
>> >>>> >> >> In general though I don't see any value to dealing with region
>> >>>> widgets
>> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
>> dealing
>> >>>> with
>> >>>> >> >> them directly. It's just adding weight to the pages controller,
>> >>>> rather
>> >>>> >> >> than breaking them up and dealing with resource concerns
>> separately.
>> >>>> >> >>
>> >>>> >> >> I get what you're saying about regions and regionwidgets only
>> making
>> >>>> >> >> sense in the context of a page, but you could say the same
>> thing for
>> >>>> >> >> any 1-many associated resource. Both entities are always
>> uniquely
>> >>>> >> >> identified, so why not deal with them individually? I see an
>> upside
>> >>>> of
>> >>>> >> >> simpler code, consistent api endpoints, and I see no downside.
>> >>>> >> >
>> >>>> >> >
>> >>>> >> > Honestly, my hope is that someday they aren't uniquely
>> identified and
>> >>>> are
>> >>>> >> > really sun objects unlike JPA today. But that is a longer
>> >>>> conversation.
>> >>>> >> >
>> >>>> >> >>
>> >>>> >> >> >
>> >>>> >> >> >
>> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >>>> >> >> > <er...@gmail.com>wrote:
>> >>>> >> >> >
>> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>> >>>> added
>> >>>> >> >> >> the interface and default implementation, and created /
>> registered
>> >>>> >> the
>> >>>> >> >> >> bean in cxf-applicationContext.xml.
>> >>>> >> >> >>
>> >>>> >> >> >> However, when I hit the endpoint I get an error:
>> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>> >>>> request
>> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
>> Path:
>> >>>> /1,
>> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >>>> >> >> >>
>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >>>> >> >> >>
>> >>>> >> >> >> Is there anything else I need to do in order to create and
>> >>>> register a
>> >>>> >> >> >> new endpoint?
>> >>>> >> >> >>
>> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >>>> >> >> >> <er...@gmail.com> wrote:
>> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >>>> >> chris@cxtsoftware.com>
>> >>>> >> >> >> wrote:
>> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >>>> >> >> >> >>
>> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >>>> >> >> >> m.ben.franklin@gmail.com>
>> >>>> >> >> >> >>> wrote:
>> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >>>> >> >> chris@cxtsoftware.com>
>> >>>> >> >> >> >>> wrote:
>> >>>> >> >> >> >>> >
>> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >>>> >> >> >> >>> >>
>> >>>> >> >> >> >>> >> > Any further discussion here? I would like to start
>> >>>> >> implementing
>> >>>> >> >> >> more
>> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
>> entire
>> >>>> >> angular
>> >>>> >> >> >> >>> >> > architecture.
>> >>>> >> >> >> >>> >> >
>> >>>> >> >> >> >>> >> > My understanding from Matt is that the current apis
>> in
>> >>>> trunk
>> >>>> >> >> are
>> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
>> much of
>> >>>> >> the
>> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest
>> api
>> >>>> >> >> >> implementations
>> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
>> other
>> >>>> >> >> >> documentation
>> >>>> >> >> >> >>> >> > we can reference?
>> >>>> >> >> >> >>> >> >
>> >>>> >> >> >> >>> >>
>> >>>> >> >> >> >>> >> I've been working on the People resource as a
>> "reference"
>> >>>> of
>> >>>> >> how
>> >>>> >> >> I'd
>> >>>> >> >> >> >>> like
>> >>>> >> >> >> >>> >> to see them done but it's still a work in progress. I
>> need
>> >>>> to
>> >>>> >> go
>> >>>> >> >> >> back
>> >>>> >> >> >> >>> and
>> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
>> "fields"
>> >>>> >> concept.
>> >>>> >> >> >> >>> Couple of
>> >>>> >> >> >> >>> >> notes:
>> >>>> >> >> >> >>> >>
>> >>>> >> >> >> >>> >>  - Object representations should be as flat as
>> possible
>> >>>> >> >> >> >>> >> and separate requests should be made to nested
>> resources to
>> >>>> >> get
>> >>>> >> >> >> nested
>> >>>> >> >> >> >>> >> details (i.e. if you have regions and
>> >>>> regions/1/regionwidgets,
>> >>>> >> >> the
>> >>>> >> >> >> >>> regions
>> >>>> >> >> >> >>> >> representation should not contain an array of
>> >>>> regionwidgets)
>> >>>> >> >> >> >>> >>
>> >>>> >> >> >> >>> >
>> >>>> >> >> >> >>> > I am concerned about the round trips to support this
>> when
>> >>>> >> >> rendering
>> >>>> >> >> >> the
>> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>> >>>> gadgets,
>> >>>> >> >> adding
>> >>>> >> >> >> to
>> >>>> >> >> >> >>> the
>> >>>> >> >> >> >>> > number of requests becomes problematic.
>> >>>> >> >> >> >>> >
>> >>>> >> >> >> >>>
>> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
>> endpoints for
>> >>>> >> crud
>> >>>> >> >> >> >>> operations on resources. We
>> >>>> >>
>> >>>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne
<er...@gmail.com>wrote:

> Going back to the discussion on field selection - I am currently going
> through the exercise of writing out the Resource interfaces to define
> our endpoints.  There is a set of generic query string parameters that
> we wish to support on all or many of the endpoints - fields (any get
> request), limit / offset (any get request that returns a list).
>
> Rather than writing each endpoint to accept QueryParam()'s and repeat
> the appropriate logic, I assume we would want to take advantage of cxf
> interceptors [1] to intelligently and generically handle those qs
> arguments?
>

I like the concept but I'm not sure how we generically filter, especially
with nested data. I'd love to see it work that way though. Interceptors are
pretty easy to use, it's the filter algorithm I haven't figured out yet.
Thoughts?

>
> [1] http://cxf.apache.org/docs/interceptors.html
>
> On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > Ok, so the endpoint is now working. Any thoughts about the
> > JsonResponseWrapper approach? Does that seem like the best way to get
> > wrapped responses?
> >
> > For the next step I would like to start writing out all of the
> > resource interfaces so that we can begin writing angular $resource
> > services against them.
> >
> > On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> > <er...@gmail.com> wrote:
> >> Awesome, thanks Chris. Not sure I would have ever figured that one
> out...
> >>
> >> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >>> Erin,
> >>>
> >>> I got it working, at least the CXF part. Couple things:
> >>>
> >>> 1) In the interface, make sure to annotate the @GET methods
> >>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
> >>> attributes from variable signatures. I know Intellij puts those in
> there
> >>> but they cause problems. Only the interface should be annotated.
> >>>
> >>> Chris
> >>>
> >>>
> >>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >>>
> >>>> Review board is not accepting my patch and is not accepting the valid
> >>>> file paths. I have attached the patch as a file to the review.
> >>>>
> >>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >>>> > Erin, I'm not seeing a patch posted up there.
> >>>> >
> >>>> >
> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> >>>> erin.noe.payne@gmail.com>wrote:
> >>>> >
> >>>> >> I was never able to hit the endpoint as expected. I've posted the
> >>>> >> patch on the review board if anyone can take a look and offer
> advice -
> >>>> >> https://reviews.apache.org/r/12777/.
> >>>> >>
> >>>> >> Thanks
> >>>> >>
> >>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <chris@cxtsoftware.com
> >
> >>>> wrote:
> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >>>> >> >
> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <
> chris@cxtsoftware.com
> >>>> >> <javascript:;>>
> >>>> >> >> wrote:
> >>>> >> >> > In the xml file you need to create the bean, then reference
> it in
> >>>> the
> >>>> >> >> > server element near the top. Other than that...no, that
> should be
> >>>> >> all. I
> >>>> >> >> > assume you set the Path attribute on the resource.
> >>>> >> >> >
> >>>> >> >> I did. I'm also messing around with the service injection,
> which may
> >>>> >> >> be the issue. Haven't gotten it to work yet though.
> >>>> >> >>
> >>>> >> >> > I thought we were going to do
> >>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >>>> >> >> > since it makes no sense to manage a region widget outside a
> region
> >>>> >> >> outside
> >>>> >> >> > a page?
> >>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept
> with
> >>>> the
> >>>> >> >> wrapped json object so I picked something simple with the
> service and
> >>>> >> >> rest models already in place.
> >>>> >> >>
> >>>> >> >> In general though I don't see any value to dealing with region
> >>>> widgets
> >>>> >> >> as a nested resource (pages/:id/regions/:id...) over just
> dealing
> >>>> with
> >>>> >> >> them directly. It's just adding weight to the pages controller,
> >>>> rather
> >>>> >> >> than breaking them up and dealing with resource concerns
> separately.
> >>>> >> >>
> >>>> >> >> I get what you're saying about regions and regionwidgets only
> making
> >>>> >> >> sense in the context of a page, but you could say the same
> thing for
> >>>> >> >> any 1-many associated resource. Both entities are always
> uniquely
> >>>> >> >> identified, so why not deal with them individually? I see an
> upside
> >>>> of
> >>>> >> >> simpler code, consistent api endpoints, and I see no downside.
> >>>> >> >
> >>>> >> >
> >>>> >> > Honestly, my hope is that someday they aren't uniquely
> identified and
> >>>> are
> >>>> >> > really sun objects unlike JPA today. But that is a longer
> >>>> conversation.
> >>>> >> >
> >>>> >> >>
> >>>> >> >> >
> >>>> >> >> >
> >>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >>>> >> >> > <er...@gmail.com>wrote:
> >>>> >> >> >
> >>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
> >>>> added
> >>>> >> >> >> the interface and default implementation, and created /
> registered
> >>>> >> the
> >>>> >> >> >> bean in cxf-applicationContext.xml.
> >>>> >> >> >>
> >>>> >> >> >> However, when I hit the endpoint I get an error:
> >>>> >> >> >> [INFO] [talledLocalContainer] WARN :
> >>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
> >>>> request
> >>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative
> Path:
> >>>> /1,
> >>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >>>> >> >> >>
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >>>> >> >> >> Please enable FINE/TRACE log level for more details.
> >>>> >> >> >>
> >>>> >> >> >> Is there anything else I need to do in order to create and
> >>>> register a
> >>>> >> >> >> new endpoint?
> >>>> >> >> >>
> >>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >>>> >> >> >> <er...@gmail.com> wrote:
> >>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >>>> >> chris@cxtsoftware.com>
> >>>> >> >> >> wrote:
> >>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >>>> >> >> >> erin.noe.payne@gmail.com>wrote:
> >>>> >> >> >> >>
> >>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >>>> >> >> >> m.ben.franklin@gmail.com>
> >>>> >> >> >> >>> wrote:
> >>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >>>> >> >> chris@cxtsoftware.com>
> >>>> >> >> >> >>> wrote:
> >>>> >> >> >> >>> >
> >>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >>>> >> >> >> >>> >> <er...@gmail.com>wrote:
> >>>> >> >> >> >>> >>
> >>>> >> >> >> >>> >> > Any further discussion here? I would like to start
> >>>> >> implementing
> >>>> >> >> >> more
> >>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the
> entire
> >>>> >> angular
> >>>> >> >> >> >>> >> > architecture.
> >>>> >> >> >> >>> >> >
> >>>> >> >> >> >>> >> > My understanding from Matt is that the current apis
> in
> >>>> trunk
> >>>> >> >> are
> >>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and
> much of
> >>>> >> the
> >>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest
> api
> >>>> >> >> >> implementations
> >>>> >> >> >> >>> >> > in the code base a good working example? Is there
> other
> >>>> >> >> >> documentation
> >>>> >> >> >> >>> >> > we can reference?
> >>>> >> >> >> >>> >> >
> >>>> >> >> >> >>> >>
> >>>> >> >> >> >>> >> I've been working on the People resource as a
> "reference"
> >>>> of
> >>>> >> how
> >>>> >> >> I'd
> >>>> >> >> >> >>> like
> >>>> >> >> >> >>> >> to see them done but it's still a work in progress. I
> need
> >>>> to
> >>>> >> go
> >>>> >> >> >> back
> >>>> >> >> >> >>> and
> >>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the
> "fields"
> >>>> >> concept.
> >>>> >> >> >> >>> Couple of
> >>>> >> >> >> >>> >> notes:
> >>>> >> >> >> >>> >>
> >>>> >> >> >> >>> >>  - Object representations should be as flat as
> possible
> >>>> >> >> >> >>> >> and separate requests should be made to nested
> resources to
> >>>> >> get
> >>>> >> >> >> nested
> >>>> >> >> >> >>> >> details (i.e. if you have regions and
> >>>> regions/1/regionwidgets,
> >>>> >> >> the
> >>>> >> >> >> >>> regions
> >>>> >> >> >> >>> >> representation should not contain an array of
> >>>> regionwidgets)
> >>>> >> >> >> >>> >>
> >>>> >> >> >> >>> >
> >>>> >> >> >> >>> > I am concerned about the round trips to support this
> when
> >>>> >> >> rendering
> >>>> >> >> >> the
> >>>> >> >> >> >>> > page.  With any page that has a sufficient number of
> >>>> gadgets,
> >>>> >> >> adding
> >>>> >> >> >> to
> >>>> >> >> >> >>> the
> >>>> >> >> >> >>> > number of requests becomes problematic.
> >>>> >> >> >> >>> >
> >>>> >> >> >> >>>
> >>>> >> >> >> >>> I see that rule applying to the "standard" rest
> endpoints for
> >>>> >> crud
> >>>> >> >> >> >>> operations on resources. We
> >>>> >>
> >>>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Going back to the discussion on field selection - I am currently going
through the exercise of writing out the Resource interfaces to define
our endpoints.  There is a set of generic query string parameters that
we wish to support on all or many of the endpoints - fields (any get
request), limit / offset (any get request that returns a list).

Rather than writing each endpoint to accept QueryParam()'s and repeat
the appropriate logic, I assume we would want to take advantage of cxf
interceptors [1] to intelligently and generically handle those qs
arguments?

[1] http://cxf.apache.org/docs/interceptors.html

On Mon, Jul 22, 2013 at 11:40 AM, Erin Noe-Payne
<er...@gmail.com> wrote:
> Ok, so the endpoint is now working. Any thoughts about the
> JsonResponseWrapper approach? Does that seem like the best way to get
> wrapped responses?
>
> For the next step I would like to start writing out all of the
> resource interfaces so that we can begin writing angular $resource
> services against them.
>
> On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
>> Awesome, thanks Chris. Not sure I would have ever figured that one out...
>>
>> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>> Erin,
>>>
>>> I got it working, at least the CXF part. Couple things:
>>>
>>> 1) In the interface, make sure to annotate the @GET methods
>>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>>> attributes from variable signatures. I know Intellij puts those in there
>>> but they cause problems. Only the interface should be annotated.
>>>
>>> Chris
>>>
>>>
>>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>>>
>>>> Review board is not accepting my patch and is not accepting the valid
>>>> file paths. I have attached the patch as a file to the review.
>>>>
>>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>>> > Erin, I'm not seeing a patch posted up there.
>>>> >
>>>> >
>>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>>> erin.noe.payne@gmail.com>wrote:
>>>> >
>>>> >> I was never able to hit the endpoint as expected. I've posted the
>>>> >> patch on the review board if anyone can take a look and offer advice -
>>>> >> https://reviews.apache.org/r/12777/.
>>>> >>
>>>> >> Thanks
>>>> >>
>>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com>
>>>> wrote:
>>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>>> >> >
>>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
>>>> >> <javascript:;>>
>>>> >> >> wrote:
>>>> >> >> > In the xml file you need to create the bean, then reference it in
>>>> the
>>>> >> >> > server element near the top. Other than that...no, that should be
>>>> >> all. I
>>>> >> >> > assume you set the Path attribute on the resource.
>>>> >> >> >
>>>> >> >> I did. I'm also messing around with the service injection, which may
>>>> >> >> be the issue. Haven't gotten it to work yet though.
>>>> >> >>
>>>> >> >> > I thought we were going to do
>>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>>> >> >> > since it makes no sense to manage a region widget outside a region
>>>> >> >> outside
>>>> >> >> > a page?
>>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept with
>>>> the
>>>> >> >> wrapped json object so I picked something simple with the service and
>>>> >> >> rest models already in place.
>>>> >> >>
>>>> >> >> In general though I don't see any value to dealing with region
>>>> widgets
>>>> >> >> as a nested resource (pages/:id/regions/:id...) over just dealing
>>>> with
>>>> >> >> them directly. It's just adding weight to the pages controller,
>>>> rather
>>>> >> >> than breaking them up and dealing with resource concerns separately.
>>>> >> >>
>>>> >> >> I get what you're saying about regions and regionwidgets only making
>>>> >> >> sense in the context of a page, but you could say the same thing for
>>>> >> >> any 1-many associated resource. Both entities are always uniquely
>>>> >> >> identified, so why not deal with them individually? I see an upside
>>>> of
>>>> >> >> simpler code, consistent api endpoints, and I see no downside.
>>>> >> >
>>>> >> >
>>>> >> > Honestly, my hope is that someday they aren't uniquely identified and
>>>> are
>>>> >> > really sun objects unlike JPA today. But that is a longer
>>>> conversation.
>>>> >> >
>>>> >> >>
>>>> >> >> >
>>>> >> >> >
>>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>>> >> >> > <er...@gmail.com>wrote:
>>>> >> >> >
>>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>>>> added
>>>> >> >> >> the interface and default implementation, and created / registered
>>>> >> the
>>>> >> >> >> bean in cxf-applicationContext.xml.
>>>> >> >> >>
>>>> >> >> >> However, when I hit the endpoint I get an error:
>>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>>> request
>>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path:
>>>> /1,
>>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>>>> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>>> >> >> >> Please enable FINE/TRACE log level for more details.
>>>> >> >> >>
>>>> >> >> >> Is there anything else I need to do in order to create and
>>>> register a
>>>> >> >> >> new endpoint?
>>>> >> >> >>
>>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>>> >> >> >> <er...@gmail.com> wrote:
>>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>>> >> chris@cxtsoftware.com>
>>>> >> >> >> wrote:
>>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>>> >> >> >> >>
>>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>>> >> >> >> m.ben.franklin@gmail.com>
>>>> >> >> >> >>> wrote:
>>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>>> >> >> chris@cxtsoftware.com>
>>>> >> >> >> >>> wrote:
>>>> >> >> >> >>> >
>>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>>> >> >> >> >>> >>
>>>> >> >> >> >>> >> > Any further discussion here? I would like to start
>>>> >> implementing
>>>> >> >> >> more
>>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
>>>> >> angular
>>>> >> >> >> >>> >> > architecture.
>>>> >> >> >> >>> >> >
>>>> >> >> >> >>> >> > My understanding from Matt is that the current apis in
>>>> trunk
>>>> >> >> are
>>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and much of
>>>> >> the
>>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
>>>> >> >> >> implementations
>>>> >> >> >> >>> >> > in the code base a good working example? Is there other
>>>> >> >> >> documentation
>>>> >> >> >> >>> >> > we can reference?
>>>> >> >> >> >>> >> >
>>>> >> >> >> >>> >>
>>>> >> >> >> >>> >> I've been working on the People resource as a "reference"
>>>> of
>>>> >> how
>>>> >> >> I'd
>>>> >> >> >> >>> like
>>>> >> >> >> >>> >> to see them done but it's still a work in progress. I need
>>>> to
>>>> >> go
>>>> >> >> >> back
>>>> >> >> >> >>> and
>>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
>>>> >> concept.
>>>> >> >> >> >>> Couple of
>>>> >> >> >> >>> >> notes:
>>>> >> >> >> >>> >>
>>>> >> >> >> >>> >>  - Object representations should be as flat as possible
>>>> >> >> >> >>> >> and separate requests should be made to nested resources to
>>>> >> get
>>>> >> >> >> nested
>>>> >> >> >> >>> >> details (i.e. if you have regions and
>>>> regions/1/regionwidgets,
>>>> >> >> the
>>>> >> >> >> >>> regions
>>>> >> >> >> >>> >> representation should not contain an array of
>>>> regionwidgets)
>>>> >> >> >> >>> >>
>>>> >> >> >> >>> >
>>>> >> >> >> >>> > I am concerned about the round trips to support this when
>>>> >> >> rendering
>>>> >> >> >> the
>>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>>>> gadgets,
>>>> >> >> adding
>>>> >> >> >> to
>>>> >> >> >> >>> the
>>>> >> >> >> >>> > number of requests becomes problematic.
>>>> >> >> >> >>> >
>>>> >> >> >> >>>
>>>> >> >> >> >>> I see that rule applying to the "standard" rest endpoints for
>>>> >> crud
>>>> >> >> >> >>> operations on resources. We
>>>> >>
>>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Ok, so the endpoint is now working. Any thoughts about the
JsonResponseWrapper approach? Does that seem like the best way to get
wrapped responses?

For the next step I would like to start writing out all of the
resource interfaces so that we can begin writing angular $resource
services against them.

On Sun, Jul 21, 2013 at 8:54 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> Awesome, thanks Chris. Not sure I would have ever figured that one out...
>
> On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> Erin,
>>
>> I got it working, at least the CXF part. Couple things:
>>
>> 1) In the interface, make sure to annotate the @GET methods
>> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
>> attributes from variable signatures. I know Intellij puts those in there
>> but they cause problems. Only the interface should be annotated.
>>
>> Chris
>>
>>
>> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>>
>>> Review board is not accepting my patch and is not accepting the valid
>>> file paths. I have attached the patch as a file to the review.
>>>
>>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>> > Erin, I'm not seeing a patch posted up there.
>>> >
>>> >
>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>>> erin.noe.payne@gmail.com>wrote:
>>> >
>>> >> I was never able to hit the endpoint as expected. I've posted the
>>> >> patch on the review board if anyone can take a look and offer advice -
>>> >> https://reviews.apache.org/r/12777/.
>>> >>
>>> >> Thanks
>>> >>
>>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>>> >> >
>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
>>> >> <javascript:;>>
>>> >> >> wrote:
>>> >> >> > In the xml file you need to create the bean, then reference it in
>>> the
>>> >> >> > server element near the top. Other than that...no, that should be
>>> >> all. I
>>> >> >> > assume you set the Path attribute on the resource.
>>> >> >> >
>>> >> >> I did. I'm also messing around with the service injection, which may
>>> >> >> be the issue. Haven't gotten it to work yet though.
>>> >> >>
>>> >> >> > I thought we were going to do
>>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>>> >> >> > since it makes no sense to manage a region widget outside a region
>>> >> >> outside
>>> >> >> > a page?
>>> >> >>  Possibly. Right now I'm just trying to do a proof of concept with
>>> the
>>> >> >> wrapped json object so I picked something simple with the service and
>>> >> >> rest models already in place.
>>> >> >>
>>> >> >> In general though I don't see any value to dealing with region
>>> widgets
>>> >> >> as a nested resource (pages/:id/regions/:id...) over just dealing
>>> with
>>> >> >> them directly. It's just adding weight to the pages controller,
>>> rather
>>> >> >> than breaking them up and dealing with resource concerns separately.
>>> >> >>
>>> >> >> I get what you're saying about regions and regionwidgets only making
>>> >> >> sense in the context of a page, but you could say the same thing for
>>> >> >> any 1-many associated resource. Both entities are always uniquely
>>> >> >> identified, so why not deal with them individually? I see an upside
>>> of
>>> >> >> simpler code, consistent api endpoints, and I see no downside.
>>> >> >
>>> >> >
>>> >> > Honestly, my hope is that someday they aren't uniquely identified and
>>> are
>>> >> > really sun objects unlike JPA today. But that is a longer
>>> conversation.
>>> >> >
>>> >> >>
>>> >> >> >
>>> >> >> >
>>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>>> >> >> > <er...@gmail.com>wrote:
>>> >> >> >
>>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>>> added
>>> >> >> >> the interface and default implementation, and created / registered
>>> >> the
>>> >> >> >> bean in cxf-applicationContext.xml.
>>> >> >> >>
>>> >> >> >> However, when I hit the endpoint I get an error:
>>> >> >> >> [INFO] [talledLocalContainer] WARN :
>>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>>> request
>>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path:
>>> /1,
>>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>>> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>>> >> >> >> Please enable FINE/TRACE log level for more details.
>>> >> >> >>
>>> >> >> >> Is there anything else I need to do in order to create and
>>> register a
>>> >> >> >> new endpoint?
>>> >> >> >>
>>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>>> >> >> >> <er...@gmail.com> wrote:
>>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>>> >> chris@cxtsoftware.com>
>>> >> >> >> wrote:
>>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>>> >> >> >> erin.noe.payne@gmail.com>wrote:
>>> >> >> >> >>
>>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>>> >> >> >> m.ben.franklin@gmail.com>
>>> >> >> >> >>> wrote:
>>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>>> >> >> chris@cxtsoftware.com>
>>> >> >> >> >>> wrote:
>>> >> >> >> >>> >
>>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>> >> >> >> >>> >> <er...@gmail.com>wrote:
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> > Any further discussion here? I would like to start
>>> >> implementing
>>> >> >> >> more
>>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
>>> >> angular
>>> >> >> >> >>> >> > architecture.
>>> >> >> >> >>> >> >
>>> >> >> >> >>> >> > My understanding from Matt is that the current apis in
>>> trunk
>>> >> >> are
>>> >> >> >> >>> >> > mostly proof of concept - they are not tested and much of
>>> >> the
>>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
>>> >> >> >> implementations
>>> >> >> >> >>> >> > in the code base a good working example? Is there other
>>> >> >> >> documentation
>>> >> >> >> >>> >> > we can reference?
>>> >> >> >> >>> >> >
>>> >> >> >> >>> >>
>>> >> >> >> >>> >> I've been working on the People resource as a "reference"
>>> of
>>> >> how
>>> >> >> I'd
>>> >> >> >> >>> like
>>> >> >> >> >>> >> to see them done but it's still a work in progress. I need
>>> to
>>> >> go
>>> >> >> >> back
>>> >> >> >> >>> and
>>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
>>> >> concept.
>>> >> >> >> >>> Couple of
>>> >> >> >> >>> >> notes:
>>> >> >> >> >>> >>
>>> >> >> >> >>> >>  - Object representations should be as flat as possible
>>> >> >> >> >>> >> and separate requests should be made to nested resources to
>>> >> get
>>> >> >> >> nested
>>> >> >> >> >>> >> details (i.e. if you have regions and
>>> regions/1/regionwidgets,
>>> >> >> the
>>> >> >> >> >>> regions
>>> >> >> >> >>> >> representation should not contain an array of
>>> regionwidgets)
>>> >> >> >> >>> >>
>>> >> >> >> >>> >
>>> >> >> >> >>> > I am concerned about the round trips to support this when
>>> >> >> rendering
>>> >> >> >> the
>>> >> >> >> >>> > page.  With any page that has a sufficient number of
>>> gadgets,
>>> >> >> adding
>>> >> >> >> to
>>> >> >> >> >>> the
>>> >> >> >> >>> > number of requests becomes problematic.
>>> >> >> >> >>> >
>>> >> >> >> >>>
>>> >> >> >> >>> I see that rule applying to the "standard" rest endpoints for
>>> >> crud
>>> >> >> >> >>> operations on resources. We
>>> >>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Awesome, thanks Chris. Not sure I would have ever figured that one out...

On Sun, Jul 21, 2013 at 3:59 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> Erin,
>
> I got it working, at least the CXF part. Couple things:
>
> 1) In the interface, make sure to annotate the @GET methods
> 2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
> attributes from variable signatures. I know Intellij puts those in there
> but they cause problems. Only the interface should be annotated.
>
> Chris
>
>
> On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> Review board is not accepting my patch and is not accepting the valid
>> file paths. I have attached the patch as a file to the review.
>>
>> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> > Erin, I'm not seeing a patch posted up there.
>> >
>> >
>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >
>> >> I was never able to hit the endpoint as expected. I've posted the
>> >> patch on the review board if anyone can take a look and offer advice -
>> >> https://reviews.apache.org/r/12777/.
>> >>
>> >> Thanks
>> >>
>> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >> >
>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
>> >> <javascript:;>>
>> >> >> wrote:
>> >> >> > In the xml file you need to create the bean, then reference it in
>> the
>> >> >> > server element near the top. Other than that...no, that should be
>> >> all. I
>> >> >> > assume you set the Path attribute on the resource.
>> >> >> >
>> >> >> I did. I'm also messing around with the service injection, which may
>> >> >> be the issue. Haven't gotten it to work yet though.
>> >> >>
>> >> >> > I thought we were going to do
>> >> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> >> > since it makes no sense to manage a region widget outside a region
>> >> >> outside
>> >> >> > a page?
>> >> >>  Possibly. Right now I'm just trying to do a proof of concept with
>> the
>> >> >> wrapped json object so I picked something simple with the service and
>> >> >> rest models already in place.
>> >> >>
>> >> >> In general though I don't see any value to dealing with region
>> widgets
>> >> >> as a nested resource (pages/:id/regions/:id...) over just dealing
>> with
>> >> >> them directly. It's just adding weight to the pages controller,
>> rather
>> >> >> than breaking them up and dealing with resource concerns separately.
>> >> >>
>> >> >> I get what you're saying about regions and regionwidgets only making
>> >> >> sense in the context of a page, but you could say the same thing for
>> >> >> any 1-many associated resource. Both entities are always uniquely
>> >> >> identified, so why not deal with them individually? I see an upside
>> of
>> >> >> simpler code, consistent api endpoints, and I see no downside.
>> >> >
>> >> >
>> >> > Honestly, my hope is that someday they aren't uniquely identified and
>> are
>> >> > really sun objects unlike JPA today. But that is a longer
>> conversation.
>> >> >
>> >> >>
>> >> >> >
>> >> >> >
>> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> >> > <er...@gmail.com>wrote:
>> >> >> >
>> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
>> added
>> >> >> >> the interface and default implementation, and created / registered
>> >> the
>> >> >> >> bean in cxf-applicationContext.xml.
>> >> >> >>
>> >> >> >> However, when I hit the endpoint I get an error:
>> >> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
>> request
>> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path:
>> /1,
>> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> >> Please enable FINE/TRACE log level for more details.
>> >> >> >>
>> >> >> >> Is there anything else I need to do in order to create and
>> register a
>> >> >> >> new endpoint?
>> >> >> >>
>> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >> >> <er...@gmail.com> wrote:
>> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> >> chris@cxtsoftware.com>
>> >> >> >> wrote:
>> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >> >>
>> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> >> >> m.ben.franklin@gmail.com>
>> >> >> >> >>> wrote:
>> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >> >> chris@cxtsoftware.com>
>> >> >> >> >>> wrote:
>> >> >> >> >>> >
>> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >> >>> >>
>> >> >> >> >>> >> > Any further discussion here? I would like to start
>> >> implementing
>> >> >> >> more
>> >> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
>> >> angular
>> >> >> >> >>> >> > architecture.
>> >> >> >> >>> >> >
>> >> >> >> >>> >> > My understanding from Matt is that the current apis in
>> trunk
>> >> >> are
>> >> >> >> >>> >> > mostly proof of concept - they are not tested and much of
>> >> the
>> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
>> >> >> >> implementations
>> >> >> >> >>> >> > in the code base a good working example? Is there other
>> >> >> >> documentation
>> >> >> >> >>> >> > we can reference?
>> >> >> >> >>> >> >
>> >> >> >> >>> >>
>> >> >> >> >>> >> I've been working on the People resource as a "reference"
>> of
>> >> how
>> >> >> I'd
>> >> >> >> >>> like
>> >> >> >> >>> >> to see them done but it's still a work in progress. I need
>> to
>> >> go
>> >> >> >> back
>> >> >> >> >>> and
>> >> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
>> >> concept.
>> >> >> >> >>> Couple of
>> >> >> >> >>> >> notes:
>> >> >> >> >>> >>
>> >> >> >> >>> >>  - Object representations should be as flat as possible
>> >> >> >> >>> >> and separate requests should be made to nested resources to
>> >> get
>> >> >> >> nested
>> >> >> >> >>> >> details (i.e. if you have regions and
>> regions/1/regionwidgets,
>> >> >> the
>> >> >> >> >>> regions
>> >> >> >> >>> >> representation should not contain an array of
>> regionwidgets)
>> >> >> >> >>> >>
>> >> >> >> >>> >
>> >> >> >> >>> > I am concerned about the round trips to support this when
>> >> >> rendering
>> >> >> >> the
>> >> >> >> >>> > page.  With any page that has a sufficient number of
>> gadgets,
>> >> >> adding
>> >> >> >> to
>> >> >> >> >>> the
>> >> >> >> >>> > number of requests becomes problematic.
>> >> >> >> >>> >
>> >> >> >> >>>
>> >> >> >> >>> I see that rule applying to the "standard" rest endpoints for
>> >> crud
>> >> >> >> >>> operations on resources. We
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
Erin,

I got it working, at least the CXF part. Couple things:

1) In the interface, make sure to annotate the @GET methods
2) In your DefaultRegionWidgetsResource class, remove the @ParamPath
attributes from variable signatures. I know Intellij puts those in there
but they cause problems. Only the interface should be annotated.

Chris


On Sat, Jul 20, 2013 at 2:00 PM, Erin Noe-Payne <er...@gmail.com>wrote:

> Review board is not accepting my patch and is not accepting the valid
> file paths. I have attached the patch as a file to the review.
>
> On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> > Erin, I'm not seeing a patch posted up there.
> >
> >
> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >
> >> I was never able to hit the endpoint as expected. I've posted the
> >> patch on the review board if anyone can take a look and offer advice -
> >> https://reviews.apache.org/r/12777/.
> >>
> >> Thanks
> >>
> >> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >> >
> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
> >> <javascript:;>>
> >> >> wrote:
> >> >> > In the xml file you need to create the bean, then reference it in
> the
> >> >> > server element near the top. Other than that...no, that should be
> >> all. I
> >> >> > assume you set the Path attribute on the resource.
> >> >> >
> >> >> I did. I'm also messing around with the service injection, which may
> >> >> be the issue. Haven't gotten it to work yet though.
> >> >>
> >> >> > I thought we were going to do
> >> pages/<id>/regions/<id>/regionwidgets/<id>
> >> >> > since it makes no sense to manage a region widget outside a region
> >> >> outside
> >> >> > a page?
> >> >>  Possibly. Right now I'm just trying to do a proof of concept with
> the
> >> >> wrapped json object so I picked something simple with the service and
> >> >> rest models already in place.
> >> >>
> >> >> In general though I don't see any value to dealing with region
> widgets
> >> >> as a nested resource (pages/:id/regions/:id...) over just dealing
> with
> >> >> them directly. It's just adding weight to the pages controller,
> rather
> >> >> than breaking them up and dealing with resource concerns separately.
> >> >>
> >> >> I get what you're saying about regions and regionwidgets only making
> >> >> sense in the context of a page, but you could say the same thing for
> >> >> any 1-many associated resource. Both entities are always uniquely
> >> >> identified, so why not deal with them individually? I see an upside
> of
> >> >> simpler code, consistent api endpoints, and I see no downside.
> >> >
> >> >
> >> > Honestly, my hope is that someday they aren't uniquely identified and
> are
> >> > really sun objects unlike JPA today. But that is a longer
> conversation.
> >> >
> >> >>
> >> >> >
> >> >> >
> >> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> >> > <er...@gmail.com>wrote:
> >> >> >
> >> >> >> I'm trying to register a new endpoint for regionWidgets. I've
> added
> >> >> >> the interface and default implementation, and created / registered
> >> the
> >> >> >> bean in cxf-applicationContext.xml.
> >> >> >>
> >> >> >> However, when I hit the endpoint I get an error:
> >> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching
> request
> >> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path:
> /1,
> >> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> >> Please enable FINE/TRACE log level for more details.
> >> >> >>
> >> >> >> Is there anything else I need to do in order to create and
> register a
> >> >> >> new endpoint?
> >> >> >>
> >> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >> >> <er...@gmail.com> wrote:
> >> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> >> chris@cxtsoftware.com>
> >> >> >> wrote:
> >> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >> >>
> >> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> >> >> m.ben.franklin@gmail.com>
> >> >> >> >>> wrote:
> >> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >> >> chris@cxtsoftware.com>
> >> >> >> >>> wrote:
> >> >> >> >>> >
> >> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >> >>> >>
> >> >> >> >>> >> > Any further discussion here? I would like to start
> >> implementing
> >> >> >> more
> >> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
> >> angular
> >> >> >> >>> >> > architecture.
> >> >> >> >>> >> >
> >> >> >> >>> >> > My understanding from Matt is that the current apis in
> trunk
> >> >> are
> >> >> >> >>> >> > mostly proof of concept - they are not tested and much of
> >> the
> >> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
> >> >> >> implementations
> >> >> >> >>> >> > in the code base a good working example? Is there other
> >> >> >> documentation
> >> >> >> >>> >> > we can reference?
> >> >> >> >>> >> >
> >> >> >> >>> >>
> >> >> >> >>> >> I've been working on the People resource as a "reference"
> of
> >> how
> >> >> I'd
> >> >> >> >>> like
> >> >> >> >>> >> to see them done but it's still a work in progress. I need
> to
> >> go
> >> >> >> back
> >> >> >> >>> and
> >> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
> >> concept.
> >> >> >> >>> Couple of
> >> >> >> >>> >> notes:
> >> >> >> >>> >>
> >> >> >> >>> >>  - Object representations should be as flat as possible
> >> >> >> >>> >> and separate requests should be made to nested resources to
> >> get
> >> >> >> nested
> >> >> >> >>> >> details (i.e. if you have regions and
> regions/1/regionwidgets,
> >> >> the
> >> >> >> >>> regions
> >> >> >> >>> >> representation should not contain an array of
> regionwidgets)
> >> >> >> >>> >>
> >> >> >> >>> >
> >> >> >> >>> > I am concerned about the round trips to support this when
> >> >> rendering
> >> >> >> the
> >> >> >> >>> > page.  With any page that has a sufficient number of
> gadgets,
> >> >> adding
> >> >> >> to
> >> >> >> >>> the
> >> >> >> >>> > number of requests becomes problematic.
> >> >> >> >>> >
> >> >> >> >>>
> >> >> >> >>> I see that rule applying to the "standard" rest endpoints for
> >> crud
> >> >> >> >>> operations on resources. We
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Review board is not accepting my patch and is not accepting the valid
file paths. I have attached the patch as a file to the review.

On Sat, Jul 20, 2013 at 4:40 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> Erin, I'm not seeing a patch posted up there.
>
>
> On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> I was never able to hit the endpoint as expected. I've posted the
>> patch on the review board if anyone can take a look and offer advice -
>> https://reviews.apache.org/r/12777/.
>>
>> Thanks
>>
>> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
>> >
>> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
>> <javascript:;>>
>> >> wrote:
>> >> > In the xml file you need to create the bean, then reference it in the
>> >> > server element near the top. Other than that...no, that should be
>> all. I
>> >> > assume you set the Path attribute on the resource.
>> >> >
>> >> I did. I'm also messing around with the service injection, which may
>> >> be the issue. Haven't gotten it to work yet though.
>> >>
>> >> > I thought we were going to do
>> pages/<id>/regions/<id>/regionwidgets/<id>
>> >> > since it makes no sense to manage a region widget outside a region
>> >> outside
>> >> > a page?
>> >>  Possibly. Right now I'm just trying to do a proof of concept with the
>> >> wrapped json object so I picked something simple with the service and
>> >> rest models already in place.
>> >>
>> >> In general though I don't see any value to dealing with region widgets
>> >> as a nested resource (pages/:id/regions/:id...) over just dealing with
>> >> them directly. It's just adding weight to the pages controller, rather
>> >> than breaking them up and dealing with resource concerns separately.
>> >>
>> >> I get what you're saying about regions and regionwidgets only making
>> >> sense in the context of a page, but you could say the same thing for
>> >> any 1-many associated resource. Both entities are always uniquely
>> >> identified, so why not deal with them individually? I see an upside of
>> >> simpler code, consistent api endpoints, and I see no downside.
>> >
>> >
>> > Honestly, my hope is that someday they aren't uniquely identified and are
>> > really sun objects unlike JPA today. But that is a longer conversation.
>> >
>> >>
>> >> >
>> >> >
>> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> >> > <er...@gmail.com>wrote:
>> >> >
>> >> >> I'm trying to register a new endpoint for regionWidgets. I've added
>> >> >> the interface and default implementation, and created / registered
>> the
>> >> >> bean in cxf-applicationContext.xml.
>> >> >>
>> >> >> However, when I hit the endpoint I get an error:
>> >> >> [INFO] [talledLocalContainer] WARN :
>> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
>> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
>> >> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> >> Please enable FINE/TRACE log level for more details.
>> >> >>
>> >> >> Is there anything else I need to do in order to create and register a
>> >> >> new endpoint?
>> >> >>
>> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> >> <er...@gmail.com> wrote:
>> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >> >> wrote:
>> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> >> erin.noe.payne@gmail.com>wrote:
>> >> >> >>
>> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> >> m.ben.franklin@gmail.com>
>> >> >> >>> wrote:
>> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> >> chris@cxtsoftware.com>
>> >> >> >>> wrote:
>> >> >> >>> >
>> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> >> >>> >> <er...@gmail.com>wrote:
>> >> >> >>> >>
>> >> >> >>> >> > Any further discussion here? I would like to start
>> implementing
>> >> >> more
>> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
>> angular
>> >> >> >>> >> > architecture.
>> >> >> >>> >> >
>> >> >> >>> >> > My understanding from Matt is that the current apis in trunk
>> >> are
>> >> >> >>> >> > mostly proof of concept - they are not tested and much of
>> the
>> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
>> >> >> implementations
>> >> >> >>> >> > in the code base a good working example? Is there other
>> >> >> documentation
>> >> >> >>> >> > we can reference?
>> >> >> >>> >> >
>> >> >> >>> >>
>> >> >> >>> >> I've been working on the People resource as a "reference" of
>> how
>> >> I'd
>> >> >> >>> like
>> >> >> >>> >> to see them done but it's still a work in progress. I need to
>> go
>> >> >> back
>> >> >> >>> and
>> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
>> concept.
>> >> >> >>> Couple of
>> >> >> >>> >> notes:
>> >> >> >>> >>
>> >> >> >>> >>  - Object representations should be as flat as possible
>> >> >> >>> >> and separate requests should be made to nested resources to
>> get
>> >> >> nested
>> >> >> >>> >> details (i.e. if you have regions and regions/1/regionwidgets,
>> >> the
>> >> >> >>> regions
>> >> >> >>> >> representation should not contain an array of regionwidgets)
>> >> >> >>> >>
>> >> >> >>> >
>> >> >> >>> > I am concerned about the round trips to support this when
>> >> rendering
>> >> >> the
>> >> >> >>> > page.  With any page that has a sufficient number of gadgets,
>> >> adding
>> >> >> to
>> >> >> >>> the
>> >> >> >>> > number of requests becomes problematic.
>> >> >> >>> >
>> >> >> >>>
>> >> >> >>> I see that rule applying to the "standard" rest endpoints for
>> crud
>> >> >> >>> operations on resources. We
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
Erin, I'm not seeing a patch posted up there.


On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne <er...@gmail.com>wrote:

> I was never able to hit the endpoint as expected. I've posted the
> patch on the review board if anyone can take a look and offer advice -
> https://reviews.apache.org/r/12777/.
>
> Thanks
>
> On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> > On Friday, July 19, 2013, Erin Noe-Payne wrote:
> >
> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com
> <javascript:;>>
> >> wrote:
> >> > In the xml file you need to create the bean, then reference it in the
> >> > server element near the top. Other than that...no, that should be
> all. I
> >> > assume you set the Path attribute on the resource.
> >> >
> >> I did. I'm also messing around with the service injection, which may
> >> be the issue. Haven't gotten it to work yet though.
> >>
> >> > I thought we were going to do
> pages/<id>/regions/<id>/regionwidgets/<id>
> >> > since it makes no sense to manage a region widget outside a region
> >> outside
> >> > a page?
> >>  Possibly. Right now I'm just trying to do a proof of concept with the
> >> wrapped json object so I picked something simple with the service and
> >> rest models already in place.
> >>
> >> In general though I don't see any value to dealing with region widgets
> >> as a nested resource (pages/:id/regions/:id...) over just dealing with
> >> them directly. It's just adding weight to the pages controller, rather
> >> than breaking them up and dealing with resource concerns separately.
> >>
> >> I get what you're saying about regions and regionwidgets only making
> >> sense in the context of a page, but you could say the same thing for
> >> any 1-many associated resource. Both entities are always uniquely
> >> identified, so why not deal with them individually? I see an upside of
> >> simpler code, consistent api endpoints, and I see no downside.
> >
> >
> > Honestly, my hope is that someday they aren't uniquely identified and are
> > really sun objects unlike JPA today. But that is a longer conversation.
> >
> >>
> >> >
> >> >
> >> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> >> > <er...@gmail.com>wrote:
> >> >
> >> >> I'm trying to register a new endpoint for regionWidgets. I've added
> >> >> the interface and default implementation, and created / registered
> the
> >> >> bean in cxf-applicationContext.xml.
> >> >>
> >> >> However, when I hit the endpoint I get an error:
> >> >> [INFO] [talledLocalContainer] WARN :
> >> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
> >> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
> >> >> HTTP Method: GET, ContentType: */*, Accept:
> >> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> >> Please enable FINE/TRACE log level for more details.
> >> >>
> >> >> Is there anything else I need to do in order to create and register a
> >> >> new endpoint?
> >> >>
> >> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> >> <er...@gmail.com> wrote:
> >> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <
> chris@cxtsoftware.com>
> >> >> wrote:
> >> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> >> erin.noe.payne@gmail.com>wrote:
> >> >> >>
> >> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> >> m.ben.franklin@gmail.com>
> >> >> >>> wrote:
> >> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> >> chris@cxtsoftware.com>
> >> >> >>> wrote:
> >> >> >>> >
> >> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> >> >>> >> <er...@gmail.com>wrote:
> >> >> >>> >>
> >> >> >>> >> > Any further discussion here? I would like to start
> implementing
> >> >> more
> >> >> >>> >> > of the REST APIs, as it is foundational for the entire
> angular
> >> >> >>> >> > architecture.
> >> >> >>> >> >
> >> >> >>> >> > My understanding from Matt is that the current apis in trunk
> >> are
> >> >> >>> >> > mostly proof of concept - they are not tested and much of
> the
> >> >> >>> >> > functionality is just stubbed. Are any of the rest api
> >> >> implementations
> >> >> >>> >> > in the code base a good working example? Is there other
> >> >> documentation
> >> >> >>> >> > we can reference?
> >> >> >>> >> >
> >> >> >>> >>
> >> >> >>> >> I've been working on the People resource as a "reference" of
> how
> >> I'd
> >> >> >>> like
> >> >> >>> >> to see them done but it's still a work in progress. I need to
> go
> >> >> back
> >> >> >>> and
> >> >> >>> >> pull out the JSONView stuff and reimplement the "fields"
> concept.
> >> >> >>> Couple of
> >> >> >>> >> notes:
> >> >> >>> >>
> >> >> >>> >>  - Object representations should be as flat as possible
> >> >> >>> >> and separate requests should be made to nested resources to
> get
> >> >> nested
> >> >> >>> >> details (i.e. if you have regions and regions/1/regionwidgets,
> >> the
> >> >> >>> regions
> >> >> >>> >> representation should not contain an array of regionwidgets)
> >> >> >>> >>
> >> >> >>> >
> >> >> >>> > I am concerned about the round trips to support this when
> >> rendering
> >> >> the
> >> >> >>> > page.  With any page that has a sufficient number of gadgets,
> >> adding
> >> >> to
> >> >> >>> the
> >> >> >>> > number of requests becomes problematic.
> >> >> >>> >
> >> >> >>>
> >> >> >>> I see that rule applying to the "standard" rest endpoints for
> crud
> >> >> >>> operations on resources. We
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
I was never able to hit the endpoint as expected. I've posted the
patch on the review board if anyone can take a look and offer advice -
https://reviews.apache.org/r/12777/.

Thanks

On Fri, Jul 19, 2013 at 2:41 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Friday, July 19, 2013, Erin Noe-Payne wrote:
>
>> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com<javascript:;>>
>> wrote:
>> > In the xml file you need to create the bean, then reference it in the
>> > server element near the top. Other than that...no, that should be all. I
>> > assume you set the Path attribute on the resource.
>> >
>> I did. I'm also messing around with the service injection, which may
>> be the issue. Haven't gotten it to work yet though.
>>
>> > I thought we were going to do pages/<id>/regions/<id>/regionwidgets/<id>
>> > since it makes no sense to manage a region widget outside a region
>> outside
>> > a page?
>>  Possibly. Right now I'm just trying to do a proof of concept with the
>> wrapped json object so I picked something simple with the service and
>> rest models already in place.
>>
>> In general though I don't see any value to dealing with region widgets
>> as a nested resource (pages/:id/regions/:id...) over just dealing with
>> them directly. It's just adding weight to the pages controller, rather
>> than breaking them up and dealing with resource concerns separately.
>>
>> I get what you're saying about regions and regionwidgets only making
>> sense in the context of a page, but you could say the same thing for
>> any 1-many associated resource. Both entities are always uniquely
>> identified, so why not deal with them individually? I see an upside of
>> simpler code, consistent api endpoints, and I see no downside.
>
>
> Honestly, my hope is that someday they aren't uniquely identified and are
> really sun objects unlike JPA today. But that is a longer conversation.
>
>>
>> >
>> >
>> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
>> > <er...@gmail.com>wrote:
>> >
>> >> I'm trying to register a new endpoint for regionWidgets. I've added
>> >> the interface and default implementation, and created / registered the
>> >> bean in cxf-applicationContext.xml.
>> >>
>> >> However, when I hit the endpoint I get an error:
>> >> [INFO] [talledLocalContainer] WARN :
>> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
>> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
>> >> HTTP Method: GET, ContentType: */*, Accept:
>> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> >> Please enable FINE/TRACE log level for more details.
>> >>
>> >> Is there anything else I need to do in order to create and register a
>> >> new endpoint?
>> >>
>> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> >> <er...@gmail.com> wrote:
>> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com>
>> >> wrote:
>> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> >> erin.noe.payne@gmail.com>wrote:
>> >> >>
>> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> >> m.ben.franklin@gmail.com>
>> >> >>> wrote:
>> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
>> chris@cxtsoftware.com>
>> >> >>> wrote:
>> >> >>> >
>> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> >>> >> <er...@gmail.com>wrote:
>> >> >>> >>
>> >> >>> >> > Any further discussion here? I would like to start implementing
>> >> more
>> >> >>> >> > of the REST APIs, as it is foundational for the entire angular
>> >> >>> >> > architecture.
>> >> >>> >> >
>> >> >>> >> > My understanding from Matt is that the current apis in trunk
>> are
>> >> >>> >> > mostly proof of concept - they are not tested and much of the
>> >> >>> >> > functionality is just stubbed. Are any of the rest api
>> >> implementations
>> >> >>> >> > in the code base a good working example? Is there other
>> >> documentation
>> >> >>> >> > we can reference?
>> >> >>> >> >
>> >> >>> >>
>> >> >>> >> I've been working on the People resource as a "reference" of how
>> I'd
>> >> >>> like
>> >> >>> >> to see them done but it's still a work in progress. I need to go
>> >> back
>> >> >>> and
>> >> >>> >> pull out the JSONView stuff and reimplement the "fields" concept.
>> >> >>> Couple of
>> >> >>> >> notes:
>> >> >>> >>
>> >> >>> >>  - Object representations should be as flat as possible
>> >> >>> >> and separate requests should be made to nested resources to get
>> >> nested
>> >> >>> >> details (i.e. if you have regions and regions/1/regionwidgets,
>> the
>> >> >>> regions
>> >> >>> >> representation should not contain an array of regionwidgets)
>> >> >>> >>
>> >> >>> >
>> >> >>> > I am concerned about the round trips to support this when
>> rendering
>> >> the
>> >> >>> > page.  With any page that has a sufficient number of gadgets,
>> adding
>> >> to
>> >> >>> the
>> >> >>> > number of requests becomes problematic.
>> >> >>> >
>> >> >>>
>> >> >>> I see that rule applying to the "standard" rest endpoints for crud
>> >> >>> operations on resources. We

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Friday, July 19, 2013, Erin Noe-Payne wrote:

> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <chris@cxtsoftware.com<javascript:;>>
> wrote:
> > In the xml file you need to create the bean, then reference it in the
> > server element near the top. Other than that...no, that should be all. I
> > assume you set the Path attribute on the resource.
> >
> I did. I'm also messing around with the service injection, which may
> be the issue. Haven't gotten it to work yet though.
>
> > I thought we were going to do pages/<id>/regions/<id>/regionwidgets/<id>
> > since it makes no sense to manage a region widget outside a region
> outside
> > a page?
>  Possibly. Right now I'm just trying to do a proof of concept with the
> wrapped json object so I picked something simple with the service and
> rest models already in place.
>
> In general though I don't see any value to dealing with region widgets
> as a nested resource (pages/:id/regions/:id...) over just dealing with
> them directly. It's just adding weight to the pages controller, rather
> than breaking them up and dealing with resource concerns separately.
>
> I get what you're saying about regions and regionwidgets only making
> sense in the context of a page, but you could say the same thing for
> any 1-many associated resource. Both entities are always uniquely
> identified, so why not deal with them individually? I see an upside of
> simpler code, consistent api endpoints, and I see no downside.


Honestly, my hope is that someday they aren't uniquely identified and are
really sun objects unlike JPA today. But that is a longer conversation.

>
> >
> >
> > On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> > <er...@gmail.com>wrote:
> >
> >> I'm trying to register a new endpoint for regionWidgets. I've added
> >> the interface and default implementation, and created / registered the
> >> bean in cxf-applicationContext.xml.
> >>
> >> However, when I hit the endpoint I get an error:
> >> [INFO] [talledLocalContainer] WARN :
> >> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
> >> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
> >> HTTP Method: GET, ContentType: */*, Accept:
> >> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> >> Please enable FINE/TRACE log level for more details.
> >>
> >> Is there anything else I need to do in order to create and register a
> >> new endpoint?
> >>
> >> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> >> <er...@gmail.com> wrote:
> >> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com>
> >> wrote:
> >> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> >> erin.noe.payne@gmail.com>wrote:
> >> >>
> >> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> >> m.ben.franklin@gmail.com>
> >> >>> wrote:
> >> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <
> chris@cxtsoftware.com>
> >> >>> wrote:
> >> >>> >
> >> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> >>> >> <er...@gmail.com>wrote:
> >> >>> >>
> >> >>> >> > Any further discussion here? I would like to start implementing
> >> more
> >> >>> >> > of the REST APIs, as it is foundational for the entire angular
> >> >>> >> > architecture.
> >> >>> >> >
> >> >>> >> > My understanding from Matt is that the current apis in trunk
> are
> >> >>> >> > mostly proof of concept - they are not tested and much of the
> >> >>> >> > functionality is just stubbed. Are any of the rest api
> >> implementations
> >> >>> >> > in the code base a good working example? Is there other
> >> documentation
> >> >>> >> > we can reference?
> >> >>> >> >
> >> >>> >>
> >> >>> >> I've been working on the People resource as a "reference" of how
> I'd
> >> >>> like
> >> >>> >> to see them done but it's still a work in progress. I need to go
> >> back
> >> >>> and
> >> >>> >> pull out the JSONView stuff and reimplement the "fields" concept.
> >> >>> Couple of
> >> >>> >> notes:
> >> >>> >>
> >> >>> >>  - Object representations should be as flat as possible
> >> >>> >> and separate requests should be made to nested resources to get
> >> nested
> >> >>> >> details (i.e. if you have regions and regions/1/regionwidgets,
> the
> >> >>> regions
> >> >>> >> representation should not contain an array of regionwidgets)
> >> >>> >>
> >> >>> >
> >> >>> > I am concerned about the round trips to support this when
> rendering
> >> the
> >> >>> > page.  With any page that has a sufficient number of gadgets,
> adding
> >> to
> >> >>> the
> >> >>> > number of requests becomes problematic.
> >> >>> >
> >> >>>
> >> >>> I see that rule applying to the "standard" rest endpoints for crud
> >> >>> operations on resources. We

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> In the xml file you need to create the bean, then reference it in the
> server element near the top. Other than that...no, that should be all. I
> assume you set the Path attribute on the resource.
>
I did. I'm also messing around with the service injection, which may
be the issue. Haven't gotten it to work yet though.

> I thought we were going to do pages/<id>/regions/<id>/regionwidgets/<id>
> since it makes no sense to manage a region widget outside a region outside
> a page?
 Possibly. Right now I'm just trying to do a proof of concept with the
wrapped json object so I picked something simple with the service and
rest models already in place.

In general though I don't see any value to dealing with region widgets
as a nested resource (pages/:id/regions/:id...) over just dealing with
them directly. It's just adding weight to the pages controller, rather
than breaking them up and dealing with resource concerns separately.

I get what you're saying about regions and regionwidgets only making
sense in the context of a page, but you could say the same thing for
any 1-many associated resource. Both entities are always uniquely
identified, so why not deal with them individually? I see an upside of
simpler code, consistent api endpoints, and I see no downside.

>
>
> On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
>> I'm trying to register a new endpoint for regionWidgets. I've added
>> the interface and default implementation, and created / registered the
>> bean in cxf-applicationContext.xml.
>>
>> However, when I hit the endpoint I get an error:
>> [INFO] [talledLocalContainer] WARN :
>> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
>> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
>> HTTP Method: GET, ContentType: */*, Accept:
>> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
>> Please enable FINE/TRACE log level for more details.
>>
>> Is there anything else I need to do in order to create and register a
>> new endpoint?
>>
>> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
>> <er...@gmail.com> wrote:
>> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
>> erin.noe.payne@gmail.com>wrote:
>> >>
>> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
>> m.ben.franklin@gmail.com>
>> >>> wrote:
>> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
>> >>> wrote:
>> >>> >
>> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >>> >> <er...@gmail.com>wrote:
>> >>> >>
>> >>> >> > Any further discussion here? I would like to start implementing
>> more
>> >>> >> > of the REST APIs, as it is foundational for the entire angular
>> >>> >> > architecture.
>> >>> >> >
>> >>> >> > My understanding from Matt is that the current apis in trunk are
>> >>> >> > mostly proof of concept - they are not tested and much of the
>> >>> >> > functionality is just stubbed. Are any of the rest api
>> implementations
>> >>> >> > in the code base a good working example? Is there other
>> documentation
>> >>> >> > we can reference?
>> >>> >> >
>> >>> >>
>> >>> >> I've been working on the People resource as a "reference" of how I'd
>> >>> like
>> >>> >> to see them done but it's still a work in progress. I need to go
>> back
>> >>> and
>> >>> >> pull out the JSONView stuff and reimplement the "fields" concept.
>> >>> Couple of
>> >>> >> notes:
>> >>> >>
>> >>> >>  - Object representations should be as flat as possible
>> >>> >> and separate requests should be made to nested resources to get
>> nested
>> >>> >> details (i.e. if you have regions and regions/1/regionwidgets, the
>> >>> regions
>> >>> >> representation should not contain an array of regionwidgets)
>> >>> >>
>> >>> >
>> >>> > I am concerned about the round trips to support this when rendering
>> the
>> >>> > page.  With any page that has a sufficient number of gadgets, adding
>> to
>> >>> the
>> >>> > number of requests becomes problematic.
>> >>> >
>> >>>
>> >>> I see that rule applying to the "standard" rest endpoints for crud
>> >>> operations on resources. We will have some number of special endpoints
>> >>> to support frequently used operations of clients. The major example
>> >>> there is the page / pages for render endpoint, which will include the
>> >>> nested regions, regionwidgets, and their rpc tokens, etc.
>> >>>
>> >>
>> >> +1
>> >
>> > So my thought is that we have the standard crud endpoints for all
>> > individual resources. For frequently-used read operations in which we
>> > need composite data sets we will have a small number of custom
>> > endpoints to serve that data. Those are read-only endpoints, they will
>> > not support create / update / delete operations.
>> >
>> > At a time when we need one of our composite data views, such as on a
>> > page load, the client will make a request and get the composite data -
>> > page, regions, regionwidgets and so on. The client can decompose those
>> > into the individual component resources which have corresponding
>> > angular $resource services, and which talk to the standard endpoints
>> > to support further crud operations on them.
>> >
>> > Make sense / thoughts?
>> >
>> >>
>> >>>
>> >>> >
>> >>> >>  - All methods should return standard HTTP codes. We should document
>> >>> this
>> >>> >> further on the wiki to make sure we all do the same way.
>> >>> >>  - We won't accept partial updates with PUT, we will eventually add
>> >>> PATCH
>> >>> >> to support that in the future
>> >>> >>  - If the "fields" query attribute isn't included in a GET then all
>> >>> fields
>> >>> >> are returned.
>> >>> >>  - What is the full meta structure we want to return?
>> >>> >>
>> >>> >>
>> >>> >> >
>> >>> >> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>> >>> >> > <er...@gmail.com> wrote:
>> >>> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
>> >>> >> m.ben.franklin@gmail.com>
>> >>> >> > wrote:
>> >>> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
>> >>> >> > >>
>> >>> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <
>> chris@cxtsoftware.com
>> >>> >
>> >>> >> > wrote:
>> >>> >> > >>
>> >>> >> > >>> 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
>> >>> >> > >
>> >>> >> > > Well the development in trunk can continue to happen on /rest.
>> >>> Angular
>> >>> >> > > (aka the consuming client for most of these apis) is already
>> >>> happening
>> >>> >> > > in a branch, so those changes can be treated as a rip / replace
>> >>> >> > > easily.
>> >>> >> > >
>> >>> >> > >>>
>> >>> >> > >>> >
>> >>> >> > >>> > 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
>> >>> >> > >
>> >>> >> > > My understanding is that PUT should always be a full object
>> >>> replace. A
>> >>> >> > > quick search returns the suggestion to use PATCH, or to use
>> POST to
>> >>> a
>> >>> >> > > subresource with a 303 response.
>> >>> >> > >
>> >>> >> > >>
>> >>> >> > >>>
>> >>> >> > >>> >
>> >>> >> > >>> > 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.
>> >>> >> > >>
>> >>> >> > >
>> >>> >> > > Fair enough. In this case I guess I would just be looking for
>> >>> >> > > consistency - will associations be infinitely nest-able. If not,
>> >>> what
>> >>> >> > > is the rule to determine where we support more or less deeply
>> nested
>> >>> >> > > associations.
>> >>> >> > >
>> >>> >> > >>
>> >>> >> > >>> >
>> >>> >> > >>> > 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?
>> >>> >> > >>>
>> >>> >> > >
>> >>> >> > > We could possibly achieve the same with HTTP headers. I prefer
>> the
>> >>> >> > > object approach for clarity, since custom http headers are less
>> >>> >> > > accessible or discoverable than object structure. I get your
>> point,
>> >>> >> > > but I see the wrapped object approach used commonly in major
>> apis.
>> >>> If
>> >>> >> > > it's clearly documented and used consistently across the entire
>> api
>> >>> I
>> >>> >> > > don't really see an issue.
>> >>> >> > >
>> >>> >> > >>> >
>> >>> >> > >>> > 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.
>> >>> >> > >>
>> >>> >> > >>
>> >>> >> > >
>> >>> >> > > I don't really know what the implementation looks like. If you
>> allow
>> >>> >> > > field filtering only on properties and deliver only properties
>> (i.e.
>> >>> >> > > no nested objects / associations) then I would assume it is
>> pretty
>> >>> >> > > straightforward.
>> >>> >> > >>>
>> >>> >> > >>> >
>> >>> >> > >>> > 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?
>> >>> >> > >>> >
>> >>> >> > >>>
>> >>> >> >
>> >>> >>
>> >>>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
In the xml file you need to create the bean, then reference it in the
server element near the top. Other than that...no, that should be all. I
assume you set the Path attribute on the resource.

I thought we were going to do pages/<id>/regions/<id>/regionwidgets/<id>
since it makes no sense to manage a region widget outside a region outside
a page?


On Fri, Jul 19, 2013 at 10:16 AM, Erin Noe-Payne
<er...@gmail.com>wrote:

> I'm trying to register a new endpoint for regionWidgets. I've added
> the interface and default implementation, and created / registered the
> bean in cxf-applicationContext.xml.
>
> However, when I hit the endpoint I get an error:
> [INFO] [talledLocalContainer] WARN :
> org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
> path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
> HTTP Method: GET, ContentType: */*, Accept:
> text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
> Please enable FINE/TRACE log level for more details.
>
> Is there anything else I need to do in order to create and register a
> new endpoint?
>
> On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <
> erin.noe.payne@gmail.com>wrote:
> >>
> >>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <
> m.ben.franklin@gmail.com>
> >>> wrote:
> >>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
> >>> wrote:
> >>> >
> >>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >>> >> <er...@gmail.com>wrote:
> >>> >>
> >>> >> > Any further discussion here? I would like to start implementing
> more
> >>> >> > of the REST APIs, as it is foundational for the entire angular
> >>> >> > architecture.
> >>> >> >
> >>> >> > My understanding from Matt is that the current apis in trunk are
> >>> >> > mostly proof of concept - they are not tested and much of the
> >>> >> > functionality is just stubbed. Are any of the rest api
> implementations
> >>> >> > in the code base a good working example? Is there other
> documentation
> >>> >> > we can reference?
> >>> >> >
> >>> >>
> >>> >> I've been working on the People resource as a "reference" of how I'd
> >>> like
> >>> >> to see them done but it's still a work in progress. I need to go
> back
> >>> and
> >>> >> pull out the JSONView stuff and reimplement the "fields" concept.
> >>> Couple of
> >>> >> notes:
> >>> >>
> >>> >>  - Object representations should be as flat as possible
> >>> >> and separate requests should be made to nested resources to get
> nested
> >>> >> details (i.e. if you have regions and regions/1/regionwidgets, the
> >>> regions
> >>> >> representation should not contain an array of regionwidgets)
> >>> >>
> >>> >
> >>> > I am concerned about the round trips to support this when rendering
> the
> >>> > page.  With any page that has a sufficient number of gadgets, adding
> to
> >>> the
> >>> > number of requests becomes problematic.
> >>> >
> >>>
> >>> I see that rule applying to the "standard" rest endpoints for crud
> >>> operations on resources. We will have some number of special endpoints
> >>> to support frequently used operations of clients. The major example
> >>> there is the page / pages for render endpoint, which will include the
> >>> nested regions, regionwidgets, and their rpc tokens, etc.
> >>>
> >>
> >> +1
> >
> > So my thought is that we have the standard crud endpoints for all
> > individual resources. For frequently-used read operations in which we
> > need composite data sets we will have a small number of custom
> > endpoints to serve that data. Those are read-only endpoints, they will
> > not support create / update / delete operations.
> >
> > At a time when we need one of our composite data views, such as on a
> > page load, the client will make a request and get the composite data -
> > page, regions, regionwidgets and so on. The client can decompose those
> > into the individual component resources which have corresponding
> > angular $resource services, and which talk to the standard endpoints
> > to support further crud operations on them.
> >
> > Make sense / thoughts?
> >
> >>
> >>>
> >>> >
> >>> >>  - All methods should return standard HTTP codes. We should document
> >>> this
> >>> >> further on the wiki to make sure we all do the same way.
> >>> >>  - We won't accept partial updates with PUT, we will eventually add
> >>> PATCH
> >>> >> to support that in the future
> >>> >>  - If the "fields" query attribute isn't included in a GET then all
> >>> fields
> >>> >> are returned.
> >>> >>  - What is the full meta structure we want to return?
> >>> >>
> >>> >>
> >>> >> >
> >>> >> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> >>> >> > <er...@gmail.com> wrote:
> >>> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> >>> >> m.ben.franklin@gmail.com>
> >>> >> > wrote:
> >>> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
> >>> >> > >>
> >>> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <
> chris@cxtsoftware.com
> >>> >
> >>> >> > wrote:
> >>> >> > >>
> >>> >> > >>> 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
> >>> >> > >
> >>> >> > > Well the development in trunk can continue to happen on /rest.
> >>> Angular
> >>> >> > > (aka the consuming client for most of these apis) is already
> >>> happening
> >>> >> > > in a branch, so those changes can be treated as a rip / replace
> >>> >> > > easily.
> >>> >> > >
> >>> >> > >>>
> >>> >> > >>> >
> >>> >> > >>> > 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
> >>> >> > >
> >>> >> > > My understanding is that PUT should always be a full object
> >>> replace. A
> >>> >> > > quick search returns the suggestion to use PATCH, or to use
> POST to
> >>> a
> >>> >> > > subresource with a 303 response.
> >>> >> > >
> >>> >> > >>
> >>> >> > >>>
> >>> >> > >>> >
> >>> >> > >>> > 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.
> >>> >> > >>
> >>> >> > >
> >>> >> > > Fair enough. In this case I guess I would just be looking for
> >>> >> > > consistency - will associations be infinitely nest-able. If not,
> >>> what
> >>> >> > > is the rule to determine where we support more or less deeply
> nested
> >>> >> > > associations.
> >>> >> > >
> >>> >> > >>
> >>> >> > >>> >
> >>> >> > >>> > 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?
> >>> >> > >>>
> >>> >> > >
> >>> >> > > We could possibly achieve the same with HTTP headers. I prefer
> the
> >>> >> > > object approach for clarity, since custom http headers are less
> >>> >> > > accessible or discoverable than object structure. I get your
> point,
> >>> >> > > but I see the wrapped object approach used commonly in major
> apis.
> >>> If
> >>> >> > > it's clearly documented and used consistently across the entire
> api
> >>> I
> >>> >> > > don't really see an issue.
> >>> >> > >
> >>> >> > >>> >
> >>> >> > >>> > 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.
> >>> >> > >>
> >>> >> > >>
> >>> >> > >
> >>> >> > > I don't really know what the implementation looks like. If you
> allow
> >>> >> > > field filtering only on properties and deliver only properties
> (i.e.
> >>> >> > > no nested objects / associations) then I would assume it is
> pretty
> >>> >> > > straightforward.
> >>> >> > >>>
> >>> >> > >>> >
> >>> >> > >>> > 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?
> >>> >> > >>> >
> >>> >> > >>>
> >>> >> >
> >>> >>
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
I'm trying to register a new endpoint for regionWidgets. I've added
the interface and default implementation, and created / registered the
bean in cxf-applicationContext.xml.

However, when I hit the endpoint I get an error:
[INFO] [talledLocalContainer] WARN :
org.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request
path "/portal/api/rest/regionWidgets/1" is found, Relative Path: /1,
HTTP Method: GET, ContentType: */*, Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,.
Please enable FINE/TRACE log level for more details.

Is there anything else I need to do in order to create and register a
new endpoint?

On Tue, Jul 16, 2013 at 11:53 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>>
>>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <m....@gmail.com>
>>> wrote:
>>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
>>> wrote:
>>> >
>>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>> >> <er...@gmail.com>wrote:
>>> >>
>>> >> > Any further discussion here? I would like to start implementing more
>>> >> > of the REST APIs, as it is foundational for the entire angular
>>> >> > architecture.
>>> >> >
>>> >> > My understanding from Matt is that the current apis in trunk are
>>> >> > mostly proof of concept - they are not tested and much of the
>>> >> > functionality is just stubbed. Are any of the rest api implementations
>>> >> > in the code base a good working example? Is there other documentation
>>> >> > we can reference?
>>> >> >
>>> >>
>>> >> I've been working on the People resource as a "reference" of how I'd
>>> like
>>> >> to see them done but it's still a work in progress. I need to go back
>>> and
>>> >> pull out the JSONView stuff and reimplement the "fields" concept.
>>> Couple of
>>> >> notes:
>>> >>
>>> >>  - Object representations should be as flat as possible
>>> >> and separate requests should be made to nested resources to get nested
>>> >> details (i.e. if you have regions and regions/1/regionwidgets, the
>>> regions
>>> >> representation should not contain an array of regionwidgets)
>>> >>
>>> >
>>> > I am concerned about the round trips to support this when rendering the
>>> > page.  With any page that has a sufficient number of gadgets, adding to
>>> the
>>> > number of requests becomes problematic.
>>> >
>>>
>>> I see that rule applying to the "standard" rest endpoints for crud
>>> operations on resources. We will have some number of special endpoints
>>> to support frequently used operations of clients. The major example
>>> there is the page / pages for render endpoint, which will include the
>>> nested regions, regionwidgets, and their rpc tokens, etc.
>>>
>>
>> +1
>
> So my thought is that we have the standard crud endpoints for all
> individual resources. For frequently-used read operations in which we
> need composite data sets we will have a small number of custom
> endpoints to serve that data. Those are read-only endpoints, they will
> not support create / update / delete operations.
>
> At a time when we need one of our composite data views, such as on a
> page load, the client will make a request and get the composite data -
> page, regions, regionwidgets and so on. The client can decompose those
> into the individual component resources which have corresponding
> angular $resource services, and which talk to the standard endpoints
> to support further crud operations on them.
>
> Make sense / thoughts?
>
>>
>>>
>>> >
>>> >>  - All methods should return standard HTTP codes. We should document
>>> this
>>> >> further on the wiki to make sure we all do the same way.
>>> >>  - We won't accept partial updates with PUT, we will eventually add
>>> PATCH
>>> >> to support that in the future
>>> >>  - If the "fields" query attribute isn't included in a GET then all
>>> fields
>>> >> are returned.
>>> >>  - What is the full meta structure we want to return?
>>> >>
>>> >>
>>> >> >
>>> >> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>>> >> > <er...@gmail.com> wrote:
>>> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
>>> >> m.ben.franklin@gmail.com>
>>> >> > wrote:
>>> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
>>> >> > >>
>>> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <chris@cxtsoftware.com
>>> >
>>> >> > wrote:
>>> >> > >>
>>> >> > >>> 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
>>> >> > >
>>> >> > > Well the development in trunk can continue to happen on /rest.
>>> Angular
>>> >> > > (aka the consuming client for most of these apis) is already
>>> happening
>>> >> > > in a branch, so those changes can be treated as a rip / replace
>>> >> > > easily.
>>> >> > >
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 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
>>> >> > >
>>> >> > > My understanding is that PUT should always be a full object
>>> replace. A
>>> >> > > quick search returns the suggestion to use PATCH, or to use POST to
>>> a
>>> >> > > subresource with a 303 response.
>>> >> > >
>>> >> > >>
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 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.
>>> >> > >>
>>> >> > >
>>> >> > > Fair enough. In this case I guess I would just be looking for
>>> >> > > consistency - will associations be infinitely nest-able. If not,
>>> what
>>> >> > > is the rule to determine where we support more or less deeply nested
>>> >> > > associations.
>>> >> > >
>>> >> > >>
>>> >> > >>> >
>>> >> > >>> > 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?
>>> >> > >>>
>>> >> > >
>>> >> > > We could possibly achieve the same with HTTP headers. I prefer the
>>> >> > > object approach for clarity, since custom http headers are less
>>> >> > > accessible or discoverable than object structure. I get your point,
>>> >> > > but I see the wrapped object approach used commonly in major apis.
>>> If
>>> >> > > it's clearly documented and used consistently across the entire api
>>> I
>>> >> > > don't really see an issue.
>>> >> > >
>>> >> > >>> >
>>> >> > >>> > 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.
>>> >> > >>
>>> >> > >>
>>> >> > >
>>> >> > > I don't really know what the implementation looks like. If you allow
>>> >> > > field filtering only on properties and deliver only properties (i.e.
>>> >> > > no nested objects / associations) then I would assume it is pretty
>>> >> > > straightforward.
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 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?
>>> >> > >>> >
>>> >> > >>>
>>> >> >
>>> >>
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <er...@gmail.com>wrote:
>
>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <m....@gmail.com>
>> wrote:
>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
>> wrote:
>> >
>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> >> <er...@gmail.com>wrote:
>> >>
>> >> > Any further discussion here? I would like to start implementing more
>> >> > of the REST APIs, as it is foundational for the entire angular
>> >> > architecture.
>> >> >
>> >> > My understanding from Matt is that the current apis in trunk are
>> >> > mostly proof of concept - they are not tested and much of the
>> >> > functionality is just stubbed. Are any of the rest api implementations
>> >> > in the code base a good working example? Is there other documentation
>> >> > we can reference?
>> >> >
>> >>
>> >> I've been working on the People resource as a "reference" of how I'd
>> like
>> >> to see them done but it's still a work in progress. I need to go back
>> and
>> >> pull out the JSONView stuff and reimplement the "fields" concept.
>> Couple of
>> >> notes:
>> >>
>> >>  - Object representations should be as flat as possible
>> >> and separate requests should be made to nested resources to get nested
>> >> details (i.e. if you have regions and regions/1/regionwidgets, the
>> regions
>> >> representation should not contain an array of regionwidgets)
>> >>
>> >
>> > I am concerned about the round trips to support this when rendering the
>> > page.  With any page that has a sufficient number of gadgets, adding to
>> the
>> > number of requests becomes problematic.
>> >
>>
>> I see that rule applying to the "standard" rest endpoints for crud
>> operations on resources. We will have some number of special endpoints
>> to support frequently used operations of clients. The major example
>> there is the page / pages for render endpoint, which will include the
>> nested regions, regionwidgets, and their rpc tokens, etc.
>>
>
> +1

So my thought is that we have the standard crud endpoints for all
individual resources. For frequently-used read operations in which we
need composite data sets we will have a small number of custom
endpoints to serve that data. Those are read-only endpoints, they will
not support create / update / delete operations.

At a time when we need one of our composite data views, such as on a
page load, the client will make a request and get the composite data -
page, regions, regionwidgets and so on. The client can decompose those
into the individual component resources which have corresponding
angular $resource services, and which talk to the standard endpoints
to support further crud operations on them.

Make sense / thoughts?

>
>>
>> >
>> >>  - All methods should return standard HTTP codes. We should document
>> this
>> >> further on the wiki to make sure we all do the same way.
>> >>  - We won't accept partial updates with PUT, we will eventually add
>> PATCH
>> >> to support that in the future
>> >>  - If the "fields" query attribute isn't included in a GET then all
>> fields
>> >> are returned.
>> >>  - What is the full meta structure we want to return?
>> >>
>> >>
>> >> >
>> >> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>> >> > <er...@gmail.com> wrote:
>> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
>> >> m.ben.franklin@gmail.com>
>> >> > wrote:
>> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
>> >> > >>
>> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <chris@cxtsoftware.com
>> >
>> >> > wrote:
>> >> > >>
>> >> > >>> 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
>> >> > >
>> >> > > Well the development in trunk can continue to happen on /rest.
>> Angular
>> >> > > (aka the consuming client for most of these apis) is already
>> happening
>> >> > > in a branch, so those changes can be treated as a rip / replace
>> >> > > easily.
>> >> > >
>> >> > >>>
>> >> > >>> >
>> >> > >>> > 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
>> >> > >
>> >> > > My understanding is that PUT should always be a full object
>> replace. A
>> >> > > quick search returns the suggestion to use PATCH, or to use POST to
>> a
>> >> > > subresource with a 303 response.
>> >> > >
>> >> > >>
>> >> > >>>
>> >> > >>> >
>> >> > >>> > 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.
>> >> > >>
>> >> > >
>> >> > > Fair enough. In this case I guess I would just be looking for
>> >> > > consistency - will associations be infinitely nest-able. If not,
>> what
>> >> > > is the rule to determine where we support more or less deeply nested
>> >> > > associations.
>> >> > >
>> >> > >>
>> >> > >>> >
>> >> > >>> > 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?
>> >> > >>>
>> >> > >
>> >> > > We could possibly achieve the same with HTTP headers. I prefer the
>> >> > > object approach for clarity, since custom http headers are less
>> >> > > accessible or discoverable than object structure. I get your point,
>> >> > > but I see the wrapped object approach used commonly in major apis.
>> If
>> >> > > it's clearly documented and used consistently across the entire api
>> I
>> >> > > don't really see an issue.
>> >> > >
>> >> > >>> >
>> >> > >>> > 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.
>> >> > >>
>> >> > >>
>> >> > >
>> >> > > I don't really know what the implementation looks like. If you allow
>> >> > > field filtering only on properties and deliver only properties (i.e.
>> >> > > no nested objects / associations) then I would assume it is pretty
>> >> > > straightforward.
>> >> > >>>
>> >> > >>> >
>> >> > >>> > 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?
>> >> > >>> >
>> >> > >>>
>> >> >
>> >>
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne <er...@gmail.com>wrote:

> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <m....@gmail.com>
> wrote:
> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >
> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> >> <er...@gmail.com>wrote:
> >>
> >> > Any further discussion here? I would like to start implementing more
> >> > of the REST APIs, as it is foundational for the entire angular
> >> > architecture.
> >> >
> >> > My understanding from Matt is that the current apis in trunk are
> >> > mostly proof of concept - they are not tested and much of the
> >> > functionality is just stubbed. Are any of the rest api implementations
> >> > in the code base a good working example? Is there other documentation
> >> > we can reference?
> >> >
> >>
> >> I've been working on the People resource as a "reference" of how I'd
> like
> >> to see them done but it's still a work in progress. I need to go back
> and
> >> pull out the JSONView stuff and reimplement the "fields" concept.
> Couple of
> >> notes:
> >>
> >>  - Object representations should be as flat as possible
> >> and separate requests should be made to nested resources to get nested
> >> details (i.e. if you have regions and regions/1/regionwidgets, the
> regions
> >> representation should not contain an array of regionwidgets)
> >>
> >
> > I am concerned about the round trips to support this when rendering the
> > page.  With any page that has a sufficient number of gadgets, adding to
> the
> > number of requests becomes problematic.
> >
>
> I see that rule applying to the "standard" rest endpoints for crud
> operations on resources. We will have some number of special endpoints
> to support frequently used operations of clients. The major example
> there is the page / pages for render endpoint, which will include the
> nested regions, regionwidgets, and their rpc tokens, etc.
>

+1

>
> >
> >>  - All methods should return standard HTTP codes. We should document
> this
> >> further on the wiki to make sure we all do the same way.
> >>  - We won't accept partial updates with PUT, we will eventually add
> PATCH
> >> to support that in the future
> >>  - If the "fields" query attribute isn't included in a GET then all
> fields
> >> are returned.
> >>  - What is the full meta structure we want to return?
> >>
> >>
> >> >
> >> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> >> > <er...@gmail.com> wrote:
> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> >> m.ben.franklin@gmail.com>
> >> > wrote:
> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
> >> > >>
> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <chris@cxtsoftware.com
> >
> >> > wrote:
> >> > >>
> >> > >>> 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
> >> > >
> >> > > Well the development in trunk can continue to happen on /rest.
> Angular
> >> > > (aka the consuming client for most of these apis) is already
> happening
> >> > > in a branch, so those changes can be treated as a rip / replace
> >> > > easily.
> >> > >
> >> > >>>
> >> > >>> >
> >> > >>> > 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
> >> > >
> >> > > My understanding is that PUT should always be a full object
> replace. A
> >> > > quick search returns the suggestion to use PATCH, or to use POST to
> a
> >> > > subresource with a 303 response.
> >> > >
> >> > >>
> >> > >>>
> >> > >>> >
> >> > >>> > 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.
> >> > >>
> >> > >
> >> > > Fair enough. In this case I guess I would just be looking for
> >> > > consistency - will associations be infinitely nest-able. If not,
> what
> >> > > is the rule to determine where we support more or less deeply nested
> >> > > associations.
> >> > >
> >> > >>
> >> > >>> >
> >> > >>> > 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?
> >> > >>>
> >> > >
> >> > > We could possibly achieve the same with HTTP headers. I prefer the
> >> > > object approach for clarity, since custom http headers are less
> >> > > accessible or discoverable than object structure. I get your point,
> >> > > but I see the wrapped object approach used commonly in major apis.
> If
> >> > > it's clearly documented and used consistently across the entire api
> I
> >> > > don't really see an issue.
> >> > >
> >> > >>> >
> >> > >>> > 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.
> >> > >>
> >> > >>
> >> > >
> >> > > I don't really know what the implementation looks like. If you allow
> >> > > field filtering only on properties and deliver only properties (i.e.
> >> > > no nested objects / associations) then I would assume it is pretty
> >> > > straightforward.
> >> > >>>
> >> > >>> >
> >> > >>> > 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?
> >> > >>> >
> >> > >>>
> >> >
> >>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <m....@gmail.com> wrote:
> On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>
>> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>> <er...@gmail.com>wrote:
>>
>> > Any further discussion here? I would like to start implementing more
>> > of the REST APIs, as it is foundational for the entire angular
>> > architecture.
>> >
>> > My understanding from Matt is that the current apis in trunk are
>> > mostly proof of concept - they are not tested and much of the
>> > functionality is just stubbed. Are any of the rest api implementations
>> > in the code base a good working example? Is there other documentation
>> > we can reference?
>> >
>>
>> I've been working on the People resource as a "reference" of how I'd like
>> to see them done but it's still a work in progress. I need to go back and
>> pull out the JSONView stuff and reimplement the "fields" concept. Couple of
>> notes:
>>
>>  - Object representations should be as flat as possible
>> and separate requests should be made to nested resources to get nested
>> details (i.e. if you have regions and regions/1/regionwidgets, the regions
>> representation should not contain an array of regionwidgets)
>>
>
> I am concerned about the round trips to support this when rendering the
> page.  With any page that has a sufficient number of gadgets, adding to the
> number of requests becomes problematic.
>

I see that rule applying to the "standard" rest endpoints for crud
operations on resources. We will have some number of special endpoints
to support frequently used operations of clients. The major example
there is the page / pages for render endpoint, which will include the
nested regions, regionwidgets, and their rpc tokens, etc.

>
>>  - All methods should return standard HTTP codes. We should document this
>> further on the wiki to make sure we all do the same way.
>>  - We won't accept partial updates with PUT, we will eventually add PATCH
>> to support that in the future
>>  - If the "fields" query attribute isn't included in a GET then all fields
>> are returned.
>>  - What is the full meta structure we want to return?
>>
>>
>> >
>> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
>> > <er...@gmail.com> wrote:
>> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
>> m.ben.franklin@gmail.com>
>> > wrote:
>> > >> +1 for every one of Chris' +1s, unless otherwise noted.
>> > >>
>> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
>> > wrote:
>> > >>
>> > >>> 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
>> > >
>> > > Well the development in trunk can continue to happen on /rest. Angular
>> > > (aka the consuming client for most of these apis) is already happening
>> > > in a branch, so those changes can be treated as a rip / replace
>> > > easily.
>> > >
>> > >>>
>> > >>> >
>> > >>> > 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
>> > >
>> > > My understanding is that PUT should always be a full object replace. A
>> > > quick search returns the suggestion to use PATCH, or to use POST to a
>> > > subresource with a 303 response.
>> > >
>> > >>
>> > >>>
>> > >>> >
>> > >>> > 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.
>> > >>
>> > >
>> > > Fair enough. In this case I guess I would just be looking for
>> > > consistency - will associations be infinitely nest-able. If not, what
>> > > is the rule to determine where we support more or less deeply nested
>> > > associations.
>> > >
>> > >>
>> > >>> >
>> > >>> > 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?
>> > >>>
>> > >
>> > > We could possibly achieve the same with HTTP headers. I prefer the
>> > > object approach for clarity, since custom http headers are less
>> > > accessible or discoverable than object structure. I get your point,
>> > > but I see the wrapped object approach used commonly in major apis. If
>> > > it's clearly documented and used consistently across the entire api I
>> > > don't really see an issue.
>> > >
>> > >>> >
>> > >>> > 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.
>> > >>
>> > >>
>> > >
>> > > I don't really know what the implementation looks like. If you allow
>> > > field filtering only on properties and deliver only properties (i.e.
>> > > no nested objects / associations) then I would assume it is pretty
>> > > straightforward.
>> > >>>
>> > >>> >
>> > >>> > 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?
>> > >>> >
>> > >>>
>> >
>>

Re: [Proposal] REST API interface

Posted by Matt Franklin <m....@gmail.com>.
On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <ch...@cxtsoftware.com> wrote:

> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
> <er...@gmail.com>wrote:
>
> > Any further discussion here? I would like to start implementing more
> > of the REST APIs, as it is foundational for the entire angular
> > architecture.
> >
> > My understanding from Matt is that the current apis in trunk are
> > mostly proof of concept - they are not tested and much of the
> > functionality is just stubbed. Are any of the rest api implementations
> > in the code base a good working example? Is there other documentation
> > we can reference?
> >
>
> I've been working on the People resource as a "reference" of how I'd like
> to see them done but it's still a work in progress. I need to go back and
> pull out the JSONView stuff and reimplement the "fields" concept. Couple of
> notes:
>
>  - Object representations should be as flat as possible
> and separate requests should be made to nested resources to get nested
> details (i.e. if you have regions and regions/1/regionwidgets, the regions
> representation should not contain an array of regionwidgets)
>

I am concerned about the round trips to support this when rendering the
page.  With any page that has a sufficient number of gadgets, adding to the
number of requests becomes problematic.


>  - All methods should return standard HTTP codes. We should document this
> further on the wiki to make sure we all do the same way.
>  - We won't accept partial updates with PUT, we will eventually add PATCH
> to support that in the future
>  - If the "fields" query attribute isn't included in a GET then all fields
> are returned.
>  - What is the full meta structure we want to return?
>
>
> >
> > On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> > <er...@gmail.com> wrote:
> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
> m.ben.franklin@gmail.com>
> > wrote:
> > >> +1 for every one of Chris' +1s, unless otherwise noted.
> > >>
> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
> > wrote:
> > >>
> > >>> 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
> > >
> > > Well the development in trunk can continue to happen on /rest. Angular
> > > (aka the consuming client for most of these apis) is already happening
> > > in a branch, so those changes can be treated as a rip / replace
> > > easily.
> > >
> > >>>
> > >>> >
> > >>> > 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
> > >
> > > My understanding is that PUT should always be a full object replace. A
> > > quick search returns the suggestion to use PATCH, or to use POST to a
> > > subresource with a 303 response.
> > >
> > >>
> > >>>
> > >>> >
> > >>> > 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.
> > >>
> > >
> > > Fair enough. In this case I guess I would just be looking for
> > > consistency - will associations be infinitely nest-able. If not, what
> > > is the rule to determine where we support more or less deeply nested
> > > associations.
> > >
> > >>
> > >>> >
> > >>> > 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?
> > >>>
> > >
> > > We could possibly achieve the same with HTTP headers. I prefer the
> > > object approach for clarity, since custom http headers are less
> > > accessible or discoverable than object structure. I get your point,
> > > but I see the wrapped object approach used commonly in major apis. If
> > > it's clearly documented and used consistently across the entire api I
> > > don't really see an issue.
> > >
> > >>> >
> > >>> > 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.
> > >>
> > >>
> > >
> > > I don't really know what the implementation looks like. If you allow
> > > field filtering only on properties and deliver only properties (i.e.
> > > no nested objects / associations) then I would assume it is pretty
> > > straightforward.
> > >>>
> > >>> >
> > >>> > 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?
> > >>> >
> > >>>
> >
>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
<er...@gmail.com>wrote:

> Any further discussion here? I would like to start implementing more
> of the REST APIs, as it is foundational for the entire angular
> architecture.
>
> My understanding from Matt is that the current apis in trunk are
> mostly proof of concept - they are not tested and much of the
> functionality is just stubbed. Are any of the rest api implementations
> in the code base a good working example? Is there other documentation
> we can reference?
>

I've been working on the People resource as a "reference" of how I'd like
to see them done but it's still a work in progress. I need to go back and
pull out the JSONView stuff and reimplement the "fields" concept. Couple of
notes:

 - Object representations should be as flat as possible
and separate requests should be made to nested resources to get nested
details (i.e. if you have regions and regions/1/regionwidgets, the regions
representation should not contain an array of regionwidgets)
 - All methods should return standard HTTP codes. We should document this
further on the wiki to make sure we all do the same way.
 - We won't accept partial updates with PUT, we will eventually add PATCH
to support that in the future
 - If the "fields" query attribute isn't included in a GET then all fields
are returned.
 - What is the full meta structure we want to return?


>
> On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
> <er...@gmail.com> wrote:
> > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <m....@gmail.com>
> wrote:
> >> +1 for every one of Chris' +1s, unless otherwise noted.
> >>
> >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com>
> wrote:
> >>
> >>> 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
> >
> > Well the development in trunk can continue to happen on /rest. Angular
> > (aka the consuming client for most of these apis) is already happening
> > in a branch, so those changes can be treated as a rip / replace
> > easily.
> >
> >>>
> >>> >
> >>> > 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
> >
> > My understanding is that PUT should always be a full object replace. A
> > quick search returns the suggestion to use PATCH, or to use POST to a
> > subresource with a 303 response.
> >
> >>
> >>>
> >>> >
> >>> > 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.
> >>
> >
> > Fair enough. In this case I guess I would just be looking for
> > consistency - will associations be infinitely nest-able. If not, what
> > is the rule to determine where we support more or less deeply nested
> > associations.
> >
> >>
> >>> >
> >>> > 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?
> >>>
> >
> > We could possibly achieve the same with HTTP headers. I prefer the
> > object approach for clarity, since custom http headers are less
> > accessible or discoverable than object structure. I get your point,
> > but I see the wrapped object approach used commonly in major apis. If
> > it's clearly documented and used consistently across the entire api I
> > don't really see an issue.
> >
> >>> >
> >>> > 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.
> >>
> >>
> >
> > I don't really know what the implementation looks like. If you allow
> > field filtering only on properties and deliver only properties (i.e.
> > no nested objects / associations) then I would assume it is pretty
> > straightforward.
> >>>
> >>> >
> >>> > 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?
> >>> >
> >>>
>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
Any further discussion here? I would like to start implementing more
of the REST APIs, as it is foundational for the entire angular
architecture.

My understanding from Matt is that the current apis in trunk are
mostly proof of concept - they are not tested and much of the
functionality is just stubbed. Are any of the rest api implementations
in the code base a good working example? Is there other documentation
we can reference?

On Thu, Jul 11, 2013 at 5:48 PM, Erin Noe-Payne
<er...@gmail.com> wrote:
> On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <m....@gmail.com> wrote:
>> +1 for every one of Chris' +1s, unless otherwise noted.
>>
>> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>>
>>> 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
>
> Well the development in trunk can continue to happen on /rest. Angular
> (aka the consuming client for most of these apis) is already happening
> in a branch, so those changes can be treated as a rip / replace
> easily.
>
>>>
>>> >
>>> > 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
>
> My understanding is that PUT should always be a full object replace. A
> quick search returns the suggestion to use PATCH, or to use POST to a
> subresource with a 303 response.
>
>>
>>>
>>> >
>>> > 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.
>>
>
> Fair enough. In this case I guess I would just be looking for
> consistency - will associations be infinitely nest-able. If not, what
> is the rule to determine where we support more or less deeply nested
> associations.
>
>>
>>> >
>>> > 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?
>>>
>
> We could possibly achieve the same with HTTP headers. I prefer the
> object approach for clarity, since custom http headers are less
> accessible or discoverable than object structure. I get your point,
> but I see the wrapped object approach used commonly in major apis. If
> it's clearly documented and used consistently across the entire api I
> don't really see an issue.
>
>>> >
>>> > 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.
>>
>>
>
> I don't really know what the implementation looks like. If you allow
> field filtering only on properties and deliver only properties (i.e.
> no nested objects / associations) then I would assume it is pretty
> straightforward.
>>>
>>> >
>>> > 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?
>>> >
>>>

Re: [Proposal] REST API interface

Posted by Erin Noe-Payne <er...@gmail.com>.
On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <m....@gmail.com> wrote:
> +1 for every one of Chris' +1s, unless otherwise noted.
>
> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>
>> 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

Well the development in trunk can continue to happen on /rest. Angular
(aka the consuming client for most of these apis) is already happening
in a branch, so those changes can be treated as a rip / replace
easily.

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

My understanding is that PUT should always be a full object replace. A
quick search returns the suggestion to use PATCH, or to use POST to a
subresource with a 303 response.

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

Fair enough. In this case I guess I would just be looking for
consistency - will associations be infinitely nest-able. If not, what
is the rule to determine where we support more or less deeply nested
associations.

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

We could possibly achieve the same with HTTP headers. I prefer the
object approach for clarity, since custom http headers are less
accessible or discoverable than object structure. I get your point,
but I see the wrapped object approach used commonly in major apis. If
it's clearly documented and used consistently across the entire api I
don't really see an issue.

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

I don't really know what the implementation looks like. If you allow
field filtering only on properties and deliver only properties (i.e.
no nested objects / associations) then I would assume it is pretty
straightforward.
>>
>> >
>> > 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?
>> >
>>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
On Thu, Jul 11, 2013 at 2:02 PM, Matt Franklin <m....@gmail.com>wrote:

> +1 for every one of Chris' +1s, unless otherwise noted.
>
> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com> wrote:
>
> > 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)
> >
>
> 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: '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?
> > >
> >
>

Re: [Proposal] REST API interface

Posted by Matt Franklin <m....@gmail.com>.
+1 for every one of Chris' +1s, unless otherwise noted.

On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <ch...@cxtsoftware.com> wrote:

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

I say not.  That is what PATCH is for, once everything supports it:
http://tools.ietf.org/html/rfc5789

>
> >
> > 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: '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?
> >
>

Re: [Proposal] REST API interface

Posted by Chris Geer <ch...@cxtsoftware.com>.
Oh boy!! :)

Comments inline


On Thu, Jul 11, 2013 at 1:20 PM, Erin Noe-Payne <er...@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?
>