James Watson
James Watson

Reputation: 464

Using URL Query Parameters on POST

My team needs to build an API for uploading documents e.g. PDFs. One of my goals is to make this as painless as possible for the callers. I believe a POST call with the binary content provided as a stream is the most straightforward. A team-member noted that there was a need to provide metadata along with this document. His assumption that this would require a multi-part-mime request. In my opinion, this adds a significant amount of complexity for the users of the service.

I suggested the idea setting the metadata in the 'query string' of the URL. This allows for the metadata and a simple stream solution for the document. We both are confident that this should work from a technical perspective, but he felt this was non-standard or potentially not RESTful.

It seems like a pretty straightforward solution to me but I indeed cannot find any clear answer on whether this is problematic. I found a few discussions that seem to be about this but the answers all seem to veer off into "mixing GET and POST" which I don't follow at all. Unless I'm missing something, this has nothing to do with GET, just POST and how the URL for that POST is structured. It seems like there's an idea that query parameters are only supported by GET but I don't believe that's the case.

Can anyone provide an authoritative reference on this?

Upvotes: 0

Views: 407

Answers (1)

Pedro Werneck
Pedro Werneck

Reputation: 41938

It depends on what you mean by "problematic". There's probably nothing wrong with it from an usability perspective. Remember, REST is an architectural style, and authoritative references on styles can be as subjective as the styles themselves. You can find an authoritative reference on the transport protocol you are using, HTTP, but when is a deviation from the protocol problematic, and when it's merely against purism? Read the RFCs 7230 and 7231 and try to figure it out.

In other words, I'm saying that if you're after an authoritative source to settle an argument with your colleagues, I don't think you're going to find it.

If you just want to clarify it, from the REST perspective, URIs are atomic identifiers of resources. Query parameters are part of the identifier, but since they are atomic, their semantics is irrelevant. This means that any discussion about whether an URI is RESTful or not is pointless. As long as an URI points to one and only one resource and it's not obtained from out-of-band information, it's RESTful, regardless of its contents. Sure, you should try to have meaningful and simple URIs, that are easy to understand, but this is a general best-pratice on HTTP, not a REST constraint.

The real problem in your case is that the semantics of the POST method is to submit the payload to be processed by the resource identified by the URI, under predefined rules. The URI you are using in the POST does not identify the file you are uploading, but the resource responsible for the uploading. If you are including metadata for processing in the URI, you are effectively saying that every PDF file is uploaded with a different uploader resource. There's nothing inherently wrong with that from a REST perspective, but it's strange from an HTTP and usability perspective. I'd expect the same resource to be used for everyone, and additional data to be present in the payload. In this point I think your colleague is correct, that you should use a multi-part-mime request, or a media-type format that allows you to pack the pdf file and the metadata together in the payload.

However, if your metadata doesn't change after the PDF file is uploaded -- or in other words, if your URI doesn't change -- it's perfectly fine to do that with a PUT method. Differently from the POST method, PUT does not submit the payload to be processed by the resource identified by the URI, but asks the server to replace the resource at the URI with the one enclosed in the payload. In this case the URI really identifies the PDF file, so it's ok, as long as that's not going to change.

Upvotes: 2

Related Questions