3

I'm writing an HTTP API to a publishing server, and I want resources with representations in multiple languages. A user whose client GETs a resource which has Korean, Japanese and Trad. Chinese representations, and sends Accept-Language: en, ja;q=0.7 should get the Japanese.

One resource, identified by one URI, will therefore have a number of different language representations. This seems to me like a totally orthodox use of content negotiation and multiple resource representations.

But when each translator comes to provide these alternate language representations to the server, what's the correct way to instruct the server which language to store the representation under? I'm having the translators PUT the representation in its entirety to the same URI, but I can't find out how to do this elegantly. Content-Language is a response header, and none of the request headers seem to fit the bill.

It seems my options are

  1. Invent a new request header
  2. Supply additional metadata in a multipart/related document
  3. Provide language as a parameter to the Content-Type of the request, like Content-Type: text/html;language=en

I don't want to get into the business of extending HTTP, and I don't feel great about bundling extra metadata into the representation. Neither approach seems friendly to HTTP caches either. So option 3 seems like the best way that I can think of, but even then it's decidedly non-standard to put my own specific parameters on a very well established content type.

Is there any by-the-book way of achieving this?

  • 4
    Some websites segregate the content by language. Each language gets it's own folder structure. These websites have URLs like example.com/fr/index and example.com/en/index – Gilbert Le Blanc Mar 16 '14 at 23:28
  • 1
    Give your users control that let's them tell you what language they are using. – Adam Zuckerman Mar 17 '14 at 0:54
  • @AdamZuckerman sure, but how do we let API clients indicate the language of a resource they're putting to a URI? – Nik M Mar 17 '14 at 15:47
  • @GilbertLeBlanc I suppose we could do that for PUT, and then provide content negotiation on GET. This way, a translator could GET a document in whatever language was negotiated from example.com/somedoc, translate it into Chinese and then PUT it to example.com/zh/somedoc, and have the application make it available from example.com/somedoc using content negotiation. It doesn't feel great to be using a URI construct to pass metadata this way, and it's not cache friendly. – Nik M Mar 17 '14 at 15:50
  • Gilbert is on the right track. Give the client a URL like: /API/ language /add. You can also do the same thing on GETs: /API/ language / id – Adam Zuckerman Mar 17 '14 at 15:51
1

First of all, let's give your resource a name: let's call it a publication. This is to disambiguate it from another kind of resource your design is implying: the translation.

Second, let's agree to the fact that a collection of resources is also a resource itself. Having said that, a publication looks to me more like a collection of translations.

Third, using PUT to create a translation seems inappropriate to me, because PUT is used to replace a resource with another one. It would make sense if a translation to a specific language was already there, and the translator was updating it. But to create a new one, I think POST suits best.

EDIT: I'm having second thoughts on the above. It appears that, since the id of the new resource is decided by the client, a PUT would actually be appropriate after all. Maybe someone else could provide a more concrete opinion on the matter.

Now, considering the above, a uri structure like /publication/XYZ/en would certainly make sense, because it would refer to the English translation of the publication with id XYZ. This resolves the creating/updating/deleting of translations (using POST/PUT/DELETE resp.), while during a GET request of /publication/XYZ you could examine the Accept-Language header and make the client redirect accordingly.

OTOH, your question clearly states that you want to treat the publication as a single resource. In that case, I guess you must treat translations as separate attributes (i.e. fields) of the same resource. Just as a person resource would have a first name, a last name and an e-mail, a publication could have a publication date, an English translation and a Japanese one.

But then you would have to find a way to partially update the publication when a translation would need to be created/edited. I guess a PATCH request would be appropriate for this scenario.

1

You can find some guidance on designing URIs to support multilingual resources here:

Also, here's how Google's Maps API let's consumers specify a language:

<script src="http://maps.google.com/maps/api/js?sensor=false&amp;language=ru-RU"      
        type="text/javascript"></script> 

Notice the URL parameter at the end: language=ru-RU

Google Maps in Russian

Note: this is referenced from this StackOverflow question:

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.