[server] Cornice minimal app

Ryan Kelly ryan at rfk.id.au
Thu Oct 13 14:11:07 PDT 2011


On 14/10/11 06:43, Rob Miller wrote:
>>
>> [...snip...]
>>
>> I think it does... to clarify, we seem to be looking at a choice between:
>>
>> a) registering a "service" with a specific path, and then registering
>> API calls against that service
>>
>> ... or ...
>>
>> b) registering each API call against a path directly, and getting rid of
>> the idea of a "service" abstraction that you have to set up beforehand
>>
>> Given these 2 choices, I lean towards b)
> 
> oops.  a).  i lean towards option a).  parsing error...
> 
>> because it allows the service
>> to be moveable. If the path to each API call is included in every @api
>> decorator, then you'd have to visit the code and change every @api
>> decorator to change that path, if some downstream user of our software
>> wanted to hang it somewhere else, for instance. If the api calls are
>> registered against a service, then you only have to make one change, to
>> the service path. This could even be wired up as configuration,
>> requiring no code at all.

Conceptually I think (a) makes a lot of sense.  If this is to be a
"toolkit for building RESTful services" then having "service" as an
explicit abstraction seems like a good idea.

However, it would be good to have a way to declare the service itself in
the same file as the views that it contains, i.e. as some sort of
venusian-based decorator.

Taking demoapp as an example, it would seem a bit odd to declare the
service on the config object in main(), then declare each of the
components by decorators on each view in a different file:

    __init__.py:

        def main():
             ...etc...
             config.add_service('users', '/users')
             ...etc...

    views.py:

        @api(service="users", request_method="GET"):
        def hello(request)
            return {"Hello": "World"}

I'm not sure what a better approach would look like though.  You could
automagically create and register the service when it gets its first
view, e.g:

    @api(service="users", prefix="/users", request_method="GET"):
    def user_index(request):
        ...etc...


    @api(service="users", request_method="POST"):
    def user_create(request):
        ...etc...

Or you could create a service *object* and register methods to it like this:

    class Users(Service):
        prefix = "/users"

    @Users.api(request_method="GET")
    def user_index(request):
        ...etc...

The later has the advantage of providing an obvious place for all the
bookkeeping about what methods are defined.


  Cheers,

     Ryan

-- 
Ryan Kelly
http://www.rfk.id.au  |  This message is digitally signed. Please visit
ryan at rfk.id.au        |  http://www.rfk.id.au/ramblings/gpg/ for details

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <https://mail.mozilla.org/private/services-dev/attachments/20111014/a9661a91/attachment.bin>


More information about the Services-dev mailing list