1

I am writing (or trying to write) a RESTful webservice. One of it's primary functions is to allow clients to search for files from our server. This seems like a textbook GET scenario, but the searches are too complex/flexible to be entered in the URL.

Rather, I am accepting search parameters via an XML object. The obvious problem there is GETs aren't supposed to have request bodies. In fact, the webserver I'm using simply ignores them, so I couldn't ignore this practice if I wanted to.

It seems then that POST is the next option, but this is clearly not really what I'm after. It will get the job done (it's actually what I'm using right now), but it's very obviously not the correct request method for the job. In no way am I creating a new resource; I am literally copying the bytes from an existing file and feeding that back to the client. It doesn't get more GET than that.

The problem I'm facing is that a request for a file simply has too many fields to be feasibly put into a URL (some optional, some mandatory, some conditionally mandatory based on other fields, and so on...), but the only other option I have is to deliberately abuse one of REST's 4 keywords. Neither of these are very RESTful.

Is there a point where requests can simply become too complicated to maintain a pure REST approach, or am I not approaching this correctly? Have I just completely missed the mark and am actually using RPC instead of REST?

NOTE: I know that there are a few similar questions on this topic, but none of them seem to have an official consensus (mainly answers like "I'm using POST, but it's pretty hacky"), and many are from several years ago. I'm hoping the REST community has since come to a larger agreement on how to handle these, or at least agreed this isn't a RESTful thing to do.

Lord Farquaad
  • 662
  • 1
  • 11
  • 29

1 Answers1

1

Are complex searches inherently not RESTful?

No.

Traditionally, the protocol for a complex search uses a form to gather the configurable tokens for the search. The processing rules for the media type tell the client how to combine the tokens into a new identifier that can be used to obtain the result.

This seems like a textbook GET scenario, but the searches are too complex/flexible to be entered in the URL.

So if you have something too complex to represent as an identifier, then form processing isn't going to solve the issue for you either.

In HTTP, the appropriate choice is to use POST.

it's very obviously not the correct request method for the job. In no way am I creating a new resource

It's very clearly the correct choice for the job, because the semantics of POST are to

process the representation enclosed in the request according to the resource's own specific semantics.

Creating a subordinate resource is one use for POST, but it's not that restrictive. In other words, using POST isn't an abuse, because your use of POST conforms to HTTP's uniform interface.

It's lacking in some ways - queries are generally both safe and idempotent, and POST doesn't advertise either of those constraints, which means that generic clients can't take advantage of them. If you had access to something better, you would use it....

The method you are looking for is SEARCH; which would probably be perfect except for not having been accepted as a standard.

Assuming your routing framework has the flexibility, you could expose both POST and SEARCH as options, which would allow clients that know about SEARCH to use that method when available.

The problem I'm facing is that a request for a file simply has too many fields to be feasibly put into a URL (some optional, some mandatory, some conditionally mandatory based on other fields, and so on...)

You know, none of that sounds particularly difficult to handle with a sequence of forms, so you might want to reconsider whether encoding that information into the URI is too complex.

Which is to say, a common starting point for developing a REST api is to start from the question "how would I do this with web pages", and then from there to see if you can make the web pages machine readable.

VoiceOfUnreason
  • 40,245
  • 4
  • 34
  • 73