JSON/HTTP is a really good decoupling mechanism, and I'll throw out a couple of suggestions that will make it even more loosely coupled.
The rapid industry adoption of JSON/HTTP interfaces really speaks well about how people view the usefulness of that model.
- Enforce a MUST IGNORE rule.
That is, when parsing the JSON (client or server), the app MUST IGNORE any fields it don't recognize.
XML went in the with idea that the app MUST UNDERSTAND each field or else the document was invalid. But that created problems with versioning, because with almost any change, clients needed to upgrade every time the server did. Even adding an informational field broke the spec. With MUST IGNORE, the server can add new fields any time, and as long as it doesn't remove or change the meaning of other fields (see below). Existing clients can just ignore the new fields. Rather, they MUST IGNORE the new fields.
A search on MUST IGNORE and MUST UNDERSTAND will reveal lots of good articles that talk about that.
- Minimize breaking changes.
A "breaking change" is a change that will break existing clients. That is, removing a field the clients use. Or changing the meaning of a field (i.e. changing an amount field from dollars to Yen). That is, something that invalidates a client's assumptions about the data it's currently using.
With a breaking change, every client needs to make a change to support the new semantics or stop relying on missing fields. Do don't do that unless its necessary.
The next logical step gets kind of contentious -- but in the extreme you would never make a breaking change. That is, have full backward-compatibility for every release. That may or may not be realistic, and it may require carrying along baggage from early versions, but it will spare a lot of churn for the clients.
OAuth 2 is a really good bet for a well-thought out, standardized security protocol. You could sit down and design something simpler, depending on what compromises are OK. But OAuth is a good fleshed-out protocol that has undergone years of industry scrutiny, so they've had lots of time to work out the kinks. And standard libraries are readily available for both client and server. I used an OAuth plugin to DJango for one project and it worked out really well.
Because of the ubiquity of JSON parsers, maintaining a single API regardless of client will make life a lot easier. Sometimes it doesn't work out -- sometimes a client can only understand XML or some proprietary protocol, but starting simple & adding complexity makes life easier.
I've had the same problem and "solved" it by modelling REST resources differently, e.g.:
/users/1 (contains basic user attributes)
/users/1/email
/users/1/activation
/users/1/address
So I've basically split the larger, complex resource into several smaller ones. Each of these contain somewhat cohesive group of attributes of the original resource which is expected to be processed together.
Each operation on these resources is atomic, even though it may be implemented using several service methods - at least in Spring/Java EE it's not a problem to create larger transaction from several methods which were originally intended to have their own transaction (using REQUIRED transaction propagation). You often still need to do extra validation for this special resource, but it's still quite manageable since the attributes are (supposed to be) cohesive.
This is also good for HATEOAS approach, because your more fine-grained resources convey more information on what you can do with them (instead of having this logic on both client and server because it can't be easily represented in resources).
It's not perfect of course - if UIs is not modelled with these resources in mind (especially data-oriented UIs), it can create some problems - e.g. UI presents big form of all attributes of given resources (and its subresources) and allows you to edit them all and save them at once - this creates illusion of atomicity even though client must call several resource operations (which are themselves atomic but the whole sequence is not atomic).
Also, this split of resources is sometimes not easy or obvious. I do this mainly on resources with complex behaviors/life cycles to manage its complexity.
Best Answer
Implement something inspired from etags.