click-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Malcolm Edgar <malcolm.ed...@gmail.com>
Subject Re: Click Services
Date Mon, 20 May 2013 12:09:45 GMT
Another approach for generating documentation would be to use a class
properties file and look up the HTML doco based on the method name, e.g.

CustomerServivce.properties
---------------------------------------------------------------------

CustomerServivce = Providers Customer Account query services.

getCustomers = Return the list of customers matching the given keyword and
active status. \n\
param : keyword : String : Search for customers matching the keyword
(optiona) \n\
        param : active : boolean : Include only active accounts (optional)"
\n\
        return : customer : array of customers


regards Malcolm


On Mon, May 20, 2013 at 9:07 PM, Malcolm Edgar <malcolm.edgar@gmail.com>wrote:

> Hi Bob,
>
> thanks for the links to Roy's blog post. I have to admit I have used the
> REST terminology a lot when talking about JSON RPC, so I am trying to be
> more precise nowdays.
>
> The WADL looks interesting, however writing an XML descriptor to generate
> doco would not be fun.
>
> Using straight reflection wouldn't probably work because the Java
> reflection API doesn't tell you what the parameter names are.  We would
> need to add annotations to make this work.  However writing code with
> annotations for doco is pretty yucky, e.g.
>
> package com.mycorp.services;
>
> @Doc(desc="Providers Customer Account query services")
> public class CustomerService {
>
>  @Doc(desc="Return the list of customers matching the given keyword and
> active status")
> public List<Customer> getCustomers(
>  @Doc(param="keyword", desc="Search for customers matching the keyword
> (optional") String keyword,
> @Doc(param="active", desc="Include only active accounts (optional)")
> boolean active) {
>  ..
> }
> }
>
> Still it would be a pretty nice feature to have APIs which are self
> describing.
>
> Its interesting using the returned POJO to create the documentation. Maybe
> a valid approach, especially if we can rely on a decent library to do the
> marshalling.  Using a reflection based approach would give us the most
> flexibility, so you could return an ActionResult or a POJO and the Filter
> would handle this result.
>
> Do you think there is merit in having stateful/singleton services ?
>
> In terms of mapping, I think we could develop some reasonable conventions
> like we have done with Click pages and cache the results, e.g.
>
> GET
> /mycorp/services/customer-service/get-customers/?keyword=john&active=true
>
> Would attempt to look up the class paths:
>
> com.mycorp.services.CustomerService
>
> Then attempt to resolve the method:
>
> getCustomers(String, String)
>
> While this is is favoring convention over configuration, in my experience
> this works really well in building large systems.
>
> Would be good for the Filter to use the Click Logging service, and log the
> appropriate output depending upon the application mode.
>
> It would also would be nice to have the Filter support formatting the JSON
> response to make it more human readable, with an optional formatJson=true
> request parameter.
>
> While all these things may appear to be pretty minor benefits, I think
> they would have a cumulative productivity benefit which would be
> significant.
>
> regards Malcolm
>
>
>
>
>
>
>
>
>
>
> On Mon, May 20, 2013 at 7:14 PM, Bob Schellink <sabob1@gmail.com> wrote:
>
>> Hi Malcolm,
>>
>> Multiple requests per service is what I have in mind. JSON over HTTP
>> instead of REST.
>>
>> Interestingly, Roy Fielding says a service isn't REST if it isn't
>> hypertext driven:
>> http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
>>
>> Basically nobody is doing REST anyway ;-)
>>
>> Wrt self documenting efforts, there is Swagger and WADL:
>> developers.helloreverb.com/swagger/
>>
>> Swager Demo:
>> http://petstore.swagger.wordnik.com/
>>
>> WADL:
>> http://en.wikipedia.org/wiki/Web_Application_Description_Language
>>
>> I'm not sure how we could self describe these services though. Perhaps a
>> url like '/services' could generate an HTML page with links to all
>> registered services. But Click will then have to "discover" it's own
>> services somehow via reflection or annotations or at build time.
>>
>> We also have to provide the input and outputs (JSON) of the services. If
>> a service looked like this:
>>
>> public Person getPerson(String id) {
>> }
>>
>> we could generate the JSON of a Person instance, as long as it has a
>> no-args constructor. The JSON won't have any values though so it would look
>> like:
>>
>> {Person: {'firstname': null, 'surname': null, 'dateOfBirth': null}}
>>
>> unless we add default values for primitives:
>> {Person: {'firstname': "example", 'surname': "example", 'dateOfBirth':
>> "2013/01/01" }}
>>
>> If we target JDK7 we could use the new InvokeDynamic instead of
>> reflection. InvokeDynamic should be quite a bit faster.
>>
>> Another note from your example:
>> customerservice/getcustomer/?id=123456
>>
>> how would one dynamically map customerservice to CustomerService? The URL
>> would have to respect the class case otherwise we won't be able to look it
>> up automatically. Unless there is a mapping somewhere (web.xml or
>> annotation) which maps the lower case customerservice to CustomerService.
>>
>> Kind regards
>>
>> Bob
>>
>>
>> On Mon, May 20, 2013 at 5:49 AM, Malcolm Edgar <malcolm.edgar@gmail.com>wrote:
>>
>>> I think there is some merit in this stuff for RPC JSON services.
>>>
>>> I would like to see some form of API documenting feature, this is a
>>> problem with existing services they are hard to program to because they are
>>> not self describing like Web Services are. This could be tricky to
>>> implement however, and you may want to disable this on production systems.
>>>
>>> Interesting to think what the design should be:
>>>
>>> 1) single RPC method per class, with the service implementing some
>>> service interface, e.g.
>>>
>>>    com.mycorp.service.GetCustomerService
>>>
>>>    /mycorp/service/getcustomer/?id=123456
>>>
>>>
>>> 2) multiple RPC methods per class, using reflection to lookup the
>>> methods:
>>>
>>>    com.mycorp.service.CustomerService
>>>
>>>    /mycorp/service/customerservice/getcustomer/?id=123456
>>>
>>>    /mycorp/service/customerservice/getcustomerlist/?keyword=bob
>>>
>>>
>>> In terms of whether we should support singleton /prototype (Spring
>>> terminology) services. I distrust stateful services and would prefer new
>>> service instances to be created per request. If people what to cache stuff,
>>> they can do this themselves in the servlet context.  If we take this
>>> approach I don't think we need lifecycle methods onInit(), onDestroy() etc.
>>>  This would also keep it simple, we dont need configuration or annoations
>>> to describe the service lifecycle.
>>>
>>> In terms of mapping requests to service, I think Bob's on demand
>>> approach would be good where by we cache resolved look-ups. For
>>> implementation agree the Filter would be the best approach as this would
>>> avoid impacting the ClickServlet and the XML configuration stuff.  It would
>>> be good do have some package automapping stuff like we do with Click pages.
>>> Maybe this could be configure against the filter in the web.xml
>>>
>>> regards
>>>
>>>
>>> On Wed, May 15, 2013 at 5:43 AM, Bob Schellink <sabob1@gmail.com> wrote:
>>>
>>>> On 2013/05/14 15:45, Malcolm Edgar wrote:
>>>>
>>>>> I think this is an interesting discussion.  I am seeing existing
>>>>> Multiple Page Applications (MPA),
>>>>> which is Clicks forte, evolve into hybrid MPA / Single Page
>>>>> Applications (SPA) using frameworks like
>>>>> AngularJS.
>>>>>
>>>>> For serving JSON/RPC we have been using both hand coded Servlets with
>>>>> net.sf.json.JSONSerializer and
>>>>> using services built with RESTEasy (http://www.jboss.org/resteasy**).
>>>>>  The RESTEasy approach is
>>>>> more idiomatic Java (lots of layers of abstraction) and works well 99%
>>>>> of time.
>>>>>
>>>>> I am not sure what the value Click could provide for services.
>>>>>
>>>>
>>>> Nods, we will be reinventing the wheel a bit.
>>>>
>>>>
>>>>  While I agree Velocity templates
>>>>
>>>>> would be useful for rendering a JSON response, the main problem in
>>>>> this space is marshalling JSON
>>>>> request data into Java objects. Maybe Marco google library would be
>>>>> good for this.
>>>>>
>>>>
>>>> I'm currently using GSON[1], mostly because their docs is
>>>> straightforward.
>>>>
>>>>
>>>>
>>>>
>>>>> How would you see the services being registered, e.g. XML definition
>>>>> or auto-mapped some how ?
>>>>>
>>>>
>>>> Guess annotation based but it looks like a pain to discover the
>>>> annotated classes. There are some libs to help with that part but EE
>>>> environments are tricky eg. JBoss 7 has a custom file system implementation
>>>> which is tricky to 'scan'. Preprocessor could also be used at compile time
>>>> to discover annotated classes and build an index of classes.
>>>>
>>>> One could also use plain interfaces and build up a cache at runtime eg:
>>>> each request that matches a valid class is placed in a map and cached for
>>>> faster retrieval in the future.
>>>>
>>>> Kind regards
>>>>
>>>> Bob
>>>>
>>>> [1]: http://code.google.com/p/**google-gson/<http://code.google.com/p/google-gson/>
>>>>
>>>
>>>
>>
>

Mime
View raw message