POST(a) and POST(p)

It's great to see others like Vish continuing to write about REST in geospatial (I continue to stalk the term). With a couple exceptions, he's right on. The principles of REST to which he refers are:

  • Give every “thing” an ID
  • Link things together
  • Use standard methods
  • Resources with multiple representations
  • Communicate statelessly

Do read and recommend Stefan Tilkov's Brief Introduction to REST, from which the tenets above are taken. It's excellent. Vish focuses on the third of these -- standard methods and their use -- and highlights the risks of unsafe GET. Unfortunately he's crossed up the methods a bit. The actual uses of the different standard methods are:

  • DELETE: delete a resource
  • GET: get a representation of a resource
  • POST: submit data to a resource
  • PUT: update the state of a resource

There is little lost by thinking of DELETE, GET, and PUT in CRUD terms. One well known use of POST is in resource factories, creating new placemarks or features in a collection, for example:

# Request
POST /features/new HTTP/1.1
Host: gis.example.com
...

[New entity]

# Response
HTTP/1.1 201 Created
Location: http://gis.example.com/features/1
...

Sometimes people refer to this as POST(a) (as in "append"), but POST is more than CRUD's "Create". It can also be used to process data and return it without necessarily creating any new server-side resources. Call this POST(p) (for "process"). Vish is considering POST(p) as a larger volume GET, but that's not quite right because GET requests should be safe and POST requests should be treated as unsafe. Rather than try to switch between GET and POST requests to a single resource (like /features in the example above) depending on the size of the request data, I'd add a new resource to handle POST(p) requests and make it distinct from the ones that are taking POST(a) and GET requests.

Call it a pet peeve, but it's "resource", not "REST endpoint". It's pretty hard to fully grok REST while clutching to the web services endpoint concept.

Update (2008-09-08): I knew Vish had simply transposed entries in his list, and he's fixed up the methods.

Comments

Re: POST(a) and POST(p)

Author: Keyur

Good discussion. ~ Rather than try to switch between GET and POST requests to a single resource depending on the size of the request data, I'd add a new resource to handle POST(p) requests and make it distinct from the ones that are taking POST(a) and GET requests. I don't see the benefit of one against the other. Allowing GET as well as POST to a /query resource v. using /query only for GET and /query/post (?) for POST is probably a subjective call. In both cases you are bending the REST principle of POST-only-unsafe-requests to work around a real world limitation (number of GET characters).

Re: POST(a) and POST(p)

Author: Brian Hamlin

sounds good.. however I have to say that I have just built a RESTful server based on a FeatureServer model, but found that the way Python's CGI handled DELETE prevented me from actually using it.. I ended up using a GET with a do_delete param in it.. so much for the perfect world...

Re: POST(a) and POST(p)

Author: Sean

Python web frameworks generally have incomplete or even poor support for REST. The cgi module is probably the worst of all. Grok's is okay, but makes nice clean URLs too hard. Selector is a neat URL dispatcher for RESTful apps.

Re: POST(a) and POST(p)

Author: Sean

I agree about the subjectivity, Keyur. I've blogged a number of times about query resources as a way to design around the query string limit -- created via a factory (POST(a)) and then accessed safely via GET, but the idea remains unpopular.