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
<[email protected]> wrote:
> On Tue, Jul 16, 2013 at 10:24 PM, Chris Geer <[email protected]> wrote:
>> On Tue, Jul 16, 2013 at 7:04 PM, Erin Noe-Payne 
>> <[email protected]>wrote:
>>
>>> On Tue, Jul 16, 2013 at 9:20 PM, Matt Franklin <[email protected]>
>>> wrote:
>>> > On Tue, Jul 16, 2013 at 12:53 PM, Chris Geer <[email protected]>
>>> wrote:
>>> >
>>> >> On Tue, Jul 16, 2013 at 10:32 AM, Erin Noe-Payne
>>> >> <[email protected]>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
>>> >> > <[email protected]> wrote:
>>> >> > > On Thu, Jul 11, 2013 at 5:02 PM, Matt Franklin <
>>> >> [email protected]>
>>> >> > wrote:
>>> >> > >> +1 for every one of Chris' +1s, unless otherwise noted.
>>> >> > >>
>>> >> > >> On Thu, Jul 11, 2013 at 3:47 PM, Chris Geer <[email protected]
>>> >
>>> >> > wrote:
>>> >> > >>
>>> >> > >>> Oh boy!! :)
>>> >> > >>>
>>> >> > >>> Comments inline
>>> >> > >>>
>>> >> > >>>
>>> >> > >>> On Thu, Jul 11, 2013 at 1:20 PM, Erin Noe-Payne <
>>> >> > [email protected]
>>> >> > >>> >wrote:
>>> >> > >>>
>>> >> > >>> > Hey All,
>>> >> > >>> >
>>> >> > >>> > As we are starting to look at the rest apis in more detail, I
>>> would
>>> >> > >>> > like to discuss and agree upon a consistent interface for our
>>> apis.
>>> >> > >>> > We currently have several developers interested in contributing
>>> to
>>> >> > the
>>> >> > >>> > apis and the angular branch, and I would like to solidify the
>>> >> > >>> > interface, methods, response format, etc so that we can be on
>>> the
>>> >> > same
>>> >> > >>> > page going forward. If we can agree on an api virtualization
>>> layer
>>> >> > >>> > then we should be able to build against it on the server and on
>>> the
>>> >> > >>> > angular application in parallel.
>>> >> > >>> >
>>> >> > >>> > I'll start with a proposal and look for feedback to iterate from
>>> >> > there.
>>> >> > >>> >
>>> >> > >>> > 1. API root url
>>> >> > >>> >
>>> >> > >>> > "/api". Drop support for rpc api, move from /api/rest to just
>>> /api.
>>> >> > >>> >
>>> >> > >>>
>>> >> > >>> +1 - the only downside of this is that it prohibits implementing
>>> over
>>> >> > time
>>> >> > >>> and requires a rip/replace approach of the whole system
>>> >> > >
>>> >> > > 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: '[email protected]
>>> ',
>>> >> > ... }
>>> >> > >>> > }
>>> >> > >>> >
>>> >> > >>> > GET /people/1?fields=id,name
>>> >> > >>> > {
>>> >> > >>> >  meta: { ... },
>>> >> > >>> >  data: { id: 1, name: 'canonical' }
>>> >> > >>> > }
>>> >> > >>> >
>>> >> > >>> > 6d. Pagination. All requests that return a list should be
>>> >> paginated.
>>> >> > >>> > The query string parameters "limit" and "offset" should be used
>>> for
>>> >> > >>> > pagination. On any request in which either parameter is not set,
>>> >> they
>>> >> > >>> > should default to 10 and 0 respectively.
>>> >> > >>> >
>>> >> > >>>
>>> >> > >>> +1
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 6e. Use camelCase for properties.
>>> >> > >>> >
>>> >> > >>>
>>> >> > >>> +1
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 7. Endpoints.
>>> >> > >>> >
>>> >> > >>> > 7a. Standard endpoints: there should be standard CRUD endpoints
>>> to
>>> >> > >>> > support each rave resource. In other words, any operation
>>> possible
>>> >> in
>>> >> > >>> > rave should be possible through a rest api action.
>>> >> > >>> >
>>> >> > >>>
>>> >> > >>> +1
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> > 7b. Special endpoints. In the case of certain client needs, we
>>> can
>>> >> > >>> > implement a small number of special endpoints to fulfill a
>>> specific
>>> >> > >>> > role. The primary case in point is retrieving a page for render,
>>> >> > which
>>> >> > >>> > returns a page, its regions, its regionWidgets, and their render
>>> >> > data.
>>> >> > >>> >
>>> >> > >>>
>>> >> > >>> +1
>>> >> > >>>
>>> >> > >>> >
>>> >> > >>> >
>>> >> > >>> >
>>> >> > >>> > Ok, I think that's it. This is meant as a proposal only - we are
>>> >> > >>> > looking for feedback to go forward. Thoughts?
>>> >> > >>> >
>>> >> > >>>
>>> >> >
>>> >>
>>>

Reply via email to