grouper-dev - Re: [grouper-dev] real rest web services
Subject: Grouper Developers Forum
List archive
- From: Scotty Logan <>
- To: Grouper Dev <>
- Subject: Re: [grouper-dev] real rest web services
- Date: Fri, 15 Feb 2008 12:41:46 -0800
On Feb 15, 2008, at 10:42 AM, Chris Hyzer wrote:
Tom and I discussed real rest web services, and have a design doc which would be a layer on top of the SOAP / xml -HTTP -rpc web services.
If this is still using Axis' "RESTful" interface, then it's not going to be RESTful by any widely accepted definition.
From http://ws.apache.org/axis2/0_94/rest-ws.html:
The REST default HTTP interface is POST.BZZZT.. The REST default HTTP interface is... HTTP. All of it.
It however acts as both a REST endpoint and SOAP endpoint. When a Message is received, if the content type is text/xml and if the SOAP Action Headers are missing, then the Message is treated as a RESTful Message. Else it is treated as a usual SOAP Message.Right, because REST is always text/xml, because XML is the only way to represent an object.
To borrow from Henry Spencer's "10 Commandments for C Programmers" (http://www.lysator.liu.se/c/ten-commandments.html )
"Thou shalt foreswear, renounce, and abjure the vile heresy which claimeth that "All the world's [in XML]", and have no commerce with the benighted heathens who cling to this barbarous belief, that the days of thy [service] may be long even though the days of thy current [representation] be short."
For groups, as with almost any other data type, there are many others:
Content-type: text/ldif
dn: cn=foo:group,ou=Groups,dc=comanage-dev,dc=stanford,dc=edu
objectClass: groupOfNames
objectClass: eduMember
cn: foo:group
hasMember:
hasMember:
member:
,ou=People,dc=comanage-dev,dc=stanford,dc=edu
member:
,ou=People,dc=comanage-dev,dc=stanford,dc=edu
Content-type: text/lispish
("foo:group"
(""
""))
Content-type: text/ini
[Name]
foo:group
[Members]
Take a look at this outline, and let us know your thoughts, and maybe we can discuss on Wednesday.
https://wiki.internet2.edu/confluence/display/GrouperWG/Grouper+Rest+Web+Services
I don't see any real rest services in that doc.
I do see a description of a real REST interface for groups at https://wiki.cac.washington.edu/x/TpNh which was sent to this list by Bob back in early January.
Also, take a look at Paul Prescod's REST mistakes:
http://www.prescod.net/rest/mistakes/
From the wiki page:
1. URLs are resource based and not RPC based
no they're not.. you have
http://localhost:8091/grouper-ws/servicesRest/subject/12341234/getGroups
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/hasMember/12341234
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/addMember/12341234
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/deleteMember/12341234
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/deleteGroup
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/saveGroup
Those are function calls, not resource names. Resource based URLs would be
GET
http://localhost:8091/grouper-ws/servicesRest/subject/12341234/groups
GET
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/members/12341234
PUT
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/members/12341234 DELETE
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup/members/12341234
DELETE
http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup
PUT http://localhost:8091/grouper-ws/servicesRest/group/aStem:aGroup
4. Payload for the services are generally in params (similar to a form submits), which for GETs can be in the URL, and POSTs in the body of the HTTP request
Payload should be in the body, with a sensible MIME type such as application/xhtml+xml or text/ldif. Query strings for GET (and possibly DELETE, although that's potentially dangerous) should be appended to the request URI.
5. GETs and POSTs are supported only, and are interchangeable
It's hard to be RESTful when you're missing half the vocabulary. GET and POST are not interchangeable. Use GET to retrieve a representation of a resource, DELETE to remove one, PUT to create one when the client picks the name and POST when the name is determined by the server.
9. HTTP response code between 200-299 (inclusive) are a success, 400-499 (inclusive) are a problem with the request, 500-599 (inclusive) are a failure on the server. Each web service response code (e.g. IS_MEMBER) maps to a unique HTTP response code, e.g.
While you can add additional HTTP response codes, I really don't think it's a good idea. Please use existing status codes, defined in RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html. If you need to include extra information, put it in the body, or put an X- Grouper-Error: header in the response
200: SUCCESS
200 OK - for GETs and DELETEs, for PUTs or POSTs it should be 201 CREATED
220: IS_MEMBER
If this is supposed to be a response for a membership query, it's either 200 OK (the subject is a member) or 404 NOT FOUND (subject is not a member).
221: IS_NOT_MEMBER
404 NOT FOUND
222: ALREADY_MEMBER
Is this an error? If I PUT /groups/stem:name/members/newmember and they're already a member, isn't that still the desired result?
If it is an error, that's a 409 CONFLICT with a message in the body, if it's not it's a 201 CREATED.
223: WASNT_MEMBER
404 NOT FOUND, assuming it's removing a member with a DELETE
224: PARTIAL_SUCCESS_INDIRECT_MEMBER_CANT_DELETE
403 FORBIDDEN, plus some message in the reponse
420: INVALID_QUERY
400 BAD REQUEST
421: INSUFFICIENT_PRIVILEGES
403 FORBIDDEN or 405 METHOD NOT ALLOWED
422: SUBJECT_DUPLICATE
409 CONFLICT
423: SUBJECT_NOT_FOUND
424: STEM_NOT_FOUND
425: MEMBER_NOT_FOUND
426: GROUP_NOT_FOUND
404 NOT FOUND
427: GROUP_NOT_UNIQUE
409 CONFLICT
428: INDIRECT_MEMBER_CANT_DELETE
403 FORBIDDEN
520: EXCEPTION
521: PROBLEM_DELETING_MEMBERS
522: PROBLEM_WITH_ASSIGNMENT
523: PROBLEM_DELETING_GROUPS
524: SOURCE_UNAVAILABLE
525: PROBLEM_WITH_QUERY
500 INTERNAL SERVER ERROR, with a message
Also missing from the document is any mention of how to discover the groups. In a RESTful world you're not supposed to just make up the URLs on the client; there's a starting point that links to resources. E.g. something like this:
Request:
GET / HTTP/1.0
Host: group-server
Response:
200 OK
Content-type: application/xhtml+xml
Content-length: nnn
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Stems</title></head>
<body>
<ul class='stemlist'>
<li><a href='/groups/foo'>Foo</a></li>
<li><a href='/groups/bar'>Bar</a></li>
<li><a href='/groups/baz'>Baz</a></li>
<li><a href='/groups/boz'>Boz</a></li>
</ul>
</body>
</html>
So now you can take one of those links to get more information about a stem:
Request:
GET /groups/foo HTTP/1.0
Host: group-server
Reponse:
200 OK
Content-type: application/xhtml+xml
Content-length: nnn
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Foo Groups</title></head>
<body>
<ul class='grouplist'>
<li><a href='/groups/foo/BigGroup'>Big
Group</a></li>
<li><a href='/groups/bar/LittleGroup'>Little
Group</a></li>
</ul>
</body>
</html>
Then pick a group to work with:
Request:
GET /groups/foo/LittleGroup HTTP/1.0
Host: group-server
Response:
200 OK
Content-type: application/xhtml+xml
Content-length: nnn
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Foo:Little Group</title></head>
<body>
<h2><a rel='owners' href='/groups/foo/BigGroup/owners'>Owners</a></ h2>
<ul class='ownerlist'>
<li><a
'>Professor
X</a></li>
<li><a
'>Hoopy
Frood</a></li>
</ul>
<h2><a rel='members' href='/groups/foo/BigGroup/members'>Owners</ a></h2>
<ul class='memberlist'>
<li><a
'>Slartibartfast</a></li>
<li><a
'>Hoopy
Frood</a></li>
<li><a
'>Ford
Prefect</a></li>
...
</ul>
</body>
</html>
(The ownerlist and memberlist sections aren't really necessary).
Now you can add a new owner:
Request:
PUT
/
HTTP/1.0
Host: group-server
Response:
201 Created
Location:
http://group-server/groups/foo/BigGroup/owners/
Content-Type: text/plain
Content-Length: nnn
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd ">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head><title>Added Owner</title></head>
<body>
<h2>Success</h2>
<p>
Added <a rel='subject' href='/subjects/ '>Slartibartfast</a> as
an owner of <a rel='group' href='/groups/foo/ BigGroup'>foo:BigGroup</a>.
<p>
<p>
More information on group owner <a rel='owner' '>Slartibartfast</a>.
</p>
</body>
</html>
What's with the obsession with using a tool (Axis2, hammer) that is so obviously ill-suited for the task at hand (RESTful services, driving screws).
Scotty
--
Scotty Logan, IT Architect, Stanford University IT Services
http://its.stanford.edu/ http://itarch.stanford.edu/
- real rest web services, Chris Hyzer, 02/15/2008
- Re: [grouper-dev] real rest web services, Scotty Logan, 02/15/2008
- RE: [grouper-dev] real rest web services, Chris Hyzer, 02/15/2008
- Re: [grouper-dev] real rest web services, Scotty Logan, 02/15/2008
Archive powered by MHonArc 2.6.16.