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 <[email protected]> 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 > <[email protected]> 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 <[email protected]> wrote: >>> On Mon, Jul 22, 2013 at 12:07 PM, Erin Noe-Payne >>> <[email protected]>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 >>>> <[email protected]> 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 >>>> > <[email protected]> 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 <[email protected]> >>>> 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 < >>>> [email protected]>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 <[email protected]> >>>> wrote: >>>> >>>> > Erin, I'm not seeing a patch posted up there. >>>> >>>> > >>>> >>>> > >>>> >>>> > On Fri, Jul 19, 2013 at 2:27 PM, Erin Noe-Payne < >>>> >>>> [email protected]>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 <[email protected] >>>> > >>>> >>>> wrote: >>>> >>>> >> > On Friday, July 19, 2013, Erin Noe-Payne wrote: >>>> >>>> >> > >>>> >>>> >> >> On Fri, Jul 19, 2013 at 1:24 PM, Chris Geer < >>>> [email protected] >>>> >>>> >> <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 >>>> >>>> >> >> > <[email protected]>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 >>>> >>>> >> >> >> <[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 >>>> >>>> >> >>>> >>>> >>>>
