It is better to go with the first option. Having your 3 clients - mobile, desktop and webapp - use the API in the same way is a better design since all of them use the API in a consistent manner, and any changes in the API will be reflected as-is in all the three clients.
This way it is easier to debug and simpler to extend new features. If your Rails app talks directly to the database you will have to modify the data access code (instead of the ReST client code) in your Rails app every time the API changes and the Rails app might end up modifying the data in a different way than the desktop and mobile app, leading to inconsistencies.
In a nutshell: Keeping consistent access mechanism will ensure better maintainability.
Another alternative (using HATEOAS). This is simple, mostly in practice you add a links tag in the json depending on your use of HATEOAS.
http://api.example.com/games/1
:
{
"id": 1,
"title": "Game A",
"publisher": "Publisher ABC",
"developer": "Developer DEF",
"releaseDate": "2015-01-01",
"platforms": [
{"_self": "http://api.example.com/games/1/platforms/53", "name": "Playstation"},
{"_self": "http://api.example.com/games/1/platforms/34", "name": "Xbox"},
]
}
http://api.example.com/games/1/platforms/34
:
{
"id": 34,
"title": "Xbox",
"publisher": "Microsoft",
"releaseDate": "2015-01-01",
"testReport": "http://api.example.com/games/1/platforms/34/reports/84848.pdf",
"forms": [
{"type": "edit", "fields: [] },
]
}
You can off course embed all data in all listing but that will likely be way too much data. This way you can embed the required data and then load more if you really want to work with it.
The technical implementation can contain caching. You can cache the platforms links and names in the game object and send it instantly without having to load the platforms api at all. Then when required you can load it.
You see for example that I added some form information. I did that to show you there can be much more information in a detailed json object than you would even want to load in the listing of games.
Best Answer
Unless the performance overhead of using the web service is an issue, you should definitely use your public API.
This will help you get a consistent behavior between your application and the consumers. It will also avoid code duplication and the best part - if you break your web service you will most likely be the first one to notice it.
The concept is usually referred to as "dogfooding" and Twitter is one example of an application, that dogfoods it's own API.