RESTful applications in Dancer
hi, I have a general web related question and then I wonder which of the answers can be easily implemented in Dancer? I am building an application that probably will be mostly just send out serialized data though I am not 100% sure so I might want to mix in sending out traditional HTML files as well. So I wonder what is the "best practice" to write RES-ish application, one that might also serve HTML? I thought about a few strategies I am going to describe now using a single route as an example: 1) /login always returns HTML no XML, JSON, YAML interface old school, no buzzwords here :) 2) /login always returns HTML /login.yml returns YAML /login.json returns JSON etc. (some of these might be allowed some might not) Q: What is the relationship between the HTML and the YAML? Is the data returned as YAML the same as would be passed to the template for generating HTML? How? 3) /login returns HTML or YAML or JSON depending on the Accept header of the request. In order to fetch the YAML response the request needs to supply: Accept: application/json I am not sure if HTTP allows multiple Accept headers and if yes then how should the application behave? Otherwise the same as 2 above. 4) No HTML responses at all (only some static pages) so 4.2) the serialization is the same as in 2) based on extension 4.3) the serialization is the same as in 3) based on Accept header Are any of these good strategies? Are there other good ones? Which one can be implemented in Dancer and how? regards Gabor -- Gabor Szabo http://szabgab.com/
First, I'd suggest that you think about what makes your webapp RESTy ? It's not because a webapp returns YYML/JSON that it is RESTy. To be REST oriented, the bare minimum is to have the logic of your app based on resources. 'login' is definitely not a resource. It looks like a verb, like "please log me on or off or something". In REST, the verbs are only HTTP verbs. URLs are resources, so you should be able to explain them as nouns. That said, maybe you already know all that and took 'login' as a strange example :) If I were you (but I don't know much about your webapp and its goal), I would design a pure REST application. - routes would be resource names - I'd use the Dancer REST plugin to handle serialization - /url/to/resource would return json or yaml based on Accept header. No Accept header would produce a server error - /url/to/resource.json would work, as well as yaml. Then, if you need a web frontend, do an other webapp :) or at least, a different Dancer::App. But Dancer being lightweight, it may be valid to have a completely seperated app. For authentication, I'd use plack and some auth mechanism. REST means it's stateless. Usually we accept that Authentication is the only state retains accross a RESTy webapp. If you need a very complicated authentication mechanism, you may end up with resources like /some/authentication. But these will be nouns, not verbs. But most of the time, some plugin/middleware/stuf will provide it for you transparently. Hope I made some sense and were not off topic On 20 December 2010 15:22, Gabor Szabo <szabgab@gmail.com> wrote:
hi,
I have a general web related question and then I wonder which of the answers can be easily implemented in Dancer?
I am building an application that probably will be mostly just send out serialized data though I am not 100% sure so I might want to mix in sending out traditional HTML files as well. So I wonder what is the "best practice" to write RES-ish application, one that might also serve HTML?
I thought about a few strategies I am going to describe now using a single route as an example:
1) /login always returns HTML no XML, JSON, YAML interface old school, no buzzwords here :)
2) /login always returns HTML /login.yml returns YAML /login.json returns JSON etc. (some of these might be allowed some might not)
Q: What is the relationship between the HTML and the YAML? Is the data returned as YAML the same as would be passed to the template for generating HTML? How?
3) /login returns HTML or YAML or JSON depending on the Accept header of the request. In order to fetch the YAML response the request needs to supply: Accept: application/json
I am not sure if HTTP allows multiple Accept headers and if yes then how should the application behave?
Otherwise the same as 2 above.
4) No HTML responses at all (only some static pages) so 4.2) the serialization is the same as in 2) based on extension 4.3) the serialization is the same as in 3) based on Accept header
Are any of these good strategies? Are there other good ones? Which one can be implemented in Dancer and how?
regards Gabor
-- Gabor Szabo http://szabgab.com/ _______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
On Mon, Dec 20, 2010 at 4:34 PM, damien krotkine <dkrotkine@gmail.com> wrote:
First, I'd suggest that you think about what makes your webapp RESTy ?
Well, I don't have a clue what makes and application RESTy but as I understood there are not many people who understand that. :)
It's not because a webapp returns YYML/JSON that it is RESTy. To be REST oriented, the bare minimum is to have the logic of your app based on resources. 'login' is definitely not a resource. It looks like a verb, like "please log me on or off or something". In REST, the verbs are only HTTP verbs. URLs are resources, so you should be able to explain them as nouns. That said, maybe you already know all that and took 'login' as a strange example :)
So maybe it would be GET /authorized_cookie or even GET /authorized_token instead of /login ? In any case it would require some kind of credentials. e.g. username/password or some way - and I don't know yet how that works - to get authenticated by OpenID or some OAuth based service. I am not sure though if even this is "allowed" in pure REST terms as I can see from http://en.wikipedia.org/wiki/Representational_State_Transfer a RESTful application should be stateless? Does that mean for every request that involves private data I'd need to supply my credentials? Anyway, here is an example, which is just the first step in my future application: A bookmark storing application. So I'd have operations such as add, delete, change ITEM list items (with some restirctions) Do these need to map to the HTTP keywords? e.g. fetching all the perl related bookmarks would be GET /bookmarks?title='%perl%' fetching all the details about a single bookmark would be: GET /bookmark/42 adding a new one would be POST /bookmark?title='The Perl Web Frameworks'&url=http://perldancer.org/ PUT /bookmark?id=42&comment="Nice framework" Is that the idea or would using GET in each case ok? (Personally I am now trying to implement the API of a web services and it drives me crazy that some requests only work as GET others only as POST and I don't even understand the errors I get from the other requests) Is that right that I have /bookmarks (in plural) above and /bookmark (in singular) in the other requests?
If I were you (but I don't know much about your webapp and its goal), I would design a pure REST application. - routes would be resource names - I'd use the Dancer REST plugin to handle serialization - /url/to/resource would return json or yaml based on Accept header. No Accept header would produce a server error - /url/to/resource.json would work, as well as yaml. Then, if you need a web frontend, do an other webapp :) or at least, a different Dancer::App. But Dancer being lightweight, it may be valid to have a completely seperated app.
I think I'll write both a perl client and a Javascript client for it and the Javascript client will use some static files from the same Dancer app to provide the base HTML to build on.
For authentication, I'd use plack and some auth mechanism. REST means it's stateless. Usually we accept that Authentication is the only state retains accross a RESTy webapp. If you need a very complicated authentication mechanism, you may end up with resources like /some/authentication. But these will be nouns, not verbs. But most of the time, some plugin/middleware/stuf will provide it for you transparently. Hope I made some sense and were not off topic
This answers my previous question about statelessness and authentication. Yes it was very useful, though I am not sure what did you mean by "plugin/middleware/stuf" and how is plack related to authentication. regards Gabor
On 20 December 2010 15:22, Gabor Szabo <szabgab@gmail.com> wrote:
hi,
I have a general web related question and then I wonder which of the answers can be easily implemented in Dancer?
I am building an application that probably will be mostly just send out serialized data though I am not 100% sure so I might want to mix in sending out traditional HTML files as well. So I wonder what is the "best practice" to write RES-ish application, one that might also serve HTML?
I thought about a few strategies I am going to describe now using a single route as an example:
1) /login always returns HTML no XML, JSON, YAML interface old school, no buzzwords here :)
2) /login always returns HTML /login.yml returns YAML /login.json returns JSON etc. (some of these might be allowed some might not)
Q: What is the relationship between the HTML and the YAML? Is the data returned as YAML the same as would be passed to the template for generating HTML? How?
3) /login returns HTML or YAML or JSON depending on the Accept header of the request. In order to fetch the YAML response the request needs to supply: Accept: application/json
I am not sure if HTTP allows multiple Accept headers and if yes then how should the application behave?
Otherwise the same as 2 above.
4) No HTML responses at all (only some static pages) so 4.2) the serialization is the same as in 2) based on extension 4.3) the serialization is the same as in 3) based on Accept header
Are any of these good strategies? Are there other good ones? Which one can be implemented in Dancer and how?
regards Gabor
On 20 December 2010 16:12, Gabor Szabo <szabgab@gmail.com> wrote:
On Mon, Dec 20, 2010 at 4:34 PM, damien krotkine <dkrotkine@gmail.com> wrote:
First, I'd suggest that you think about what makes your webapp RESTy ?
Well, I don't have a clue what makes and application RESTy but as I understood there are not many people who understand that. :)
You might want to read : http://oreilly.com/catalog/9780596529260 Writing a web service which is half REST, half classical is imho way worse than writing your web service in old school way.
It's not because a webapp returns YYML/JSON that it is RESTy. To be REST oriented, the bare minimum is to have the logic of your app based on resources. 'login' is definitely not a resource. It looks like a verb, like "please log me on or off or something". In REST, the verbs are only HTTP verbs. URLs are resources, so you should be able to explain them as nouns. That said, maybe you already know all that and took 'login' as a strange example :)
So maybe it would be
GET /authorized_cookie
or even
GET /authorized_token
instead of /login ?
Hm, I don't think so. I mean, technically yes, you may have a web service that requires you to advertize an auth token, but I don't think you need that. My recommandation would be that you explain what you want to achieve, with use-cases :) Then we can come up with examples of resources and which HTTP verbs to use.
In any case it would require some kind of credentials. e.g. username/password or some way - and I don't know yet how that works - to get authenticated by OpenID or some OAuth based service.
I am not sure though if even this is "allowed" in pure REST terms as I can see from http://en.wikipedia.org/wiki/Representational_State_Transfer a RESTful application should be stateless? Does that mean for every request that involves private data I'd need to supply my credentials?
In theory yes. It works well with basic HTTP auth, where login / password is passed for each request. It works well for basic https auth as well, for the same reasons. I suggest you keep authentication for later, and concentrate to the real features you want in your app, because learning REST by starting with the Auth paradygm is imho a bad idea.
Anyway, here is an example, which is just the first step in my future application:
Ah here are the explanations :)
A bookmark storing application. So I'd have operations such as add, delete, change ITEM list items (with some restirctions) Do these need to map to the HTTP keywords?
e.g. fetching all the perl related bookmarks would be
GET /bookmarks?title='%perl%'
fetching all the details about a single bookmark would be:
GET /bookmark/42
adding a new one would be
POST /bookmark?title='The Perl Web Frameworks'&url=http://perldancer.org/
I usually use POST verbs on plural resources, so POST /bookmarks but that may be a bad habit
PUT /bookmark?id=42&comment="Nice framework"
Is that the idea or would using GET in each case ok?
you got the idea right I think. using GET in each case completely destroys the REST concept.
(Personally I am now trying to implement the API of a web services and it drives me crazy that some requests only work as GET others only as POST and I don't even understand the errors I get from the other requests)
Is that right that I have /bookmarks (in plural) above and /bookmark (in singular) in the other requests?
yes You should spend a lot of time designing your REST interface (resource names + verbs), because that's the important bits, and once it's done and made public, you cn't really change it. So make sure you handle all the cases, and thatit's future proof, and so on. But reading a book on REST is good too :)
For authentication, I'd use plack and some auth mechanism. REST means it's stateless. Usually we accept that Authentication is the only state retains accross a RESTy webapp. If you need a very complicated authentication mechanism, you may end up with resources like /some/authentication. But these will be nouns, not verbs. But most of the time, some plugin/middleware/stuf will provide it for you transparently. Hope I made some sense and were not off topic
This answers my previous question about statelessness and authentication.
Yes it was very useful, though I am not sure what did you mean by "plugin/middleware/stuf" and how is plack related to authentication.
I was just saying that maybe plack has some middleware you can use that handles authentication for you. I never used one, but it may be worth looking at it. dams
On Mon, Dec 20, 2010 at 12:13 PM, damien krotkine <dkrotkine@gmail.com> wrote:
On 20 December 2010 16:12, Gabor Szabo <szabgab@gmail.com> wrote:
On Mon, Dec 20, 2010 at 4:34 PM, damien krotkine <dkrotkine@gmail.com> wrote:
First, I'd suggest that you think about what makes your webapp RESTy ?
Well, I don't have a clue what makes and application RESTy but as I understood there are not many people who understand that. :)
You might want to read : http://oreilly.com/catalog/9780596529260 Writing a web service which is half REST, half classical is imho way worse than writing your web service in old school way.
It's not because a webapp returns YYML/JSON that it is RESTy. To be REST oriented, the bare minimum is to have the logic of your app based on resources. 'login' is definitely not a resource. It looks like a verb, like "please log me on or off or something". In REST, the verbs are only HTTP verbs. URLs are resources, so you should be able to explain them as nouns. That said, maybe you already know all that and took 'login' as a strange example :)
So maybe it would be
GET /authorized_cookie
or even
GET /authorized_token
instead of /login ?
Hm, I don't think so. I mean, technically yes, you may have a web service that requires you to advertize an auth token, but I don't think you need that. My recommandation would be that you explain what you want to achieve, with use-cases :) Then we can come up with examples of resources and which HTTP verbs to use.
In any case it would require some kind of credentials. e.g. username/password or some way - and I don't know yet how that works - to get authenticated by OpenID or some OAuth based service.
I am not sure though if even this is "allowed" in pure REST terms as I can see from http://en.wikipedia.org/wiki/Representational_State_Transfer a RESTful application should be stateless? Does that mean for every request that involves private data I'd need to supply my credentials?
In theory yes. It works well with basic HTTP auth, where login / password is passed for each request. It works well for basic https auth as well, for the same reasons. I suggest you keep authentication for later, and concentrate to the real features you want in your app, because learning REST by starting with the Auth paradygm is imho a bad idea.
Anyway, here is an example, which is just the first step in my future application:
Ah here are the explanations :)
A bookmark storing application. So I'd have operations such as add, delete, change ITEM list items (with some restirctions) Do these need to map to the HTTP keywords?
e.g. fetching all the perl related bookmarks would be
GET /bookmarks?title='%perl%'
fetching all the details about a single bookmark would be:
GET /bookmark/42
adding a new one would be
POST /bookmark?title='The Perl Web Frameworks'&url=http://perldancer.org/
I usually use POST verbs on plural resources, so POST /bookmarks but that may be a bad habit
PUT /bookmark?id=42&comment="Nice framework"
Is that the idea or would using GET in each case ok?
you got the idea right I think. using GET in each case completely destroys the REST concept.
(Personally I am now trying to implement the API of a web services and it drives me crazy that some requests only work as GET others only as POST and I don't even understand the errors I get from the other requests)
Is that right that I have /bookmarks (in plural) above and /bookmark (in singular) in the other requests?
yes You should spend a lot of time designing your REST interface (resource names + verbs), because that's the important bits, and once it's done and made public, you cn't really change it. So make sure you handle all the cases, and thatit's future proof, and so on. But reading a book on REST is good too :)
For authentication, I'd use plack and some auth mechanism. REST means it's stateless. Usually we accept that Authentication is the only state retains accross a RESTy webapp. If you need a very complicated authentication mechanism, you may end up with resources like /some/authentication. But these will be nouns, not verbs. But most of the time, some plugin/middleware/stuf will provide it for you transparently. Hope I made some sense and were not off topic
This answers my previous question about statelessness and authentication.
Yes it was very useful, though I am not sure what did you mean by "plugin/middleware/stuf" and how is plack related to authentication.
I was just saying that maybe plack has some middleware you can use that handles authentication for you. I never used one, but it may be worth looking at it.
Yes, plack middleware is great for this. You can have a resource which is protected by http authentication. You get this for free with plack middleware. For example: #!/usr/bin/perl use Dancer; use Plack::Builder; use MyAPI; builder { # Enable http basic authentication for the /authorization resource enable_if { my $env = shift; $env->{PATH_INFO} eq '/authorization' } 'Plack::Middleware::Auth::Basic', authenticator => \&MyAPI::authenticate; dance; }; MyAPI contains the routes. Only the '/authorization' route will be wrapped by the middleware. You can also use the Auth::Digest middleware. A client of this api could do something like: my $agent = LWP::UserAgent->new()->credentials($host, $realm, $user, $pass); my $authorization = from_json($agent->get('/authorization')->content()); -Naveed
dams _______________________________________________ Dancer-users mailing list Dancer-users@perldancer.org http://www.backup-manager.org/cgi-bin/listinfo/dancer-users
participants (3)
-
damien krotkine -
Gabor Szabo -
Naveed Massjouni