Dear all, I worked a bit on the design of the RESTful API and as a result I've integrated what was written on the http://dev.xwiki.org/xwiki/bin/view/Design/RestfulAPI page. There is still a big and important part missing (maybe the most important one), i.e., the one about the data formats for representations (in particular the XML schemas to be used in requests and responses). I am working on it. Anyway you can already comment on what is present on the page. Thank you. -Fabio
Hi Fabio, Looks good. 2 questions: 1) # /spaces/{space}/pages/{page}/translations[?start=offset&number=n] (The list of all available translations of the page {space}.{page}) # /spaces/{space}/pages/{page}/{version} (The page {space}.{page}. at version {version}) # /spaces/{space}/pages/{page}/{lang} (The page {space}.{page} in its {lang} translation) # /spaces/{space}/pages/{page}/{lang}/history (The list of all the available revision of the page {space}.{page} in it {lang} translation.) # /spaces/{space}/pages/{page}/{lang}/{version} This seems somewhat inconsistent with "pages", "attachments", "objects" Why not have "versions" and "translations"? For example: /spaces/{space}/pages/{page}/versions/{version} Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency. 2) How will we support nested spaces? Thanks -Vincent On Dec 15, 2008, at 4:43 PM, Fabio Mancinelli wrote:
Dear all,
I worked a bit on the design of the RESTful API and as a result I've integrated what was written on the http://dev.xwiki.org/xwiki/bin/view/Design/RestfulAPI page.
There is still a big and important part missing (maybe the most important one), i.e., the one about the data formats for representations (in particular the XML schemas to be used in requests and responses). I am working on it.
Anyway you can already comment on what is present on the page.
Thank you.
-Fabio
Vincent Massol wrote:
Hi Fabio,
Looks good. 2 questions:
1)
# /spaces/{space}/pages/{page}/translations[?start=offset&number=n] (The list of all available translations of the page {space}.{page}) # /spaces/{space}/pages/{page}/{version} (The page {space}.{page}. at version {version}) # /spaces/{space}/pages/{page}/{lang} (The page {space}.{page} in its {lang} translation) # /spaces/{space}/pages/{page}/{lang}/history (The list of all the available revision of the page {space}.{page} in it {lang} translation.) # /spaces/{space}/pages/{page}/{lang}/{version}
This seems somewhat inconsistent with "pages", "attachments", "objects"
Why not have "versions" and "translations"? For example: /spaces/{space}/pages/{page}/versions/{version}
I thought that having shorter URIs would be better. But I am not against having something like /spaces/{space}/pages/{page} /spaces/{space}/pages/{page}/versions /spaces/{space}/pages/{page}/versions/{version} /spaces/{space}/pages/{page}/translations /spaces/{space}/pages/{page}/translations/{language} /spaces/{space}/pages/{page}/translations/{language}/versions /spaces/{space}/pages/{page}/translations/{language}/versions/{version} Or similar.
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
URI design is not that important (as long as the hypermedia constraints is fully leveraged). However having descriptive URIs and consistent URIs can enhance the possibility of discovering resources by guessing (i.e. the level of "serendipity")
2) How will we support nested spaces?
Actually I didn't address the nested spaces issue. Spaces can be nested at an arbitrary level? Thanks. -Fabio
On Dec 15, 2008, at 5:24 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Hi Fabio,
Looks good. 2 questions:
1)
# /spaces/{space}/pages/{page}/translations[?start=offset&number=n] (The list of all available translations of the page {space}.{page}) # /spaces/{space}/pages/{page}/{version} (The page {space}.{page}. at version {version}) # /spaces/{space}/pages/{page}/{lang} (The page {space}.{page} in its {lang} translation) # /spaces/{space}/pages/{page}/{lang}/history (The list of all the available revision of the page {space}.{page} in it {lang} translation.) # /spaces/{space}/pages/{page}/{lang}/{version}
This seems somewhat inconsistent with "pages", "attachments", "objects"
Why not have "versions" and "translations"? For example: /spaces/{space}/pages/{page}/versions/{version}
I thought that having shorter URIs would be better. But I am not against having something like
/spaces/{space}/pages/{page} /spaces/{space}/pages/{page}/versions /spaces/{space}/pages/{page}/versions/{version} /spaces/{space}/pages/{page}/translations /spaces/{space}/pages/{page}/translations/{language} /spaces/{space}/pages/{page}/translations/{language}/versions /spaces/{space}/pages/{page}/translations/{language}/versions/ {version}
Or similar.
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
URI design is not that important (as long as the hypermedia constraints is fully leveraged). However having descriptive URIs and consistent URIs can enhance the possibility of discovering resources by guessing (i.e. the level of "serendipity")
2) How will we support nested spaces?
Actually I didn't address the nested spaces issue. Spaces can be nested at an arbitrary level?
Not yet but we want to support this in the future yes so better design a REST API that will work with nested spaces (arbitrary level yes). Thanks -Vincent
Hi, Fabio. 1) Why we need /spaces/ and /pages/ ? Can't we use just /{space}/{page}/... ? What does mean /spaces/{space} GET: retrieves a space? What is space? 2) How could I get all translations of a page? (so i think {page}/translatios is needed) 3) I think we need {page}/versions instead of {page}/history Fabio Mancinelli wrote:
Vincent Massol wrote:
Hi Fabio,
Looks good. 2 questions:
1)
# /spaces/{space}/pages/{page}/translations[?start=offset&number=n] (The list of all available translations of the page {space}.{page}) # /spaces/{space}/pages/{page}/{version} (The page {space}.{page}. at version {version}) # /spaces/{space}/pages/{page}/{lang} (The page {space}.{page} in its {lang} translation) # /spaces/{space}/pages/{page}/{lang}/history (The list of all the available revision of the page {space}.{page} in it {lang} translation.) # /spaces/{space}/pages/{page}/{lang}/{version}
This seems somewhat inconsistent with "pages", "attachments", "objects"
Why not have "versions" and "translations"? For example: /spaces/{space}/pages/{page}/versions/{version}
I thought that having shorter URIs would be better. But I am not against having something like
/spaces/{space}/pages/{page} /spaces/{space}/pages/{page}/versions /spaces/{space}/pages/{page}/versions/{version} /spaces/{space}/pages/{page}/translations /spaces/{space}/pages/{page}/translations/{language} /spaces/{space}/pages/{page}/translations/{language}/versions /spaces/{space}/pages/{page}/translations/{language}/versions/{version}
Or similar.
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
URI design is not that important (as long as the hypermedia constraints is fully leveraged). However having descriptive URIs and consistent URIs can enhance the possibility of discovering resources by guessing (i.e. the level of "serendipity")
2) How will we support nested spaces?
Actually I didn't address the nested spaces issue. Spaces can be nested at an arbitrary level?
Thanks.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Artem Melentyev wrote:
Hi, Fabio.
1) Why we need /spaces/ and /pages/ ? Can't we use just /{space}/{page}/... ?
Yes, but this might lead to ambiguities in URI routing. Consider /tags/foo Is it a a list of pages tagged as foo, or the foo page in the tags space? By interleaving variable parts with fixed ones this ambiguity can be solved. This is standard practice however. Even the plural form. But this can be worked out I guess.
What does mean /spaces/{space} GET: retrieves a space? What is space?
This was a leftover of the current implementation. Actually we can get rid of this resource. I am not sure what Alexandru's implementation returned but I guess it was the {space}.WebHome page.
2) How could I get all translations of a page? (so i think {page}/translatios is needed)
Propbably you missed it. It's already there.
3) I think we need {page}/versions instead of {page}/history
Again a leftover of the current implementation. Anyway I agree. Thanks -Fabio
Fabio Mancinelli wrote:
Artem Melentyev wrote:
Hi, Fabio.
1) Why we need /spaces/ and /pages/ ? Can't we use just /{space}/{page}/... ?
Yes, but this might lead to ambiguities in URI routing.
Consider /tags/foo
Is it a a list of pages tagged as foo, or the foo page in the tags space?
By interleaving variable parts with fixed ones this ambiguity can be solved. This is standard practice however.
Even the plural form. But this can be worked out I guess.
Ok. +1 for /space/{space}/page/{page}/...
Artem Melentyev wrote:
2) How could I get all translations of a page? (so i think {page}/translatios is needed)
+1
3) I think we need {page}/versions instead of {page}/history
I'm not sure... 'history' is semantically more correct than 'versions', IMO, at least for me. Versions is closer to variants than to history (see http://wordnetweb.princeton.edu/perl/webwn?s=version ). It might even lead the user to think of translations. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Fabio Mancinelli wrote:
Vincent Massol wrote:
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
URI design is not that important (as long as the hypermedia constraints is fully leveraged). However having descriptive URIs and consistent URIs can enhance the possibility of discovering resources by guessing (i.e. the level of "serendipity")
I disagree. URI design is crucial, although some don't give much importance to it. I'd rather we sacrifice shortness for meaning. Given that URLs are already long, there's no need to reduce just a few parts to save 8 bytes. There's always purl, tinyrl and other services for this. -- Sergiu Dumitriu http://purl.org/net/sergiu/
On Dec 15, 2008, at 6:51 PM, Sergiu Dumitriu wrote:
Fabio Mancinelli wrote:
Vincent Massol wrote:
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
URI design is not that important (as long as the hypermedia constraints is fully leveraged). However having descriptive URIs and consistent URIs can enhance the possibility of discovering resources by guessing (i.e. the level of "serendipity")
I disagree. URI design is crucial, although some don't give much importance to it. I'd rather we sacrifice shortness for meaning. Given that URLs are already long, there's no need to reduce just a few parts to save 8 bytes. There's always purl, tinyrl and other services for this.
+1 to that. -Vincent
Vincent Massol wrote:
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
Ok. I saw what you meant. I modified a bit the resources to remove the inconsistency. I did this because attachments have also their own versioning. So you can access a specific version of an attachment either by requesting an attachment at a given page version or by requesting an specific version of an attachment. To be consistent I only left the resources for referring to an attachment starting for a given page version: /space/{space}/pages/{page}/attachments /space/{space}/pages/{page}/attachments/{attachment} /space/{space}/pages/{page}/{version}/attachments/ /space/{space}/pages/{page}/{version}/attachments/{attachment} I still maintained the non-verbose version but that can be changed if there is not an agreement on it. However it might be still useful to expose attachment resources by using their own versioning: /space/{space}/pages/{page}/attachments/{attachment}/history /space/{space}/pages/{page}/attachments/{attachment}/{version} Thanks. -Fabio
Other question: Why use the plural when retrieving a single instance. For example: /spaces --> All spaces /space/{space} --> One space Ah just saw you changed that but not everywhere. Like classes/{class} should be class/{class} And pages/{page} should be page/{page} no? Re nested spaces the best is probably to define a delimiter other than "/" Something like: /space/this::is::nested/page/WebHome Of course this would mean that "::" is not allowed in space names. BTW this would also means that "/" is not allowed in space names. -Vincent On Dec 15, 2008, at 5:39 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
Ok. I saw what you meant. I modified a bit the resources to remove the inconsistency. I did this because attachments have also their own versioning. So you can access a specific version of an attachment either by requesting an attachment at a given page version or by requesting an specific version of an attachment.
To be consistent I only left the resources for referring to an attachment starting for a given page version:
/space/{space}/pages/{page}/attachments /space/{space}/pages/{page}/attachments/{attachment} /space/{space}/pages/{page}/{version}/attachments/ /space/{space}/pages/{page}/{version}/attachments/{attachment}
I still maintained the non-verbose version but that can be changed if there is not an agreement on it.
However it might be still useful to expose attachment resources by using their own versioning:
/space/{space}/pages/{page}/attachments/{attachment}/history /space/{space}/pages/{page}/attachments/{attachment}/{version}
Thanks.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Vincent Massol wrote:
Other question:
Why use the plural when retrieving a single instance.
For example: /spaces --> All spaces /space/{space} --> One space
Ah just saw you changed that but not everywhere. Like classes/{class} should be class/{class} And pages/{page} should be page/{page} no?
Actually this was a leftover of my Ruby On Rails experience... But yes, I think that this can be worked out without any problem :)
Re nested spaces the best is probably to define a delimiter other than "/"
Something like: /space/this::is::nested/page/WebHome
Of course this would mean that "::" is not allowed in space names. BTW this would also means that "/" is not allowed in space names.
This is an interesting solution. In fact, I don't know if Restlet supports some kind of regular expression extension on URI templates. I mean, I am not sure if we can define a "/{space}+/pages/{page}" URI template as a route for catching nested spaces... To be investigated. Thanks -Fabio
Vincent Massol wrote:
Other question:
Why use the plural when retrieving a single instance.
For example: /spaces --> All spaces /space/{space} --> One space
Ah just saw you changed that but not everywhere. Like classes/{class} should be class/{class} And pages/{page} should be page/{page} no? Actually I think that the plural form makes sense.
/spaces/Main means that in the "list of spaces, I want the Main space", being /spaces the resource representing that list. Same thing for classes. -Fabio
Vincent Massol wrote:
Other question:
Why use the plural when retrieving a single instance.
For example: /spaces --> All spaces /space/{space} --> One space
Ah just saw you changed that but not everywhere.
Actually that was a typo.
From my point of view the first component should be "spaces" everywhere :)
I corrected it for the sake of uniformity. -Fabio
Vincent Massol wrote:
Other question:
Why use the plural when retrieving a single instance.
For example: /spaces --> All spaces /space/{space} --> One space
Ah just saw you changed that but not everywhere. Like classes/{class} should be class/{class} And pages/{page} should be page/{page} no?
Re nested spaces the best is probably to define a delimiter other than "/"
Something like: /space/this::is::nested/page/WebHome
Of course this would mean that "::" is not allowed in space names. BTW this would also means that "/" is not allowed in space names.
It is currently, so dropping it would be a regression. %2F can be used to escape / inside the space/page name. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Fabio Mancinelli wrote:
Vincent Massol wrote:
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
Ok. I saw what you meant. I modified a bit the resources to remove the inconsistency. I did this because attachments have also their own versioning. So you can access a specific version of an attachment either by requesting an attachment at a given page version or by requesting an specific version of an attachment.
To be consistent I only left the resources for referring to an attachment starting for a given page version:
/space/{space}/pages/{page}/attachments /space/{space}/pages/{page}/attachments/{attachment} /space/{space}/pages/{page}/{version}/attachments/ /space/{space}/pages/{page}/{version}/attachments/{attachment}
I still maintained the non-verbose version but that can be changed if there is not an agreement on it.
However it might be still useful to expose attachment resources by using their own versioning:
/space/{space}/pages/{page}/attachments/{attachment}/history /space/{space}/pages/{page}/attachments/{attachment}/{version}
+1 for both (verbose): /space/{space}/pages/{page}/history/{version}/attachments/{attachment} /space/{space}/pages/{page}/attachments/{attachment}/history/{version} But this should not work: /space/{space}/pages/{page}/history/{version}/attachments/{attachment}/history/{version} Since we either want to see all the versions of the attachment, or the attachment variant used in a certain version of the document. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Vincent Massol wrote:
Hi Fabio,
Looks good. 2 questions:
1)
# /spaces/{space}/pages/{page}/translations[?start=offset&number=n] (The list of all available translations of the page {space}.{page}) # /spaces/{space}/pages/{page}/{version} (The page {space}.{page}. at version {version}) # /spaces/{space}/pages/{page}/{lang} (The page {space}.{page} in its {lang} translation) # /spaces/{space}/pages/{page}/{lang}/history (The list of all the available revision of the page {space}.{page} in it {lang} translation.) # /spaces/{space}/pages/{page}/{lang}/{version}
This seems somewhat inconsistent with "pages", "attachments", "objects"
Why not have "versions" and "translations"? For example: /spaces/{space}/pages/{page}/versions/{version}
+1. We use an identifier for every sub-fragment of information to eliminate the URL-parsing magic. The more information -> The less ambiguities -> The simpler things are. Plus, /spaces/Main/pages/WebHome/2.3 does not suggest that 2.3 is a version. More, like with version control systems, in the future I'd like to add support for version tags, which would be accessible using: /spaces/{space}/pages/{page}/history/HEAD /spaces/{space}/pages/{page}/history/some_tag If we don't use /history/, there will be more if-else programming and more reserved keywords.
Note that I don't know what are the REST best practices. I'm jut noticing the inconsistency.
2) How will we support nested spaces?
That's one of the reasons why I insisted on /spaces/{space}/pages/{page}/ instead of /{space}/{page}/ . Here {space} can be a nested space, for example: /spaces/A/Nested/Space/pages/Page/ Drawback: a space hierarchy cannot have a part named 'pages' (or other special names). Alternative: Use %2F as the internal separator, like: /spaces/A%2FNested%2FSpace/pages/Page/ Possible problem: %2F causes Tomcat (with the default settings) to abort the request, since there are some security problems with poorly designed applications. Another problem: This will be incompatible with the current URLs, since %2F is used to escape / inside space or page names. This URL works quite well: http://localhost:8080/xwiki/bin/view/Blog%2F2.0/Here%2Fwe%2Fgo , where the space is Blog/2.0 and the document is Here/we/go So, I'd like to stay with: /spaces/A/Nested/Space with %2F in it/pages/Page with %2F in it/
Thanks -Vincent
On Dec 15, 2008, at 4:43 PM, Fabio Mancinelli wrote:
Dear all,
I worked a bit on the design of the RESTful API and as a result I've integrated what was written on the http://dev.xwiki.org/xwiki/bin/view/Design/RestfulAPI page.
There is still a big and important part missing (maybe the most important one), i.e., the one about the data formats for representations (in particular the XML schemas to be used in requests and responses). I am working on it.
Anyway you can already comment on what is present on the page.
How about some of the views done in WebDAV, like attachments view and tree view? /attachments/spaces/{space}/pages/{page}/{attachment.ext} I'm not sure about the extension-controlled format. What if the document contains dots in its name, like "Help/How to create a .pdf"? More URL-parsing magic? And then what about "How to open a .tar".gz versus "How to open a .tar.gz"? I think that HTTP Accept header alone is better. To make XMLs more friendly, we could use XSLT stylesheets to transform them into HTML on the client. /space/{space}/pages/{page}/objects/{id} -> what is the id? How to handle both new GUIDs and old indexes? I prefer to also have the detailed property view. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Dear all, while I was in the metro I thought of another way of organizing resources in a more compact way. I've added a second proposal on the http://dev.xwiki.org/xwiki/bin/view/Design/RestfulAPI page. ThomasM also told me that we should take into account the "XWiki" resource in a mult-wiki environment. This can be done by adding an optional segment "/wiki/{wiki}/" as a suffix to all the resources. Thanks. -Fabio
Interesting discussion ! You might want to think about using the webdav methods such as MOVE or COPY in some instances (wiki / space / page / attachment (?) ) which could be useful for refactoring content organization or for administrative purposes. Just a thought Luis On Mon, Dec 15, 2008 at 10:20 PM, Fabio Mancinelli <[email protected]> wrote:
Fabio Mancinelli wrote:
ThomasM also told me that we should take into account the "XWiki" resource in a mult-wiki environment. This can be done by adding an optional segment "/wiki/{wiki}/" as a suffix to all the resources.
Sorry, I meant prefix.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Luis Arias +33 6 14 20 87 93 skype : kaaloo
Luis Arias wrote:
Interesting discussion ! You might want to think about using the webdav methods such as MOVE or COPY in some instances (wiki / space / page / attachment (?) ) which could be useful for refactoring content organization or for administrative purposes.
Just a thought
Luis
I don't think it can be done, as HTTP servers and clients usually don't allow other verbs to be used. -- Sergiu Dumitriu http://purl.org/net/sergiu/
I think they are well supported by the restlet framework and most http servers support webdav. There may be issues with client libraries, probably not java, but maybe javascript libraries not supporting those verbs though. Might be worth checking out though instead of tunneling, using a sequence of existing verbs, or not providing that type of feature in the api. Luis On Tue, Dec 16, 2008 at 2:02 AM, Sergiu Dumitriu <[email protected]> wrote:
Luis Arias wrote:
Interesting discussion ! You might want to think about using the webdav methods such as MOVE or COPY in some instances (wiki / space / page / attachment (?) ) which could be useful for refactoring content organization or for administrative purposes.
Just a thought
Luis
I don't think it can be done, as HTTP servers and clients usually don't allow other verbs to be used. -- Sergiu Dumitriu http://purl.org/net/sergiu/ _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
-- Luis Arias +33 6 14 20 87 93 skype : kaaloo
Dear all, I've integrated the remarks done by Sergiu about verbose URIs, object properties and attachment versions. Just a comment about the .format. I agree with the fact that there are some degenerate cases like "How to open a .pdf" and some ambiguous cases as well like "How to open a .tar.gz" The idea here is to have a way for specifying a format even without having control about the Accept header (i.e., with a simple browser). For handling degenerate cases a simple test can be made on the page name. And the format should be a simple string with no dots so .tar.gz should actually be expressed as .tgz Frankly I find very useful to have a way of typing the URI of a page in a browser, stick a .pdf suffix and have Acrobat opened on the PDF rendering. Alternatively, a ?format=XYZ query string can be used instead of the .format convention. The .format thing, actually, is a "Railism" (e.g., see http://weblog.rubyonrails.org/2006/12/19/using-custom-mime-types). Of course we can decide whether Accept headers have higher priority or not. -Fabio
Hi, here's my 2 cents re the first proposal... Why do we have separation between objects and tags/comments? Shouldn't the objects mapping be enough to handle them? And speaking of objects where is the path to get all objects, not just from a page? I propose: * /objects[?start=offset&number=n] (The list of objects in the wiki) * /objects/{className}/ (All the object of class {className} in the wiki) <-- missing * /object/guid/{guid} (The object identified by its {guid}) * /object/guid/{guid}/properties (The property list for the object identified by its {guid}) * /object/guid/{guid}/properties/{property} (The property for the object identified by its {guid}) * /object/guid/{guid}/history/{version} (The version {version} of the object identified by {guid}) * /object/guid/{guid}/history/{version}/properties (The property list for the version {version} of the object identified by {guid}) * /space/{space}/page/{page}/objects[?start=offset&number=n] (The list of objects associated to a {page}) * /space/{space}/page/{page}/objects/{className}/ (All the object of class {className} in a {page}) <-- missing * /space/{space}/page/{page}/history/{version}/objects[?start=offset&number=n] (The list of objects associated to a {page}'s {version}) * /space/{space}/page/{page}/history/{version}/objects/{className}/ (All the object of class {className} in a {page}'s {version}) <-- missing Do we still need this, since the object's number should be deprecated by the use of the guid: * /space/{space}/page/{page}/object/{className}/{objectNumber} (The object identified by {id}) * /space/{space}/page/{page}/object/{className}/{objectNumber}/properties (The property list for the object identified by {id}) * /space/{space}/page/{page}/object/{className}/{objectNumber}/properties/{property} (The property the object identified by {id}) And does it make sense to have this, when we already know the guid of the object we want: * /spaces/{space}/pages/{page}/objects/guid/{guid} (The object identified by its {guid}) * /spaces/{space}/pages/{page}/objects/guid/{guid}/properties (The property list for the object identified by its {guid}) * /spaces/{space}/pages/{page}/objects/guid/{guid}/properties/{property} (The property for the object identified by its {guid}) The semantics implies that object operations can be performed on: - a page - an older version of a page (read-only) - the wiki IMO, it's more flexible this way. With this mapping you should have access to comments/tags (and attachments?). The drawback would be that we loose: * /tags/{tag1}[,{tag2},{tag3}...][?start=offset&number=n] (The list of pages tagged with tags {tag1}, {tag2}, {tag3}, ...) Of course, we could still have it as a convention or we could even create a generic way of getting this result with other objects as well. Related to pages, we could also have: * /pages[?start=offset&number=n] (The list of available pages in the space in the entire wiki) Could we need it? Thanks. P.S.: From what I asked around, it seems that attachments are not objects. That seems weird to me because, intuitively, the attachments should be objects on a page of the class Attachment. On attachments you have versioning, meta-data and an attachment can exist on a page or not, the behaviour of an object. Could anybody explain the reason for this please? Fabio Mancinelli wrote:
Dear all,
I worked a bit on the design of the RESTful API and as a result I've integrated what was written on the http://dev.xwiki.org/xwiki/bin/view/Design/RestfulAPI page.
There is still a big and important part missing (maybe the most important one), i.e., the one about the data formats for representations (in particular the XML schemas to be used in requests and responses). I am working on it.
Anyway you can already comment on what is present on the page.
Thank you.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Dec 16, 2008, at 10:50 AM, Eduard Moraru wrote: [snip]
P.S.: From what I asked around, it seems that attachments are not objects. That seems weird to me because, intuitively, the attachments should be objects on a page of the class Attachment. On attachments you have versioning, meta-data and an attachment can exist on a page or not, the behaviour of an object. Could anybody explain the reason for this please?
I think I agree (need to think more of consequences). Probably historical reason. Attachments have a separate store but we could generalize this to let objects have an optional separate store too. Something to keep in mind when we redesign the model. Ludovic, any input from you on this? Thanks -Vincent
Vincent Massol wrote:
On Dec 16, 2008, at 10:50 AM, Eduard Moraru wrote:
[snip]
P.S.: From what I asked around, it seems that attachments are not objects. That seems weird to me because, intuitively, the attachments should be objects on a page of the class Attachment. On attachments you have versioning, meta-data and an attachment can exist on a page or not, the behaviour of an object. Could anybody explain the reason for this please?
I think I agree (need to think more of consequences). Probably historical reason. Attachments have a separate store but we could generalize this to let objects have an optional separate store too.
The problem is that we don't have property types suited for storing attachments. The largest one is TextArea, which can hold 60k, not enough for most attachments. Other problems are: - Different storage for attachments, as they tend to be quite big. Storing objects on the filesystem is not good, since we need to query objects, something not easy (or efficient) to do on the FS. - Users should not be able to edit attachments using the object editor, since most attachments are binary. - Harder to track the history of objects, and we need to display attachments' history. - Harder to ensure that no 2 objects with the same filename are specified. - Lucene plugin has to be adapted a lot - Lots of API breakage -- Sergiu Dumitriu http://purl.org/net/sergiu/
Eduard Moraru wrote:
Hi, here's my 2 cents re the first proposal...
Why do we have separation between objects and tags/comments? Shouldn't the objects mapping be enough to handle them?
Of course objects are enough to handle them but since comments and tags are very "useful" objects imho it's worth to expose them *also* as separate resources that can accept specific media types. I mean, imagine you want to tag a page. If you have /spaces/{space}/pages/{page}/tags You can do a POST to that URI by sending, for example, just the new tag. Something like: curl -d "foo" http://localhost:8080/spaces/Main/pages/WebHome/tags If you handle this *only* with objects you will need to post a more complex media type, typically an XML containing the property name, value, etc. Same thing for comments: curl -d "I like this page" http://localhost:8080/spaces/Main/pages/WebHome/comments
And does it make sense to have this, when we already know the guid of the object we want:
I agree that with guid the old way of identifying objects is useless. I put it in the resource list because it is the current way of identifying objects. And maybe somebody has a reason to leave it.
The drawback would be that we loose: * /tags/{tag1}[,{tag2},{tag3}...][?start=offset&number=n] (The list of pages tagged with tags {tag1}, {tag2}, {tag3}, ...) Of course, we could still have it as a convention or we could even create a generic way of getting this result with other objects as well.
I don't understand why you say we "loose". If we want to expose a /tags resource we can do this. And I think that it's a resource worth to be exposed.
Related to pages, we could also have: * /pages[?start=offset&number=n] (The list of available pages in the space in the entire wiki) Could we need it?
Probably for indexing purposes that could be useful.
Thanks.
P.S.: From what I asked around, it seems that attachments are not objects. That seems weird to me because, intuitively, the attachments should be objects on a page of the class Attachment. On attachments you have versioning, meta-data and an attachment can exist on a page or not, the behaviour of an object. Could anybody explain the reason for this please?
AFAIK, it's for historical reason. Yesterday I was asking ThomasM how attachments work because me too I found it a bit counterintuitive. Thanks. -Fabio
Sorry for the typo. (loose -> lose) Could we also need the selectors(as I earlier mentioned but probably did not get noticed): - All objects of the class {className} in a {page}, {page}'s {version} or the entire wiki? /objects/class/{className}/ /space/{space}/page/{page}/objects/{className}/ /space/{space}/page/{page}/history/{version}/objects/{className}/ possibly with the added: [?start=offset&number=n] Fabio Mancinelli wrote:
Eduard Moraru wrote:
Hi, here's my 2 cents re the first proposal...
Why do we have separation between objects and tags/comments? Shouldn't the objects mapping be enough to handle them?
Of course objects are enough to handle them but since comments and tags are very "useful" objects imho it's worth to expose them *also* as separate resources that can accept specific media types.
I mean, imagine you want to tag a page. If you have /spaces/{space}/pages/{page}/tags
You can do a POST to that URI by sending, for example, just the new tag. Something like:
curl -d "foo" http://localhost:8080/spaces/Main/pages/WebHome/tags
If you handle this *only* with objects you will need to post a more complex media type, typically an XML containing the property name, value, etc.
Same thing for comments:
curl -d "I like this page" http://localhost:8080/spaces/Main/pages/WebHome/comments
And does it make sense to have this, when we already know the guid of the object we want:
I agree that with guid the old way of identifying objects is useless. I put it in the resource list because it is the current way of identifying objects. And maybe somebody has a reason to leave it.
The drawback would be that we loose: * /tags/{tag1}[,{tag2},{tag3}...][?start=offset&number=n] (The list of pages tagged with tags {tag1}, {tag2}, {tag3}, ...) Of course, we could still have it as a convention or we could even create a generic way of getting this result with other objects as well.
I don't understand why you say we "loose". If we want to expose a /tags resource we can do this. And I think that it's a resource worth to be exposed.
Related to pages, we could also have: * /pages[?start=offset&number=n] (The list of available pages in the space in the entire wiki) Could we need it?
Probably for indexing purposes that could be useful.
Thanks.
P.S.: From what I asked around, it seems that attachments are not objects. That seems weird to me because, intuitively, the attachments should be objects on a page of the class Attachment. On attachments you have versioning, meta-data and an attachment can exist on a page or not, the behaviour of an object. Could anybody explain the reason for this please?
AFAIK, it's for historical reason. Yesterday I was asking ThomasM how attachments work because me too I found it a bit counterintuitive.
Thanks.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Eduard Moraru wrote:
Sorry for the typo. (loose -> lose)
Actually it was not for the typo (I read it as "lose" anyway) but for the overall meaning. As I replied earlier, I don't understand why you said that we could lose /tags as a drawback... If we want it to be there we just put it there :) And I think that's a good resource to have.
Could we also need the selectors(as I earlier mentioned but probably did not get noticed): - All objects of the class {className} in a {page}, {page}'s {version} or the entire wiki?
/objects/class/{className}/
This could be indeed useful, but maybe we don't really need it, do we? Do you have an use case for this?
/space/{space}/page/{page}/objects/{className}/
/space/{space}/page/{page}/history/{version}/objects/{className}/
Yes, they are missing. Now that we have spent some time thinking to URI design, the next phase is to start thinking about media types design which, imho, is even more important. A remark here... Having these URI is good because they are meaningful and clients can guess. However the RESTful API should be, above all, hypermedia driven by what clients receive as a result of their requests (i.e., the media types). So for example the "discovery" of the available resources (whatever is their URI) should be made by following links and by interpreting media types. Infact, if we hard-code those URI in a client we just end up with a pseudo-XMLRPC api that uses HTTP as its semantics and custom media types for request/response. Moreover we increase the coupling between the client and the server (in case one day we decide that a given URI is not anymore appropriate). Not very RESTful[1] Fielding in [1] says, besides other interesting things, that "A REST API should be entered with no prior knowledge beyond the initial URI (bookmark)" This is what happens, for example, with Atom Service documents that are the "entry point" for all atom collections. Clients are then driven by the media type representing those collection till the "edit URI" of an entry for updating its content. So I was thinking that rooted at the toplevel / there should be a "service document". Something like: <xwiki> <link rel="spaces" href="spaces"/> <link rel="tags" href="tags"/> <link rel="watchlist" href="watchlist"/> </xwiki> These elements will give the URIs to the toplevel hierarchy for discovering all the rest. A thing to be noted here is that URIs are generated by the server that has full control of its own "namespace". What is important here is the semantics of the rel elements. Following the same principle documents served at a given URI should be rich in terms of links (properly "annotated" with rel-like attibutes) in order to allow clients to "discover" more resources. What is important is that we establish a good semantic model and a good set of elements in media types so that clients can understand what they receive. Of course the set of the available elements can be extended in the future. Old clients will still be able to understand what is server (they will ignore new items). New clients will be able to take full advantage of the new exposed resources. This is what happens with the GData extension. Basically Google is using Atom + GData extensions in order to provide resource representations. A plain Atom client is still able to understand what is "available"... But, for example, it will miss the geolocation of the different items! The same principle should drive, imho, our media types. Maybe we could also rely on Atom[2] as well as the foundation for our media types. Anyway looking at the Atom Syndication Format[3] and the Atom Publishing Protocol[4][5] and above all at its mechanism for specifying metadata and links to actual data could be very useful in order to design a useful and a good RESTful API. My 2 cents. -Fabio [1] http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven [2] http://abdera.apache.org/ [3] http://www.ietf.org/rfc/rfc4287.txt [4] http://www.ietf.org/rfc/rfc5023.txt [5] http://www-128.ibm.com/developerworks/library/x-atompp1/
Fabio Mancinelli wrote:
Eduard Moraru wrote:
Sorry for the typo. (loose -> lose)
Actually it was not for the typo (I read it as "lose" anyway) but for the overall meaning.
As I replied earlier, I don't understand why you said that we could lose /tags as a drawback... If we want it to be there we just put it there :) And I think that's a good resource to have.
The discussion was about consistency and predictability vs conventions for usability, but in our case and the use-cases you provided it would make sense to keep /tags.
Could we also need the selectors(as I earlier mentioned but probably did not get noticed): - All objects of the class {className} in a {page}, {page}'s {version} or the entire wiki?
/objects/class/{className}/
This could be indeed useful, but maybe we don't really need it, do we? Do you have an use case for this?
Standard use (With the current classes): /objects/class/XWiki.TagClass/ - all tag objects in the wiki (as a consistent alternative to /tags) Of course, depending on the user-logic of the user-created classes, such methods could be useful. We could also choose to complicate things(just a thought) by providing XPATH-like queries by giving access to object/page's default fields like parent and such. Example: /objects/class/XWiki.SingleInstancePerPageClass/parent - list of all pages containing maximum one object of the class SingleInstancePerPageClass with user-logic functionality. This could spare some server queries among other things.
/space/{space}/page/{page}/objects/{className}/
/space/{space}/page/{page}/history/{version}/objects/{className}/
Yes, they are missing. Now that we have spent some time thinking to URI design, the next phase is to start thinking about media types design which, imho, is even more important.
A remark here... Having these URI is good because they are meaningful and clients can guess. However the RESTful API should be, above all, hypermedia driven by what clients receive as a result of their requests (i.e., the media types).
So for example the "discovery" of the available resources (whatever is their URI) should be made by following links and by interpreting media types.
Infact, if we hard-code those URI in a client we just end up with a pseudo-XMLRPC api that uses HTTP as its semantics and custom media types for request/response. Moreover we increase the coupling between the client and the server (in case one day we decide that a given URI is not anymore appropriate). Not very RESTful[1]
Fielding in [1] says, besides other interesting things, that "A REST API should be entered with no prior knowledge beyond the initial URI (bookmark)"
This is what happens, for example, with Atom Service documents that are the "entry point" for all atom collections. Clients are then driven by the media type representing those collection till the "edit URI" of an entry for updating its content.
So I was thinking that rooted at the toplevel / there should be a "service document". Something like:
<xwiki> <link rel="spaces" href="spaces"/> <link rel="tags" href="tags"/> <link rel="watchlist" href="watchlist"/> </xwiki>
These elements will give the URIs to the toplevel hierarchy for discovering all the rest. A thing to be noted here is that URIs are generated by the server that has full control of its own "namespace". What is important here is the semantics of the rel elements.
Following the same principle documents served at a given URI should be rich in terms of links (properly "annotated" with rel-like attibutes) in order to allow clients to "discover" more resources. What is important is that we establish a good semantic model and a good set of elements in media types so that clients can understand what they receive.
Of course the set of the available elements can be extended in the future. Old clients will still be able to understand what is server (they will ignore new items). New clients will be able to take full advantage of the new exposed resources. This is what happens with the GData extension. Basically Google is using Atom + GData extensions in order to provide resource representations. A plain Atom client is still able to understand what is "available"... But, for example, it will miss the geolocation of the different items!
The same principle should drive, imho, our media types. Maybe we could also rely on Atom[2] as well as the foundation for our media types.
Anyway looking at the Atom Syndication Format[3] and the Atom Publishing Protocol[4][5] and above all at its mechanism for specifying metadata and links to actual data could be very useful in order to design a useful and a good RESTful API.
My 2 cents.
-Fabio
[1] http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
[3] http://www.ietf.org/rfc/rfc4287.txt
[4] http://www.ietf.org/rfc/rfc5023.txt
[5] http://www-128.ibm.com/developerworks/library/x-atompp1/
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Also take into account that it could be used in parallel with a static set of URIs for performance reasons. Accessing a resource like objects in a page could end up with a lot of queries to the server, just to make sure that the syntax has not changed. I don't think that REST APIs change that often. +1 for resource discovery in general.
Dear all, I haven't seen any comment about the second proposal I did. It basically "moves" some URI path elements to the parameter list. These elements are the ones that introduces a degree of variability wrt to the resource, namely language and version. For example with a single URI: /spaces/{space}/pages/{page}[?lang=l&version=v] I can get the page at its latest version in the default language (no query parameters) or, by combining the query parameters, any page at a specific version in a given language. I think it is worth thinking about it because, by following the previous example, the 8 URIs in the "pages" section could be reduced to 4. Similarly for other resources where the "version element" basically introduces a doubling of the resources to be exposed (e.g., as it happens with objects and attachments). WDYT? -Fabio
On Dec 18, 2008, at 11:39 AM, Fabio Mancinelli wrote:
Dear all,
I haven't seen any comment about the second proposal I did. It basically "moves" some URI path elements to the parameter list. These elements are the ones that introduces a degree of variability wrt to the resource, namely language and version.
For example with a single URI:
/spaces/{space}/pages/{page}[?lang=l&version=v]
I can get the page at its latest version in the default language (no query parameters) or, by combining the query parameters, any page at a specific version in a given language.
I think it is worth thinking about it because, by following the previous example, the 8 URIs in the "pages" section could be reduced to 4. Similarly for other resources where the "version element" basically introduces a doubling of the resources to be exposed (e.g., as it happens with objects and attachments).
WDYT?
I don't like it since I'm not sure this is very RESTful. But then I'm no REST expert. Thanks -Vincent
Vincent Massol wrote:
I don't like it since I'm not sure this is very RESTful.
But then I'm no REST expert.
Actually I think you're right. I checked the "URI design" section of the Restful Web Services book, they suggest to "use query variables only to suggest arguments being plugged into an algorithm" (e.g., Google search "q" parameter) So, since a "page" doesn't seem to be an algorithm, I think the second proposal is not in line with the "good practices". Never mind. Thanks. -Fabio
Vincent Massol wrote:
On Dec 18, 2008, at 11:39 AM, Fabio Mancinelli wrote:
Dear all,
I haven't seen any comment about the second proposal I did. It basically "moves" some URI path elements to the parameter list. These elements are the ones that introduces a degree of variability wrt to the resource, namely language and version.
For example with a single URI:
/spaces/{space}/pages/{page}[?lang=l&version=v]
I can get the page at its latest version in the default language (no query parameters) or, by combining the query parameters, any page at a specific version in a given language.
I think it is worth thinking about it because, by following the previous example, the 8 URIs in the "pages" section could be reduced to 4. Similarly for other resources where the "version element" basically introduces a doubling of the resources to be exposed (e.g., as it happens with objects and attachments).
WDYT?
I don't like it since I'm not sure this is very RESTful.
+1, but it depends. A resource is identified by the path, without query parameters. The question is, is there only one resource, with multiple variants, or each translation/version is a resource? And we'd still need some path to get the list of versions. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Sergiu Dumitriu wrote:
I don't like it since I'm not sure this is very RESTful.
+1, but it depends.
A resource is identified by the path, without query parameters.
Not sure about this... At the protocol level, AFAIK, query parameters are part of the URI an though they contribute to identify the resource. So, at this level, imho, it is almost a philosophical or best practice matter. Anyway I thought again about query parameters and actually the main reason why they are problematic is because apparently many caching agents, by default, don't take into account query parameters. Squid, for example, does so (but it can cache resources by using the full URI http://foo/bar?param=value if configured properly). So if we want to be sure that caching occurs, maybe it's best to identify cacheable resources without using query parameters. -Fabio
Fabio Mancinelli wrote:
Sergiu Dumitriu wrote:
I don't like it since I'm not sure this is very RESTful. +1, but it depends.
A resource is identified by the path, without query parameters.
Not sure about this... At the protocol level, AFAIK, query parameters are part of the URI an though they contribute to identify the resource.
So, at this level, imho, it is almost a philosophical or best practice matter.
Yes, it is. But the whole REST concept is a best practice on top of something old. After all, it's just a way of using classic HTTP in a special way. There are no hard validation rules yet, and the fact that something is or isn't REST depends on the person you ask. And if you ask me, the path is the identifier of the resource, while query parameters and HTTP headers only influence the representation. So, is the version/language a different representation of the same resource (the document), or a whole different resource? This is also a philosophical question, and we might have different opinions on this one, too. And the answer depends on the involved content, too. About the long URLs, many coding books suggest that longer, descriptive names are better than very short ones. A name should be long enough to describe what it holds, but from all the possibilities, the shorter ones are preferable. Short, _understandable_ names. A URL is a name, too. We should favor understandability over shortness.
Anyway I thought again about query parameters and actually the main reason why they are problematic is because apparently many caching agents, by default, don't take into account query parameters. Squid, for example, does so (but it can cache resources by using the full URI http://foo/bar?param=value if configured properly).
So if we want to be sure that caching occurs, maybe it's best to identify cacheable resources without using query parameters.
-Fabio
-- Sergiu Dumitriu http://purl.org/net/sergiu/
On Dec 24, 2008, at 3:55 AM, Sergiu Dumitriu wrote:
Fabio Mancinelli wrote:
Sergiu Dumitriu wrote:
I don't like it since I'm not sure this is very RESTful. +1, but it depends.
A resource is identified by the path, without query parameters.
Not sure about this... At the protocol level, AFAIK, query parameters are part of the URI an though they contribute to identify the resource.
So, at this level, imho, it is almost a philosophical or best practice matter.
Yes, it is. But the whole REST concept is a best practice on top of something old. After all, it's just a way of using classic HTTP in a special way. There are no hard validation rules yet, and the fact that something is or isn't REST depends on the person you ask. And if you ask me, the path is the identifier of the resource, while query parameters and HTTP headers only influence the representation. So, is the version/language a different representation of the same resource (the document), or a whole different resource? This is also a philosophical question, and we might have different opinions on this one, too. And the answer depends on the involved content, too.
About the long URLs, many coding books suggest that longer, descriptive names are better than very short ones. A name should be long enough to describe what it holds, but from all the possibilities, the shorter ones are preferable. Short, _understandable_ names. A URL is a name, too. We should favor understandability over shortness.
+1 to that. -Vincent
Anyway I thought again about query parameters and actually the main reason why they are problematic is because apparently many caching agents, by default, don't take into account query parameters. Squid, for example, does so (but it can cache resources by using the full URI http://foo/bar?param=value if configured properly).
So if we want to be sure that caching occurs, maybe it's best to identify cacheable resources without using query parameters.
-Fabio
+1 to both issues. Sergiu Dumitriu wrote:
Fabio Mancinelli wrote:
Sergiu Dumitriu wrote:
I don't like it since I'm not sure this is very RESTful.
+1, but it depends.
A resource is identified by the path, without query parameters.
Not sure about this... At the protocol level, AFAIK, query parameters are part of the URI an though they contribute to identify the resource.
So, at this level, imho, it is almost a philosophical or best practice matter.
Yes, it is. But the whole REST concept is a best practice on top of something old. After all, it's just a way of using classic HTTP in a special way. There are no hard validation rules yet, and the fact that something is or isn't REST depends on the person you ask. And if you ask me, the path is the identifier of the resource, while query parameters and HTTP headers only influence the representation. So, is the version/language a different representation of the same resource (the document), or a whole different resource? This is also a philosophical question, and we might have different opinions on this one, too. And the answer depends on the involved content, too.
About the long URLs, many coding books suggest that longer, descriptive names are better than very short ones. A name should be long enough to describe what it holds, but from all the possibilities, the shorter ones are preferable. Short, _understandable_ names. A URL is a name, too. We should favor understandability over shortness.
Anyway I thought again about query parameters and actually the main reason why they are problematic is because apparently many caching agents, by default, don't take into account query parameters. Squid, for example, does so (but it can cache resources by using the full URI http://foo/bar?param=value if configured properly).
So if we want to be sure that caching occurs, maybe it's best to identify cacheable resources without using query parameters.
-Fabio
Sergiu Dumitriu wrote:
Yes, it is. But the whole REST concept is a best practice on top of something old. After all, it's just a way of using classic HTTP in a special way. There are no hard validation rules yet, and the fact that something is or isn't REST depends on the person you ask.
The ultimate validation is Roy Fielding's thesis. Anyway, I am not against what we have said. What I would like to avoid is to build a so called RESTful Api that is not RESTful and that would be criticized as this API http://wikis.glassfish.org/socialsite/Wiki.jsp?page=FinalizeRESTAPI in this post http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
About the long URLs, many coding books suggest that longer, descriptive names are better than very short ones. A name should be long enough to describe what it holds, but from all the possibilities, the shorter ones are preferable. Short, _understandable_ names. A URL is a name, too. We should favor understandability over shortness.
I am +1 about this, don't misunderstand me. Now the problem is to use these URI in a proper RESTful context. Well conceived media types and hypermedia leverage is the biggest challenge now. -Fabio
One thing I haven't heard in this discussion is the usage of links. That's a crucial feature of anything REST. Have you looked at prescod.net? Paul Le 25-déc.-08 à 18:33, Fabio Mancinelli <[email protected]> a écrit :
Sergiu Dumitriu wrote:
Yes, it is. But the whole REST concept is a best practice on top of something old. After all, it's just a way of using classic HTTP in a special way. There are no hard validation rules yet, and the fact that something is or isn't REST depends on the person you ask.
The ultimate validation is Roy Fielding's thesis.
Anyway, I am not against what we have said.
What I would like to avoid is to build a so called RESTful Api that is not RESTful and that would be criticized as this API http://wikis.glassfish.org/socialsite/Wiki.jsp?page=FinalizeRESTAPI in this post http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
About the long URLs, many coding books suggest that longer, descriptive names are better than very short ones. A name should be long enough to describe what it holds, but from all the possibilities, the shorter ones are preferable. Short, _understandable_ names. A URL is a name, too. We should favor understandability over shortness.
I am +1 about this, don't misunderstand me. Now the problem is to use these URI in a proper RESTful context. Well conceived media types and hypermedia leverage is the biggest challenge now.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Paul Libbrecht wrote:
One thing I haven't heard in this discussion is the usage of links. That's a crucial feature of anything REST.
Have you looked at prescod.net?
Yes, read all of it someday in the past. Anyway the "hypermedia as the engine of application state" has been a recent hot-topic of the REST community since when Fielding did the post I cited in my previous mail. Recently a very nice article has been published on InfoQ about the subject: http://www.infoq.com/articles/subbu-allamaraju-rest I have linked all the references I have cited on the XWiki page about the RESTful API design on Xwiki.org for keeping track of the background discussion. Thanks. -Fabio
Dear all, we had some comments from Jerome Louvel (the author of Restlet). I will summarize them here FYI. Things in double square brackets are comments of mine. 1) Use more specific variable names in URI templates (e.g., spaceId, pageId, etc.) [[Already updated on the wiki page]] 2) Use ';' instead of ',' as a separator since it complies better with the definition of URI matrix by Tim Berners Lee [[Already updated on the wiki page]] 3) /watchlist seems a strange resource. Isn't it associated to a user? If yes this should be made explicit like "/accounts/{accountId}/watchlist[?start=offset&number=n]" [[Right. However I was implicitly supposing that every request provides authentication info (guest included). So basically the user is implicitly given at every request in a header]] 4) Content negotiation via suffixes is transparently supported by Restlet through the TunnelService 5) The second proposal seems to be more simple. If the version is not specified in query parameters, it is expected to be the latest one. This should be precised. [[Already updated on the wiki page]] [[I am collecting some more info about the second proposal. I started also a discussion on the REST discussion group in order to have more feedback]] 6) Representation description is missing. [[Working on it, see previous mails]] 7) Think about WADL for describing the API in a dynamic way. Restlet supports the automatic generation of a java-doc like documentation of the API through Yahoo! XSLT. [[I am investigating it]] Thanks to Jerome for his precious comments. -Fabio
On Dec 19, 2008, at 5:41 PM, Fabio Mancinelli wrote:
Dear all,
we had some comments from Jerome Louvel (the author of Restlet). I will summarize them here FYI. Things in double square brackets are comments of mine.
1) Use more specific variable names in URI templates (e.g., spaceId, pageId, etc.) [[Already updated on the wiki page]]
2) Use ';' instead of ',' as a separator since it complies better with the definition of URI matrix by Tim Berners Lee [[Already updated on the wiki page]]
3) /watchlist seems a strange resource. Isn't it associated to a user? If yes this should be made explicit like "/accounts/{accountId}/watchlist[?start=offset&number=n]" [[Right. However I was implicitly supposing that every request provides authentication info (guest included). So basically the user is implicitly given at every request in a header]]
Does this mean I cannot open my browser and call the REST URL without specifying a user? Thanks -Vincent
4) Content negotiation via suffixes is transparently supported by Restlet through the TunnelService
5) The second proposal seems to be more simple. If the version is not specified in query parameters, it is expected to be the latest one. This should be precised. [[Already updated on the wiki page]] [[I am collecting some more info about the second proposal. I started also a discussion on the REST discussion group in order to have more feedback]]
6) Representation description is missing. [[Working on it, see previous mails]]
7) Think about WADL for describing the API in a dynamic way. Restlet supports the automatic generation of a java-doc like documentation of the API through Yahoo! XSLT. [[I am investigating it]]
Thanks to Jerome for his precious comments.
-Fabio
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access. Cannot we default to guest when no username/account is specified? Thanks -Vincent
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Well, when a resource is requested for the first time (i.e., a request with no auth headers) either the server assume that is a guest or it sends back a challenge (e.g., auth basic) in order to request an auth header. It's this challenge that makes the browser open the popup. So if we want to be able to authenticate users that types URIs in a browser we need to make this popup open. AFAIK this is the only way for making the browser send an auth header. Otherwise a user that types URIs in a plain browser will always results as "guest". For automation I don't really see the problem. If we are going to write a script or another automated agent, for example using curl, we can always stick an auth header starting from the first request and no challenge will be generated: the server will provide the requested resource (provided that the credentials in the auth header are correct) -Fabio
On Dec 19, 2008, at 6:57 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Well, when a resource is requested for the first time (i.e., a request with no auth headers) either the server assume that is a guest or it sends back a challenge (e.g., auth basic) in order to request an auth header.
It's this challenge that makes the browser open the popup. So if we want to be able to authenticate users that types URIs in a browser we need to make this popup open. AFAIK this is the only way for making the browser send an auth header. Otherwise a user that types URIs in a plain browser will always results as "guest".
For automation I don't really see the problem. If we are going to write a script or another automated agent, for example using curl, we can always stick an auth header starting from the first request and no challenge will be generated: the server will provide the requested resource (provided that the credentials in the auth header are correct)
I have the feeling that REST services that I have used in the past don't do this. For ex I can open a browser and type: http://repository.sonatype.org/service/local/repositories And it just gives me the answer without having to type anything. See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API I really prefer it this way. We need to make it extra easy to query IMO (for open wikis). Thanks -Vincent
On Dec 19, 2008, at 7:06 PM, Vincent Massol wrote:
On Dec 19, 2008, at 6:57 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Well, when a resource is requested for the first time (i.e., a request with no auth headers) either the server assume that is a guest or it sends back a challenge (e.g., auth basic) in order to request an auth header.
It's this challenge that makes the browser open the popup. So if we want to be able to authenticate users that types URIs in a browser we need to make this popup open. AFAIK this is the only way for making the browser send an auth header. Otherwise a user that types URIs in a plain browser will always results as "guest".
For automation I don't really see the problem. If we are going to write a script or another automated agent, for example using curl, we can always stick an auth header starting from the first request and no challenge will be generated: the server will provide the requested resource (provided that the credentials in the auth header are correct)
I have the feeling that REST services that I have used in the past don't do this.
For ex I can open a browser and type: http://repository.sonatype.org/service/local/repositories
And it just gives me the answer without having to type anything.
See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API
I really prefer it this way. We need to make it extra easy to query IMO (for open wikis).
BTW the source code is available here: http://svn.sonatype.org/nexus/trunk/nexus/nexus-rest-api/ Thanks -Vincent
Vincent Massol wrote:
For ex I can open a browser and type: http://repository.sonatype.org/service/local/repositories
And it just gives me the answer without having to type anything.
Because resources are not restricted and they can be browsed as "guest".
See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API
I really prefer it this way. We need to make it extra easy to query IMO (for open wikis).
Even there they state that "A user may be authenticated by providing their credentials to /authentication/login OR to any restricted resource in the form of HTTP Basic formatted data in the Authorization HTTP header of the request. The response will include the authToken as a value in the data response to the request." Now since in our case, imho, every resource can be considered "restricted" (starting from the space list, because its representation depends on the actual user requesting it) this boils down to what I was saying. But the link you provided contains an interesting alternative! (To be verified) We could provide a /authentication resource which provides a challenge for plain browser users. So basically if the user requests a resource, it will always be served as if he were guest. In order to access to the "restricted" representation it must before visit the /authentication and provide credentials (through the popup). Then he could visit other resources that will be server by taking into account the auth header that the browser (hopefully) sends. The only concern is whether the browser, after the authentication, sends at each subsequent request to the site the auth header. Of course here I am speaking only about an interaction with a plain browser. Anyway this is an important aspect that must be discusses in depth. Others, WDYT? -Fabio
Vincent Massol wrote:
On Dec 19, 2008, at 6:57 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource. Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Well, when a resource is requested for the first time (i.e., a request with no auth headers) either the server assume that is a guest or it sends back a challenge (e.g., auth basic) in order to request an auth header.
It's this challenge that makes the browser open the popup. So if we want to be able to authenticate users that types URIs in a browser we need to make this popup open. AFAIK this is the only way for making the browser send an auth header. Otherwise a user that types URIs in a plain browser will always results as "guest".
For automation I don't really see the problem. If we are going to write a script or another automated agent, for example using curl, we can always stick an auth header starting from the first request and no challenge will be generated: the server will provide the requested resource (provided that the credentials in the auth header are correct)
I have the feeling that REST services that I have used in the past don't do this.
For ex I can open a browser and type: http://repository.sonatype.org/service/local/repositories
And it just gives me the answer without having to type anything.
See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API
I really prefer it this way. We need to make it extra easy to query IMO (for open wikis).
+1 -- Sergiu Dumitriu http://purl.org/net/sergiu/
Sergiu Dumitriu wrote:
See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API
I really prefer it this way. We need to make it extra easy to query IMO (for open wikis).
+1
I have looked at https://docs.sonatype.com/display/Nx/Nexus+Rest+API and, in the authentication section they state: GET - /authentication/logout - Expire an authToken Authorization Header This is completely UNRestFul, since it subvert the semantics of the GET verb (safe and idempotent), and it encodes in the URI an operation and not a resource. I am -1 for this. -Fabio
On Dec 21, 2008, at 12:55 PM, Fabio Mancinelli wrote:
Sergiu Dumitriu wrote:
See the Authentication section of https://docs.sonatype.com/display/Nx/Nexus+Rest+API
I really prefer it this way. We need to make it extra easy to query IMO (for open wikis).
+1
I have looked at https://docs.sonatype.com/display/Nx/Nexus+Rest+API and, in the authentication section they state:
GET - /authentication/logout - Expire an authToken Authorization Header
This is completely UNRestFul, since it subvert the semantics of the GET verb (safe and idempotent), and it encodes in the URI an operation and not a resource.
I am -1 for this.
I have no idea about implementation. All I was saying is that IMO we should offer a REST API that works when not authenticated (in that case the user is considered Guest). -Vincent
Vincent Massol wrote:
I have no idea about implementation. All I was saying is that IMO we should offer a REST API that works when not authenticated (in that case the user is considered Guest).
Maybe there was a misunderstanding. I agree with you. I just didn't agree with the way Nexus does it. Anyway I committed a tentative implementation of the behavior you were suggesting in the sandbox. -Fabio
Look at this article which shows an even worse example by SUN:) http://developers.sun.com/identity/reference/techart/id-svcs.html To my mind: /authentication could be a resource /authentication/logout is not resource but an action... Something like /authentication with something like a "state=logout" in parameters or body would be better... REST would require this to be a POST and not a GET because it means you change the resource... But it would mean you can't logout without sending a POST request which is not practical to my mind... So, the question is: can we find a way to make logout look like it doesn't change the authentication resource?... hummmm OK, it's stupid because I'm just trying to make the problem fit the REST architecture. This is certainly not a solution, just a misuse of the architecture...
From my point of view, REST is an architecture model which doesn't fit for anything... Sometimes, you can't fulfill all its requirements and you have to accept some steps aside the theory...
so something like "GET /authorization?state=logout" might not be exactly RESTful but it is acceptable for my intellect ;) regards Pascal On Sun, Dec 21, 2008 at 10:29 PM, Fabio Mancinelli < [email protected]> wrote:
Vincent Massol wrote:
I have no idea about implementation. All I was saying is that IMO we should offer a REST API that works when not authenticated (in that case the user is considered Guest).
Maybe there was a misunderstanding. I agree with you. I just didn't agree with the way Nexus does it.
Anyway I committed a tentative implementation of the behavior you were suggesting in the sandbox.
-Fabio _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Hello, Looking at the proposal again, I feel it has a very document oriented perspective and does not do justice to the primary use case of a wiki which is collaborative work. So for instance, a user is not viewed as a resource. That means that if I want to know what a user's recent activity on a space that we share, well it would probably require some processing with the current api. I would have liked to have done something like a GET on /users/{userId}/spaces/{spaceId}/recent Anyhow that is a real common use case, who has done what on a shared work space. The notion of a group of users is also missing so it wouldn't be so simple to let's say to have a client that allows me to send an email to my group. Whereas something like getting /groups/{groupId} would probably be quite sufficient, another common use case. Finally, since some of this might seem useful for these basic elements, it might also be useful for XWiki classes in general to be able to expose a bit of RESTful api. So let's say I implemented a friends feature by linking user objects, I would certainly like to expose something like a GET on /users/{userId}/friends So I think one of the requirements in the design is to allow this type of behavior, maybe by linking a script to an object that describes the api and is attached to the XWiki class. More thoughts... -- Luis Arias +33 6 14 20 87 93 skype : kaaloo
Pascal Voitot wrote:
From my point of view, REST is an architecture model which doesn't fit for anything... Sometimes, you can't fulfill all its requirements and you have to accept some steps aside the theory...
Well, anything can be made RESTfull. Sometimes it requires critical changes in the developers' mindset, letting go old URLs and old ways of doing things. As an example, relational databases were considered absurd at first, the reviewers of the initial paper considered that it only fits a few data structures/types, and that traditional storage methods (structured plain text or binary files) are still the right solution. The same thing happens with REST. People don't know how to apply it, and blame the idea, not their habits. -- Sergiu Dumitriu http://purl.org/net/sergiu/
Pascal Voitot wrote:
Look at this article which shows an even worse example by SUN:) http://developers.sun.com/identity/reference/techart/id-svcs.html
To my mind: /authentication could be a resource /authentication/logout is not resource but an action...
Right.
so something like "GET /authorization?state=logout" might not be exactly RESTful but it is acceptable for my intellect ;)
A way to do authentication is the way Google does. You post your credentials to /authorization and you get as a response a token that you provide in subsequent request with an Authorization header. The POST operation could also generate a URI that you will DELETE in order to logout. Or you can also put a timeout on the token so you don't have to logout at all. The problem here is that, while this is perfectly RESTful, it's not very practical to do with a plain browser because, unless you do some javascript magic, you cannot add headers to a request just by typing something in the URL bar. A solution could be as other suggested to use the http://username:password@uri in order to leverage Basic auth, or as I proposed to expose a special uri that when requested challenges the browser to ask for an authentication. Subsequent requests will have the Authorization header set and, hence, login performed. -Fabio
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
+1 I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser. That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so.
On Mon, Dec 22, 2008 at 10:56 AM, Eduard Moraru <[email protected]>wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
+1
User as a resource seems quite logical... this is the same point of view as OpenID...
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
for security issues, passing the user/password for each request is really not very good... I really prefer the authentication token approach...
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so. _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Yes, but in both cases the security issue would be for someone to sniff the network. In this situation, both methods fail to provide security: HTTP Auth: - sniffer decodes username:password from the Base64 "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" header and can authenticate whenever he pleases. Token: - sniffer grabs the token and uses it himself to pose as the user. + user can call log out and the sniffer's access will be blocked out but the damage can already be done. - the sniffer can catch the initial log-in which sends the GET command with user name and password parameters which are in plain text. + If the authentication process involves more than one step (at least public/private keys or something stronger), the sniffer would not be able to find the user/pass and authenticate whenever he pleases. If we want good security, we need it done by an application on the client side. Another idea would be to use HTTP:// for anonymous access and HTTPS:// for authenticated access. Having HTTPS to secure the communication, the authentication approach could be a relatively simple one(please correct me), even token-based or basic auth. (seems curl handles HTTPS http://curl.netmirror.org/docs/manual.html) We should provide a standard way accessible both to a browser and a command-line tool like curl. WDYT? Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 10:56 AM, Eduard Moraru <[email protected]>wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
+1
User as a resource seems quite logical... this is the same point of view as OpenID...
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
for security issues, passing the user/password for each request is really not very good... I really prefer the authentication token approach...
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so. _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
On Mon, Dec 22, 2008 at 12:14 PM, Eduard Moraru <[email protected]>wrote:
Yes, but in both cases the security issue would be for someone to sniff the network. In this situation, both methods fail to provide security: HTTP Auth: - sniffer decodes username:password from the Base64 "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" header and can authenticate whenever he pleases. Token: - sniffer grabs the token and uses it himself to pose as the user. + user can call log out and the sniffer's access will be blocked out but the damage can already be done. - the sniffer can catch the initial log-in which sends the GET command with user name and password parameters which are in plain text. + If the authentication process involves more than one step (at least public/private keys or something stronger), the sniffer would not be able to find the user/pass and authenticate whenever he pleases.
For sure, but it enforces the hacker to be just a bit more clever... But you're right!!! Basic and Digest authentication is a bit light :) We should do as Amazon S3 and define our own Authentication digest called AWS ;););)
If we want good security, we need it done by an application on the client side.
Another idea would be to use HTTP:// for anonymous access and HTTPS:// for authenticated access. Having HTTPS to secure the communication, the authentication approach could be a relatively simple one(please correct me), even token-based or basic auth. (seems curl handles HTTPS http://curl.netmirror.org/docs/manual.html)
We should provide a standard way accessible both to a browser and a command-line tool like curl.
WDYT?
Don't know if this is really needed... Currently, without REST, XWiki doesn't use HTTPS and has the same authentication risk, am I right? But if we want a strong security layer, HTTPS could be a solution...
Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 10:56 AM, Eduard Moraru <[email protected] wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Thanks -Vincent
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
+1
User as a resource seems quite logical... this is the same point of view as OpenID...
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
for security issues, passing the user/password for each request is really not very good... I really prefer the authentication token approach...
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so. _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
_______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 12:14 PM, Eduard Moraru <[email protected]>wrote:
Yes, but in both cases the security issue would be for someone to sniff the network. In this situation, both methods fail to provide security: HTTP Auth: - sniffer decodes username:password from the Base64 "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" header and can authenticate whenever he pleases. Token: - sniffer grabs the token and uses it himself to pose as the user. + user can call log out and the sniffer's access will be blocked out but the damage can already be done. - the sniffer can catch the initial log-in which sends the GET command with user name and password parameters which are in plain text. + If the authentication process involves more than one step (at least public/private keys or something stronger), the sniffer would not be able to find the user/pass and authenticate whenever he pleases.
Any HTTP authentication method is either not generic enough, or not safe enough. The only solution is to use HTTPS. - Digest auth requires that we store passwords in plaintext - Basic auth and URL auth have no protection at all - Cookie auth requires that the user/pass are sent at least once to the server - Client side encryption requires the use of a graphical browser, and enabled javascript HTTPS is safe enough to make any of the above methods also safe.
For sure, but it enforces the hacker to be just a bit more clever... But you're right!!! Basic and Digest authentication is a bit light :) We should do as Amazon S3 and define our own Authentication digest called AWS ;););)
How do we make clients understand this? Javascript-powered browsers can emulate this authentication method, but what about lynx and wget?
If we want good security, we need it done by an application on the client side.
Another idea would be to use HTTP:// for anonymous access and HTTPS:// for authenticated access. Having HTTPS to secure the communication, the authentication approach could be a relatively simple one(please correct me), even token-based or basic auth. (seems curl handles HTTPS http://curl.netmirror.org/docs/manual.html)
We should provide a standard way accessible both to a browser and a command-line tool like curl.
WDYT?
+1 for Basic auth over HTTPS, or cookies over HTTPS. Basic auth should be used by non-interactive clients (command line tools), since in a browser it is hard to "logout". Cookies should be used for interactive tools, which can keep an internal state.
Don't know if this is really needed... Currently, without REST, XWiki doesn't use HTTPS and has the same authentication risk, am I right? But if we want a strong security layer, HTTPS could be a solution...
No web application has safe authentication without HTTPS.
Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 10:56 AM, Eduard Moraru <[email protected] wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
> Does this mean I cannot open my browser and call the REST URL without > specifying a user? > > > It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
+1
User as a resource seems quite logical... this is the same point of view as OpenID...
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
for security issues, passing the user/password for each request is really not very good... I really prefer the authentication token approach...
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so.
GET (or POST) /authToken?user=..&pass=.. -> sets a cookie (deleting all previous values set) DELETE /authToken -> deletes the cookie The semantics seem correct IMO. You GET a token, this has the most correct meaning. But since GET is defined as a simple resource retrieval, and here we do a lot of processing behind the scenes, a POST might be better suited (you send some parameters and expect a result from the server). DELETE also is meaningful. We don't delete a resource with the same value as a document or object. The difference is that this resource is not stored on the server, but on the client. However, it is used on the server, thus it is a correct computational resource that the server sees, and which it can also DELETE. Now, since DELETE is not easy to access from all clients, to delete a token without using a DELETE request, a client can simply POST or GET the authToken without specifying user/pass, or using empty values for them. By the mechanics of cookies, if the server sends an expired cookie (i.e. an invalid token, or an invalidating token), it will be deleted from the client. -- Sergiu Dumitriu http://purl.org/net/sergiu/
On Mon, Dec 22, 2008 at 2:50 PM, Sergiu Dumitriu <[email protected]> wrote:
Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 12:14 PM, Eduard Moraru <[email protected] wrote:
Yes, but in both cases the security issue would be for someone to sniff the network. In this situation, both methods fail to provide security: HTTP Auth: - sniffer decodes username:password from the Base64 "Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==" header and can authenticate whenever he pleases. Token: - sniffer grabs the token and uses it himself to pose as the user. + user can call log out and the sniffer's access will be blocked out but the damage can already be done. - the sniffer can catch the initial log-in which sends the GET command with user name and password parameters which are in plain text. + If the authentication process involves more than one step (at least public/private keys or something stronger), the sniffer would not be able to find the user/pass and authenticate whenever he pleases.
Any HTTP authentication method is either not generic enough, or not safe enough. The only solution is to use HTTPS. - Digest auth requires that we store passwords in plaintext - Basic auth and URL auth have no protection at all - Cookie auth requires that the user/pass are sent at least once to the server - Client side encryption requires the use of a graphical browser, and enabled javascript
HTTPS is safe enough to make any of the above methods also safe.
For sure, but it enforces the hacker to be just a bit more clever... But you're right!!! Basic and Digest authentication is a bit light :) We should do as Amazon S3 and define our own Authentication digest called AWS ;););)
How do we make clients understand this? Javascript-powered browsers can emulate this authentication method, but what about lynx and wget?
I was joking :) Basic auth will be good enough :)
If we want good security, we need it done by an application on the client side.
Another idea would be to use HTTP:// for anonymous access and HTTPS:// for authenticated access. Having HTTPS to secure the communication, the authentication approach could be a relatively simple one(please correct me), even token-based or basic auth. (seems curl handles HTTPS http://curl.netmirror.org/docs/manual.html)
We should provide a standard way accessible both to a browser and a command-line tool like curl.
WDYT?
+1 for Basic auth over HTTPS, or cookies over HTTPS. Basic auth should be used by non-interactive clients (command line tools), since in a browser it is hard to "logout". Cookies should be used for interactive tools, which can keep an internal state.
+1 for this...
Don't know if this is really needed... Currently, without REST, XWiki doesn't use HTTPS and has the same authentication risk, am I right? But if we want a strong security layer, HTTPS could be a solution...
No web application has safe authentication without HTTPS.
and even HTTPS can be attacked :)
Pascal Voitot wrote:
On Mon, Dec 22, 2008 at 10:56 AM, Eduard Moraru < [email protected] wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
> Vincent Massol wrote: > > > >> Does this mean I cannot open my browser and call the REST URL without >> specifying a user? >> >> >> > It should open up the authentication dialog where you type your > username > and password (or guest) the first time you request a resource. > > Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
+1
User as a resource seems quite logical... this is the same point of view as OpenID...
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
for security issues, passing the user/password for each request is really not very good... I really prefer the authentication token approach...
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so.
GET (or POST) /authToken?user=..&pass=.. -> sets a cookie (deleting all previous values set) DELETE /authToken -> deletes the cookie
The semantics seem correct IMO. You GET a token, this has the most correct meaning. But since GET is defined as a simple resource retrieval, and here we do a lot of processing behind the scenes, a POST might be better suited (you send some parameters and expect a result from the server).
DELETE also is meaningful. We don't delete a resource with the same value as a document or object. The difference is that this resource is not stored on the server, but on the client. However, it is used on the server, thus it is a correct computational resource that the server sees, and which it can also DELETE.
Now, since DELETE is not easy to access from all clients, to delete a token without using a DELETE request, a client can simply POST or GET the authToken without specifying user/pass, or using empty values for them. By the mechanics of cookies, if the server sends an expired cookie (i.e. an invalid token, or an invalidating token), it will be deleted from the client.
-- Sergiu Dumitriu http://purl.org/net/sergiu/ _______________________________________________ devs mailing list [email protected] http://lists.xwiki.org/mailman/listinfo/devs
Eduard Moraru wrote:
We should provide a standard way accessible both to a browser and a command-line tool like curl.
WDYT?
I agree. I have to catch up today's discussion but I think it's worth that I detail what I have implemented yesterday: --- With Firefox: * http://localhost:8080/xwiki/rest/spaces (gets all spaces as guest) * http://localhost:8080/xwiki/rest/browser_authentication (sends a challenge that makes the browser pop up the username password dialog) Type Admin, admin and from now on we are recognized as admin (Firefox starts to send Authorization headers in subsequent requests) * http://localhost:8080/xwiki/rest/spaces (gets all spaces as Admin) Logout by clearing your private data and authenticated session (or restarting Firefox) * http://localhost:8080/xwiki/rest/spaces (gets all spaces as guest) --- With curl: $ curl http://localhost:8080/xwiki/rest/spaces (gets all spaces as guest) $ curl -u Admin:amdin http://localhost:8080/xwiki/rest/spaces (gets all spaces as Admin) Isn't it an acceptable implementation (modulo security via HTTPS, etc.)? Logout is not really necessary. Each request bears the Authorization header if the user wants to be recognized (i.e., it like a login at each request, consistent with the REST stateless constraint) -Fabio
Eduard Moraru wrote:
Vincent Massol wrote:
On Dec 19, 2008, at 6:27 PM, Fabio Mancinelli wrote:
Vincent Massol wrote:
Does this mean I cannot open my browser and call the REST URL without specifying a user?
It should open up the authentication dialog where you type your username and password (or guest) the first time you request a resource.
Is that right? It sounds cumbersome and bad for easy automation when you want guest access.
Cannot we default to guest when no username/account is specified?
Thanks -Vincent
+1
I think it would be easier and more natural to have the default to guest or anonymous user. When an anonymous user tries to access restricted content -> 403 If he wants to log-in, he just does: http://user:[email protected]/space/X/page/Y
+1 for URL authentication. This is something needed (for command line clients that don't speak BASIC auth), although it is not safe at all. Still, it has the same safety level as BASIC auth, so it is no less safe than other authentication methods (given that by default our login sends plaintext values over HTTP).
We should mimic the basic auth and skip the pop`ul window that requires user/pass in the browser.
That is: Imply that the current user is exactly who he says he is and do not assume he could be a user with rights to a resource until he explicitly says so.
-1. Although URL authentication should not create any persistent authentication, we need something persistent (using cookies). -- Sergiu Dumitriu http://purl.org/net/sergiu/
Dear all, I had some feedback about the URI design on the REST-discuss mailing list. The guy who replied put his answer on this page with his comments: http://restpatterns.org/User:SteveB/Designing_URIs Very interesting. -Fabio P.S.: My original message is here: http://tech.groups.yahoo.com/group/rest-discuss/message/11860
participants (8)
-
Artem Melentyev -
Eduard Moraru -
Fabio Mancinelli -
Luis Arias -
Pascal Voitot -
Paul Libbrecht -
Sergiu Dumitriu -
Vincent Massol