On Mon, Jul 22, 2013 at 11:24 PM, Matt Franklin <[email protected]> wrote: > > >> On Jul 22, 2013, at 15:39, Erin Noe-Payne <[email protected]> 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 >> <[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 >>>>>>
