Specifying locale for http request/response - rest

I have a ReSTful web service which needs to parse locale-sensitive data from the request. This data could either be in an XML body or part of the query string. Is there any acepted way of determining which locale the data is being sent in (and by extension the locale in which the response should be sent)?
One option is simply to specify to the clients the locale in which all requests should be sent. A friendlier option seems to be to allow the client to specify the locale.
I've considered:
a) using the accept-language http header to encode this information.
b) using the xml:lang attribute for XML POSTs, and an extra field for query strings (e.g. ...&locale=en-GB)
http://www.w3.org/International/questions/qa-accept-lang-locales warns of limitations in using the accept-language header, but most of the warnings seem to center around requests originating from browsers. In my case the requests will come from other applications.
All advice greatly appreciated!

Your immediate choice is Accept-Language and probably Accept-Charset. A further option is to used a database that maps the client IP to a geographic location (as far as possible). These databases have become quite good. I think, but they usually are not free (you need to pay).

There's a precise and thorough discussion on this topic on w3.org. Quick summary: You can use the language as a first guess, but make sure your client can correct the locale settings you derive from that, as it can be wrong.

Related

RESTful API - how to include id/token/... in each request?

I developed a mobile app that needs to access and update data on a server. I'd like to include e.g. the device ID and some token in each request.
I am including these in the body at the moment, so I have only POST requests, even when asking to read data from the server. However, a request to read data should be GET, but how do I include these pieces of information? Should I just add a body to a GET request? Should I rather add some headers? If so, can I just create any custom headers with any name? Thank you for your guidance.
Your FCM token and device id are really authentication credentials for the request. In HTTP, you typically use the Authorization header with a scheme to indicate to the service
In your case, you could use bearer tokens in the HTTP Authorization header.
While bearer tokens are often used with JWT token, they are not required to be that specific format.
You could just concatenate the FCM token and the device id like the basic authentication scheme does.
BTW, it's not recommended to use a body on a GET request since some proxies may not retain that.
Well, REST is basically just a generalization of the concepts used already for years in the browser-based web. On applying these concepts consistently in your applications you'll gain freedom to evolve the server side while gaining robustness to changes on the clientside. However, in order to benefit from such strong properties a certain number of constraints need to be followed consequently like adhering to the rules of the underlying transport protocol or relying on HATEOAS to drive application state further. Any out-of-band information needed to interact with the service will lead to a coupling and therefore has the potential to either break clients or prevent servers from changing in future.
A common misconception in REST achitecture design is that URIs should be meaningful and express semantics to the client. However, in a REST architecture the URI is just a pointer to a resource which a client should never parse. The decision whether to invoke the URI should soly be based on the accompanying link relation name which may further be described in either the media-type or common standards. I.e. on a pageable collection link relation like prev, next, first or last may give a client the option to page through the collection. The actual structure of the URI is therefore not important to REST at all. Over-engineered URIs might further lead to typed resources. Therefore I don't like the term restful-url actually. How do non-restful-urls look like then?
While sending everything via POST requests is technically a valid option, it also has some drawbacks to consider though. IANA maintains a list of available HTTP methods you might use. Each method conveys different promisses and semantics. I.e. a client invoking a GET operation on a server should be safe to assume that invoking the resource does not cause any state changes (safe) and in case of network issues the request can be reissued again without any further considerations (idempotent). These are very important benefits to i.e. Web crawlers. Besides that intermediary nodes can determine based on the request method and the resulting response if the response can be cached or not. While this is not necessarily an issue in terms of decoupling clients from servers, it helps to take away unnecessary workload from the server itself, especially when resource state is rarly changing, improving the scalability of the whole system.
POST on the otherhand does not convey such properties. On sending a POST request for retrieving data the client can't be sure if the request actually lead to changes on the resources state or not. On a network issue the request might have reached the server and may have created a new resource though the response just got lost mid way which might keep the client in a state of uncertainty whether it simply can resend the request or not. Also, responses for POST operations are not cacheable by default, only after explicitely adding frehness information to it. A POST method invocation requests the target resource to process the provided representation accoding to the resources own semantics. As literally anything can be sent to the server it is of importance that the server teaches the client on how a request should look like. In HTML i.e. this is done via Web forms where a user can fill in data into certain input fields and then send the data to the server on clicking a submit button. The same concept could be applied for mobile or REST applications as well. Either reusing HTML forms or defining an own application/vnd.company-x.forms+json where the description of that media type is made public (or registered with IANA) can help you on this.
The actual question on where to include certain data is, unfortunately, to generic to give a short answer. It further depends whether data should be shareable or has some security related concerns. While parameters might be passed to the server via URL parameters (query, matrix, path) to a certain extent, it is probably not the best option in general eventhough query parameters are encrypted in SSL interactions. This option, though, is convenient if the URI should be pastable without losing information. This of course then shouldn't contain security related data then. Security related information should almost always be passed in HTTP headers or at least the actual payload itself.
Usually you shoud distinguish between content and meta-data describing the content. While the content should be the actual payload of the request/response, any meta-data describing the content should go inside the headers. Think of an image you want to transfer. As you don't want to mess with the bytes of the image you simply append the image name, the compression format and further properties describing how to convert the bytes back to an image representation within the headers. This discrimination works probably best for standardized representation formats as you need to be within the capabilities of the spec to guarantee interoperability. Though, even there things may start to get fuzzy. I.e in the area of EDI there exist a couple of well-defined standards like Edifact, Tradacoms, and so forth which can be used to exchange different message formats like invoices, orders, order responses, ... though different ERP systems speak different slangs and this is where things start to get complicated and messy.
If you are in control of your representation format as you probably did not standardize it or defined it only vaguely yet things might even be harder to determine whether to put it insight your document or append it via headers. Here it solely depends on your design. I have also seen representations that defined own header sections within the payload and therefore recreated a SOAP like envelop-header-body structure.
About your question if you can create custom header for your requirement. My answer is YES.
As above was mentioned, you can use the standard Authorization header to send the token in each request . Other alternative is defining a custom header. However you will have to implement by server side a logic to support that custom header .
You can read more about it here

Is it a good idea to use a URL as an iCalendar UID?

iCalendar has a UID field which is a universal identifier. It's intended to be unique value so the same event can be recognized when syncing or trying to add the same event twice. They're usually randomly generated, eg. a37c3632-3c26-4543-b91d-355a1b668a3a.
I'm tempted to use a URL describing the event as my UID. Is there any reason this isn't a good idea?
While strictly speaking this may not be forbidden, if you do care about interoperability, you are always taking a risk by not following common practices. There will be some client or server out there which will choke on your events. For example, some CalDAV servers tend to use the UID value as the last segment in CalDAV resource URLs. With your type of UID, they will need to URI encode that last segment, which some of them may fail to do.
Of course you can always put the blame on those bad implementations but, at the end of the day, it will be your users who will be unable to see your events.
There are new recommendations for the UID property which were published as part of RFC 7986 (see https://www.rfc-editor.org/rfc/rfc7986#section-5.3 ). Although the main purpose of this section is to allow use of UID in VCALENDAR, the recommended format make sense in all cases.
I would use a URL or X- property to convey your URL if you do care about it.

encoding mobile-device versioning for REST Api server

We have restful api over HTTP. Amongst other clients we have also mobile-device clients (e.g. iphone). The issue is that there are several iphone apps in different versions out there (1.0, 2.0). Because they are distributed we don't have control which app-version is calling us.
To identify the app-version on server-side I see following options:
device must append URL parameter (e.g. /foo?iphone-app-version=1.0) : A bit yucky, but good thing is that I can see it always on server-logs (URL is always logged)
we authenticate api-clients with HTTP digest. We could encode the app-version inside the username (e.g. iphone_1_0): Good thing it is logged in server logs, but only works for resources which are exposed as HTTP digest.
device must use custom HTTP-header, e.g. X-IPHONE-APP-VERSION: In my view the cleanest approach, but we don't log HTTP headers in server logs (for log-noise it is switched off). So later analyzation is not possible.
Do you have a preferred approach or any other alternatives?
EDIT: With above versioning I don't mean api-versioning/content-negotiation. It is the version of the mobile-device.
You can use the Accept-Header to allow a client to declare what capabilities it has by identifying what versions of media types it supports. e.g.
mobile app does:
GET /server/foo
Accept: application/vnd.acme.fooappV1+xml
When you introduce new features that are not backward compatible you can tell the new updated clients to send,
GET /server/foo
Accept: application/vnd.acme.fooappV2+xml
Then your server knows the capabilities of the client it is talking to.
You could also get the new clients to do this:
GET /server/foo
Accept: application/vnd.acme.fooappV1+xml, application/vnd.acme.fooappV2+xml
That way you can migrate your server resources over to the new format slowly. If the endpoints deliver application/vnd.acme.fooappV1+xml then the client will revert back to the old way. If the endpoints return application/vnd.acme.fooappV2+xml then the new code can take over.
Using this approach, no URIs need to be changed, so bookmarks and statistics remain valid. Migration to a new format can be done incrementally over time and support for old clients can be gradually phased out.
I decided for custom X-xxx-USER-AGENT one. Main reason to decide against more standard "User-Agent" is that is already "polluted" with http-client library or mobile-device information. A custom X-xxx-USER-AGENT is easier to parse for server and does not intervent http-library which often sets it and could override a custom entry.

RESTful Web Services: method names, input parameters, and return values?

I'm trying to develop a simple REST API. I'm still trying to understand the basic architectural paradigms for it. I need some help with the following:
"Resources" should be nouns, right? So, I should have "user", not "getUser", right?
I've seen this approach in some APIs: www.domain.com/users/ (returns list), www.domain.com/users/user (do something specific to a user). Is this approach good?
In most examples I've seen, the input and output values are usually just name/value pairs (e.g. color='red'). What if I wanted to send or return something more complex than that? Am I forced to deal with XML only?
Assume a PUT to /user/ method to add a new user to the system. What would be a good format for input parameter (assume the only fields needed are 'username' and 'password')? What would be a good response if the user is successful? What if the user has failed (and I want to return a descriptive error message)?
What is a good & simple approach to authentication & authorization? I'd like to restrict most of the methods to users who have "logged in" successfully. Is passing username/password at each call OK? Is passing a token considered more secured (if so, how should this be implemented in terms of expiration, etc.)?
For point 1, yes. Nouns are expected.
For point 2, I'd expect /users to give me a list of users. I'd expect /users/123 to give me a particular user.
For point 3, you can return anything. Your client can specify what it wants. e.g. text/xml, application/json etc. by using an HTTP request header, and you should comply as much as you can with that request (although you may only handle, say, text/xml - that would be reasonable in a lot of situations).
For point 4, I'd expect POST to create a new user. PUT would update an existing object. For reporting success or errors, you should be using the existing HTTP success/error codes. e.g. 200 OK. See this SO answer for more info.
the most important constraint of REST is the hypermedia constraint ("hypertext as the engine of application state"). Think of your Web application as a state machine where each state can be requested by the client (e.g. GET /user/1).Once the client has one such state (think: a user looking at a Web page) it sees a bunch of links that it can follow to go to a next state in the application. For example, there might be a link from the 'user state' that the client can follow to go to the details state.
This way, the server presents the client the application's state machine one state at a time at runtime. The clever thing: since the state machine is discovered at runtime on state at a time, the server can dynamically change the state machine at runtime.
Having said that...
on 1. the resources essentially represent the application states you want to present to the client. The will often closely match domain objects (e.g. user) but make sure you understand that the representations you provide for them are not simply serialized domain objects but states of your Web application.
Thinking in terms of GET /users/123 is fine. Do NOT place any action inside a URI. Although not harmful (it is just an opaque string) it is confusing to say the least.
on 2. As Brian said. You might want to take a look at the Atom Publishing Protocol RFC (5023) because it explains create/read/update cycles pretty well.
on 3. Focus on document oriented messages. Media types are an essential part of REST because they provide the application semantics (completely). Do not use generic types such as application/xml or application/json as you'll couple your clients and servers around the often implicit schema. If nothing fits your needs, just make up your own type.
Maybe you are interested in an example I am hacking together using UBL: http://www.nordsc.com/blog/?cat=13
on 4. Normally, use POST /users/ for creation. Have a look at RFC 5023 - this will clarify that. It is an easy to understand spec.
on 5. Since you cannot use sessions (stateful server) and be RESTful you have to send credentials in every request. Various HTTP auth schemes handle that already. It is also important with regard to caching because the HTTP Authorization header has special specified semantics to caches (no public caching). If you stuff your credentials into a cookie, you loose that important piece.
All HTTP status codes have a certain application semantic. Use them, do not tunnel your own error semantics through HTTP.
You can come visit #rest IRC or join rest-discuss on Yahoo for detailed discussions.
Jan

REST and localized resources

I'd like to have my resources localized to several languages.
How multiple languages should be posted to resource using REST architecture?
resource: /chapters, /chapters/:id
When POST is issued to chapters, client send data structure:
{localizations: { en: {title: 'New chapter' },sk: {title: 'Nova kapitola'} }}
and new chapter with localizations en and sk is created.
When client wants to access this chapter at URL /chapter/1, only one language mutation should be returned in representation. How should I implement locale scoping?
I can use Accept-Language HTTP header with desired locale, Accept-Language: sk, or i can include locale into URL like /chapters/1/en.
Also, how PUT request should be handled? For most of the time only one language mutation would be updated, but occasionally 2 or more of them would be updated.
For updating the data, the language should be provided in the payload of data, just as you've described. That works great.
For fetching, it depends on if you want to allow 1) linkability, and 2) clients to change their selected language. I'd argue you want both - its much easier and preferable to change the URL or toggle the language within your app then futz around in the browser and change the browser-wide locale settings.
So, check your url, application cookies, or application user data for the language, and use the Accept-Language headers as a fallback.
I don't understand your PUT request question. The data structure you describe would handle multiple language updates just fine, no? You can treat PUTs pretty much however you want, so long as the URL that is PUT to remains an addressable resource.