In first blog post we wrote about how to design a good API. Now we are going to take the next step and talk about Relationships and andpoints.
In this relationship, one resource is related to only one resource. In database architecture that would mean that one row in a table may be linked with only one row in another table and vice versa.
Type of relationship that refers to relationship between two resources A and B in which resource A may be linked to many elements of B, but resource B is linked to only one element of A. In database terms that would mean resource A is linked to many rows in resource B, but resource B with only one row from resource A.
We could say that one to many model is always parent-child (children) model, where one element from one resource “owns” many child resource elements. In one to many model it is not possible to “glue” related tables together
Relationship in which one resource element is related to many elements (in other resource) and vice versa. Good example would be Movies and Categories relationship.
Movie can belong to many Categories, and Category can have many movies. In relation database management system, these types of relationships are implemented by the means of pivot tables.
Other widely used many to many relationship is User-Role relationships. In which User can have many Roles and Roles can have many Users.
As we stated in previous article, for our fakeTwitter project we will have three main resources: User, Post, Comment. Now we are going to define relationships between these resources.
From image it is easy to see dependencies between Users and Posts. Users would have many Posts and a single Post will always belong to only one User.
There is also one special type of relationship in which one resource is related to distant resource through third resource.
So in our case, Users resource is related to Comments resource through Posts resource. This relation enables us to get all comments written by one user, which we will use later in the series.
Now we have defined backbone of our API, since API’s are data centers it is crucial to define resources and relationships between them before starting to code.
Now we are going to replicate this in Laravel. Resource would be a model, so we begin by creating database structure first and then creating Models folder in app directory and creating User, Post, Comment models inside created folder.
There would be three database tables: users, posts, comments. Easiest way to do this is to create migrations using artisan command:
Migrations will create database structure for us, now it is time to communicate with database. Next thing to do is to create Models folder in app folder and create User, Post, Comment model inside that folder.
Good thing to mention when creating custom folders is to declare a namespace that will point to that folder avoiding long and unpractical class references. Namespaces are declared in composer.json under autoload PSR-4 key in project base folder. So my composer.json now looks like this:
Now we are ready to create models and define relationships between them in the way I described earlier. For handling one to many relationship we are going to use Eloquent’s hasMany() method, for inverse relation (many to one) we will use belongsTo() method and finally for has many through relationship (User — Comments) we will use hasManyThrough() method. The only thing we need to do is just define in on the model and Eloquent magic will do the rest.
Eloquent’s hasMany command takes 3 arguments (only first is required), first one is related model, second is foreign key on related model and third one is the local key. HasManyThrough() however is little bit more complex, it’s first argument is distant model on which we define relationship, second argument is intermediate model, third is foreign key on intermediate model (Post model) and finally fourth argument is foreign key on distant model (Comments model).
In this case we also have a many to one relation which is represented by belongsTo() method, it takes three parameters, first is related model, second is foreign key and third is local key of parent model (User).
Similar to previous examples. For more information about relationships in Laravel please visit Laravel documentation.
Now that we have our models defined, we have a blueprint on which we will build rest of our API. As I stated in previous articles, we will use HTTP verb based endpoint naming method. We will use GET, POST, PUT, DELETE verbs. Using this verbs we can define “default endpoints”. Default endpoints are incredibly easy to design and they will exists in almost every project, except default endpoints we will have custom endpoints too.
Last two columns are the names of methods in controller that will handle that endpoint. As you can see, naming examples are quite intuitive and have a consistent pattern.
In Post model thing are little bit different. Since Post is owned by User model some endpoints are accessible only through User model. These endpoints starts by “users” base node in URL (POST /users/{id}/post, PUT /users/{id}/post/{post_id}).
Some of the endpoints are publicly accessible such as get all posts (GET /posts) or get one post (GET /posts/{id) and furthermore some are accessible only by admin (DELETE /posts — deletes all posts). While designing developer needs to think about usability and functionality which needs to be implemented and adjust endpoints to project needs.
Now we have defined most common endpoints that will lead request to our models which in the end will interact with database and do some data manipulation. Bear in mind that these endpoints are just for learning purposes. In a real world example you would have more, depending on your project’s needs. Feel free to have questions about API.