I knew this already :-) And that's not nessesarilly a bad thing, depending on what you are developing. I just think we need to think through how to implement it in Ladon. Since you have enjoyed using Ladon until now, you probably already know that I am a hugh fan of end-user simplicity.
And since REST is strictly object-oriented, I really think we should be looking at decorating the LadonType instead of methods. I haven't thought it all the way through yet, but I'm almost sure that would be the place to do it. / Jakob 2012/10/23 Mykhailo Stadnyk <[email protected]> > Exacly! REST is a constraint to objects by design! You've caught it. But > it's good principal for data-oriented services with no overhead by any > top-level protocol. It's a principal of building RESTful services. And will > be good if Ladon will support it > > 2012/10/23 Jakob Simon-Gaarde <[email protected]> > >> But, I think I know what you mean. It's the fact that it utilizes all >> HTTP methods that makes you say that REST is in the HTTP protocol. I just >> don't nessesarily find that this is very revolutionary. It's more of a >> constraint, cause you are limited to objects by design. >> >> / Jakob >> >> >> 2012/10/23 Mykhailo Stadnyk <[email protected]> >> >>> For REST HTTP is not underlying level but the protocol itself. In terms >>> of REST design of service is known, so all you need is just to describe a >>> list of objects. And then for each object there is 4 operations you are >>> able to perform Create (HTTP PUT), Read (HTTP GET), Update (HTTP POST) and >>> Delete (HTTP DELETE). That's why in terms of REST you do not need the >>> description. You have only URLs each representing the object you can do >>> direct HTTP requests and you have no overhead of having some top-level >>> protocol, etc. That's why I said that REST is HTTP, because there is >>> nothing on top of HTTP in REST. And there is nothing to describe, only the >>> object URLs. >>> >>> It means that RESTful service architecture is not as flexible as SOAP, >>> so if you, as developer decided to create RESTful service it means that you >>> already chosen the service architecture. It also means that not every SOAP >>> service can be RESTful, but RESTful service could be delivered with SOAP. >>> So you, as developer MUST decide first if you are building a RESTful >>> service, if so - go ahead, make it and Ladon give you benefit to deliver >>> your RESTful service throug varius different supported protocols. >>> >>> Again. You CAN deliver RESTful service throug SOAP/XML-RPC/JSON-WSP/etc. >>> But you CAN NOT deliver abstract SOAP/XML-RPC/JSON-WSP service through REST >>> if it wasn't designed as RESTful >>> >>> In my implementation I've tried to make everything with maximum >>> flexibility, so each RESTFul service could have more than 4 CRUD methods, >>> for each HTTP request method you can have as many service methods as you >>> need if the service methods have different signatures (arguments) >>> >>> like >>> >>> class Service: >>> @restfulize(method="GET") >>> def get_one_record( r_id): >>> pass >>> @restfulize(method="GET") >>> def get_last_record( r_time): >>> pass >>> @restfulize(method="GET") >>> def get_all_records(): >>> pass >>> @restfulize(method="GET") >>> def get_filtered_records( filters): >>> pass >>> >>> As you see in this example 4 service methods are bind to HTTP GET >>> method. Depending of parameters bypassed through HTTP I try to determine >>> which method to call, but from terms of protocol you always do >>> >>> GET /Service/rest?filters['name']=*bla&filters['another_key']=somevalue >>> HTTP/1.1 >>> Host: yourservice.com >>> ... >>> >>> The same for other HTTP methods. You can have 2 different methods for >>> POST, for example for User service example you may have split User data >>> update and user password update, etc.. >>> >>> Or maybe your service may not provide some methods. Like you create the >>> public read-only service, so you don't provide PUT/POST/DELETE >>> >>> P.S. REST does not provide the way do bypass which service method to >>> call by name. REST is not RPC. You have only the Resource, it's URL and 4 >>> operations. It is REST. >>> >>> Best regards, >>> Mike >>> >>> >>> 2012/10/23 Jakob Simon-Gaarde <[email protected]> >>> >>>> Everything in Ladon is HTTP :-) >>>> >>>> But HTTP is just the underlying protocol, and under that is a transport >>>> protocol etc. >>>> >>>> When I am talking about protocol in Ladon I mean service protocols like >>>> soap, json-wsp and soon json-rpc which are also protocols. I would put REST >>>> at this level aswell. >>>> >>>> I haven't really used REST before, but from what I can see it is >>>> nothing more than another service protocol which utilizes the HTTP standard >>>> a bit more, like using PUT,POST,GET,DELETE methods. Also it looks like >>>> there is not so much constraint on how parameters are passed so they can be >>>> JSON or XML or query-string. >>>> >>>> I don't like that there is no service description format for REST >>>> services. That is kind of a key feature in Ladon, that all supported >>>> protocols should be able to describe themselves. >>>> >>>> >>>> / Jakob >>>> >>>> 2012/10/22 Mykhailo Stadnyk <[email protected]> >>>> >>>>> What do you mean? >>>>> >>>>> Actually REST is HTTP in terms of protocol, so what do I need to >>>>> implement? Maybe you can explain me more detailed your thought. >>>>> >>>>> Best regards, >>>>> Mike >>>>> >>>>> 2012/10/22 Jakob Simon-Gaarde <[email protected]> >>>>> >>>>>> My first question about your RESTful implementation is, why are you >>>>>> not implementing it as a protocol? >>>>>> >>>>>> / Jakob >>>>>> >>>>>> 2012/10/22 Jakob Simon-Gaarde <[email protected]> >>>>>> >>>>>>> Just a remark about the package name tracepyd. That might be an >>>>>>> unfortunate package name, cause on that odd platform called Windows >>>>>>> pyd-files are binary python modules. Just a remark :-) >>>>>>> >>>>>>> >>>>>>> 2012/10/22 Jakob Simon-Gaarde <[email protected]> >>>>>>> >>>>>>>> Hi Mike. >>>>>>>> >>>>>>>> Let's talk about tracepyd first, does it solve this bug: >>>>>>>> >>>>>>>> https://bugs.launchpad.net/ladon/+bug/877727 >>>>>>>> >>>>>>>> rpclib has a terribly ugly solution for this, as you can see in the >>>>>>>> bug, and we want to be better than rpclib :-) >>>>>>>> >>>>>>>> / Jakob >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> 2012/10/22 Jakob Simon-Gaarde <[email protected]> >>>>>>>> >>>>>>>>> Hi Mike >>>>>>>>> >>>>>>>>> Looking into this now, you will have my reply today :-) >>>>>>>>> >>>>>>>>> / Jakob >>>>>>>>> >>>>>>>>> >>>>>>>>> 2012/10/22 Mykhailo Stadnyk <[email protected]> >>>>>>>>> >>>>>>>>>> Currently it's an experimental feature which is not ready to be >>>>>>>>>> integrated. I didn't test it at all (keep working on it). >>>>>>>>>> >>>>>>>>>> So here is my personal road-map for this feature: >>>>>>>>>> 1. Resolve problem with decorators dependencies (something I >>>>>>>>>> described in previous message) >>>>>>>>>> 2. Write tests and test the functionality >>>>>>>>>> 3. I've not checked how does it deal with requests containing >>>>>>>>>> multipart boundaries and binary data >>>>>>>>>> 4. Not sure what to do with service description (currently I've >>>>>>>>>> just removed, but have an idea we can use it to describe service any >>>>>>>>>> way, >>>>>>>>>> even as long as REST does not specify this) >>>>>>>>>> 5. Write documentation/examples >>>>>>>>>> >>>>>>>>>> But I'm stuck on issue #1. I want to know: >>>>>>>>>> * do you agree to add dependency in Ladon to tracepyd module or >>>>>>>>>> not? >>>>>>>>>> * If not - do you agree to include tracepyd's implementation >>>>>>>>>> into Ladon (not as dependency, but to place it somewhere in tools)? >>>>>>>>>> * If not - do you agree to modify @ladonize decorator >>>>>>>>>> functionality to add extra-params for REST (for me its ugly). >>>>>>>>>> * If not - which ideas do you have then? :) >>>>>>>>>> >>>>>>>>>> I'd like to suggest to add dependency to tracepyd. Currently I >>>>>>>>>> have a version locally which works fine, so I can publish this >>>>>>>>>> solution to >>>>>>>>>> my branch to let you see. >>>>>>>>>> >>>>>>>>>> Thank you in advance for your time and advice, >>>>>>>>>> Mike >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> 2012/10/22 Jakob Simon-Gaarde <[email protected]> >>>>>>>>>> >>>>>>>>>>> Interesting :-) >>>>>>>>>>> >>>>>>>>>>> I'll look at it later - we must make sure that it doesn't break >>>>>>>>>>> anything. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> 2012/10/22 Mykhailo Stadnyk <[email protected]> >>>>>>>>>>> >>>>>>>>>>>> Hi Jacob. >>>>>>>>>>>> >>>>>>>>>>>> As I told I'm trying to implement RESTful services support by >>>>>>>>>>>> Ladon. The basic functionality is implemented - you can check my >>>>>>>>>>>> branch: >>>>>>>>>>>> lp:~mikhus/ladon/rest<https://code.launchpad.net/~mikhus/ladon/rest> >>>>>>>>>>>> to >>>>>>>>>>>> see how does it work. Here is an example of RESTful service you >>>>>>>>>>>> may run to >>>>>>>>>>>> see: >>>>>>>>>>>> >>>>>>>>>>>> from ladon.ladonizer import ladonize, restfulize >>>>>>>>>>>> from ladon.compat import PORTABLE_STRING >>>>>>>>>>>> from ladon.types.ladontype import LadonType >>>>>>>>>>>> >>>>>>>>>>>> class User(LadonType): >>>>>>>>>>>> name = PORTABLE_STRING >>>>>>>>>>>> email = PORTABLE_STRING >>>>>>>>>>>> passwd = PORTABLE_STRING >>>>>>>>>>>> def __init__(): >>>>>>>>>>>> self.name = "" >>>>>>>>>>>> self.email = "" >>>>>>>>>>>> self.passwd = "" >>>>>>>>>>>> >>>>>>>>>>>> class UserService( object) : >>>>>>>>>>>> @restfulize(method="PUT") >>>>>>>>>>>> @ladonize(str, str, str, rtype=User) >>>>>>>>>>>> def newUser( self, u_name, u_email, u_passwd) : >>>>>>>>>>>> user = User() # where User is LadonType object >>>>>>>>>>>> user.name = u_name >>>>>>>>>>>> user.email = u_email >>>>>>>>>>>> user.passwd = u_passwd >>>>>>>>>>>> return user >>>>>>>>>>>> @restfulize(method="GET") >>>>>>>>>>>> @ladonize(int, rtype=[User]) >>>>>>>>>>>> def getUser(self, u_id) : >>>>>>>>>>>> return User() >>>>>>>>>>>> @restfulize(method="GET") >>>>>>>>>>>> @ladonize(int, rtype=[User]) >>>>>>>>>>>> def getUsers(self) : >>>>>>>>>>>> return [User(), User(), User()] >>>>>>>>>>>> @restfulize(method="POST") >>>>>>>>>>>> @ladonize(int, str, str, str, rtype=User) >>>>>>>>>>>> def updUser( self, u_id, u_name, u_email, u_passwd): >>>>>>>>>>>> user = User() >>>>>>>>>>>> user.name = u_name >>>>>>>>>>>> user.email = u_email >>>>>>>>>>>> user.passwd = u_passwd >>>>>>>>>>>> return user >>>>>>>>>>>> @restfulize(method="DELETE") >>>>>>>>>>>> @ladonize(int, rtype=bool) >>>>>>>>>>>> def delUser( self, u_id) : >>>>>>>>>>>> return True >>>>>>>>>>>> >>>>>>>>>>>> By the way, there is at least one issue I don't know how to >>>>>>>>>>>> solve better, so I want your advice. >>>>>>>>>>>> >>>>>>>>>>>> As you see I've implemented specific decorator to mark service >>>>>>>>>>>> methods as RESTful. It's @restfulize decorator. The problem that >>>>>>>>>>>> it is >>>>>>>>>>>> implemented now as: >>>>>>>>>>>> >>>>>>>>>>>> def restfulize( *dargs, **dkwargs): >>>>>>>>>>>> def decorator(fn): >>>>>>>>>>>> * minfo = fn._ladon_method_info* >>>>>>>>>>>> if 'method' in dkwargs: >>>>>>>>>>>> if not minfo.restfulize( **dkwargs): >>>>>>>>>>>> raise RestfulMethodConfigMismatch( fn.func_name) >>>>>>>>>>>> >>>>>>>>>>>> return fn # returns ladonized method >>>>>>>>>>>> return decorator >>>>>>>>>>>> >>>>>>>>>>>> The problem is highlighted with bold. Will be good to make this >>>>>>>>>>>> decorator independent of what @ladonize defined in it's private >>>>>>>>>>>> props. But, >>>>>>>>>>>> as far as "fn" here is a reference to ladon's "injector" function >>>>>>>>>>>> I have no >>>>>>>>>>>> way to determine correctly which real method in which class is >>>>>>>>>>>> decorated. >>>>>>>>>>>> It means that in such case I have no way to extract LadonMethodInfo >>>>>>>>>>>> associated to "fn" in other way but implemented for the moment. >>>>>>>>>>>> >>>>>>>>>>>> The real problem is when I want to override @ladonize >>>>>>>>>>>> decorator. In this case @resftulize becomes nonoperational because >>>>>>>>>>>> I loose >>>>>>>>>>>> reference to "_ladon_method_info" and means that I should take >>>>>>>>>>>> care to >>>>>>>>>>>> bypass all the existing private properties in 3-d party override >>>>>>>>>>>> implementation, which is not good at all. So I want to have >>>>>>>>>>>> @restfulize and >>>>>>>>>>>> @ladonize implemented without hard dependency between them. >>>>>>>>>>>> Via global_service_collection() it's possible to do but you >>>>>>>>>>>> need to determine real method function in some way. >>>>>>>>>>>> >>>>>>>>>>>> So I see the following ways to fix it: >>>>>>>>>>>> >>>>>>>>>>>> 1. Via decorator registry (Here we solved such kind of problem >>>>>>>>>>>> by creating DecoratorRegistry (I've published it as >>>>>>>>>>>> http://pypi.python.org/pypi/tracepyd)) >>>>>>>>>>>> 2. By adding REST functionality to @ladonize decorator itself, >>>>>>>>>>>> to have something like: >>>>>>>>>>>> @ladonize(PORTABLE_STRING, rtype=[PORTABLE_STRING], *rest={ >>>>>>>>>>>> "method" : "GET", "produces": "XML" }*) >>>>>>>>>>>> >>>>>>>>>>>> Maybe you can point me to some other ideas you know how to >>>>>>>>>>>> resolve such kind of problem. >>>>>>>>>>>> >>>>>>>>>>>> Best regards, >>>>>>>>>>>> Mike >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> -- >>>>>>>>>>> Med venlig hilsen / Best regards >>>>>>>>>>> Jakob Simon-Gaarde >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Med venlig hilsen / Best regards >>>>>>>>> Jakob Simon-Gaarde >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Med venlig hilsen / Best regards >>>>>>>> Jakob Simon-Gaarde >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Med venlig hilsen / Best regards >>>>>>> Jakob Simon-Gaarde >>>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Med venlig hilsen / Best regards >>>>>> Jakob Simon-Gaarde >>>>>> >>>>> >>>>> >>>> >>>> >>>> -- >>>> Med venlig hilsen / Best regards >>>> Jakob Simon-Gaarde >>>> >>> >>> >> >> >> -- >> Med venlig hilsen / Best regards >> Jakob Simon-Gaarde >> >> -- >> Mailing list: https://launchpad.net/~ladon-dev-team >> Post to : [email protected] >> Unsubscribe : https://launchpad.net/~ladon-dev-team >> More help : https://help.launchpad.net/ListHelp >> >> > -- Med venlig hilsen / Best regards Jakob Simon-Gaarde
-- Mailing list: https://launchpad.net/~ladon-dev-team Post to : [email protected] Unsubscribe : https://launchpad.net/~ladon-dev-team More help : https://help.launchpad.net/ListHelp

