How do REST URIs work internally?
I'm trying to create a REST API to interact with a MySQL database. I want to use this API to access the database from an Android or iOS device without (obviously) exposing the database directly through the application. But I'm having problems wrapping my head around a key aspect about REST and the implementation of an API designed on its principles.
I understand the concepts of REST from the theory stand point. What I've been struggling for days trying to grasp is how a REST URI maps to something located on a database server.
If I make a GET request to a server for a resource with a given URI, say http://www.example.com/resource, internally, where does this go to on the server? The way I understand it, is that it goes to the root directory, then to the "resource" directory. From there it returns all the files within that "resource" directory. I'm simply confused because the resource is located on the database server and not the server where the API is being called from. Does the resource path/hierarchy represent actual directories on the server or is it an abstraction of the resource? If the latter, then what do I do with that abstracted resource name to make it map to a table or row in a database? It's been frustrating not being able to find concrete implementation examples of this where I can easily understand how this URI path works internally.
You can use a framework to do a lot of the work for you, but what happens under the hood is no magic. In some way, the URIs map to some database tables. They don't refer to a certain directory structure, but try to explain a hierarchical relationship between the resources.
For example, let's say that we're modelling a university. The elements in the database are stored in one of two tables, either Faculties or Courses. The Faculties table consists of rows describing the Faculty of Law, Faculty of Medicine and so on. It has a unique faculty_id column and then columns to describe whatever we need. The Courses table has a unique course_id column and a foreign key faculty_id column, to tell which faculty the course belongs to.
A RESTful way of designing this API might be
- /faculties to get a list of all faculties, retrieved with SELECT * FROM Faculties
- /faculties/2 to get the information about a certain faculty, retrieved with SELECT * FROM Faculties WHERE faculty_id=2
- /faculties/2/courses to get all the courses belonging to a certain faculty, retrieved with SELECT * FROM Courses WHERE faculty_id=2
- /faculties/2/courses/15 to retrieve a certain course, if it indeed belongs to faculty 2, retrieved with SELECT * FROM Courses WHERE faculty_id=2 AND course_id=15
The exact implementation of this depends on the programming language (and possibly framework) that you choose, but at some point you need to make choices about how you should be able to query the database. This is not obvious. You need to plan it carefully for it to make sense!
The result from the database will of course have to be encoded in some way, typically XML or JSON (but other representations are just as fine, although maybe not as common).
Apart from this, you should also make sure to implement the four verbs correctly so that they match the SQL commands (GET=SELECT, POST=INSERT, PUT=UPDATE, DELETE=DELETE), handle encoding negotiation correctly, return proper HTTP response codes and all the other things that are expected of a RESTful API.
As a final piece of advice: If you do this neatly, it'll become so much easier for you to design your mobile apps. I really can't stress this enough. For example, if you on a POST request return the full entry as it now looks in the database, you can immediately store it on the phone with the correct ID, and you can use the same code for rendering the content as you would if it had been downloaded using a GET request. Also, you won't trick the user by updating prematurely, before you know whether that request was successful (mobile phones lose connection a lot).
EDIT: To answer your question in the comments: Creating an API can be seen as a form of art, and should probably not involve any coding in the design stage. The API should be meaningful and not rely on a particular implementation (i.e. a different database choice shouldn't affect your API). Your next task will be to create ties between the human-readable structure of the API and your database (regardless of whether it's relational or something else). So yes, you will need to do some translation, but I don't see how the query string would help you. The typical structure is api.my.website/collection/element/collection/element. Queries can be used for filtering. You could for example write example.com/resource?since=2012-06-01 to retrieve a subset of the elements from your 'resource' collection, but the meaning of this particular query is to retrieve something you couldn't express with an unique ID.
The way I understand it, you think that incoming requests must always go to separate files based on the way PHP and HTTP servers work. This is not the case. You can configure your web server to route every request to a single PHP file and then parse $_SERVER['REQUEST_URI']. Depending on your choice of HTTP server your mileage might vary, but this is essentially what you want to do.
By googling I found a list of frameworks for PHP but I don't know any of them. There are others, though, and I also recently heard someone mention Apify, although I can't tell you much about that either. PHP is probably one more the more common choices for implementing an API. cURL, however, is a library/tool that's only designed to connect to other websites, as far as I know. You can certainly use the command line version of it to debug your API, but I don't think you'll have much use for it on the server side.
I think you should start with what framework you want to built the REST application from. Rails, RestEasy for java, Codeigniter, all have the basis for good REST routing capabilities. This includes abstracting URL's from the underlining resource either from database or even business processes. They accomplish this using URL mapping, or creating a Facade for abstractions. Generally REST does not really differ from tradational GET/PUT/POST with query parameters. Infact Apache URL rewrites usually are used to support REST style routing. I recommend you should pick up one of the frameworks and study how they implement this functions. Rails i thing has significant strength among other frameworks.