Build a RESTful API using PHP and Yii2
Time to read: 9 minutes
Since its introduction, RESTful architecture has redefined the way we think about (and build) software applications by breaking down complex application ecosystems into smaller, more focused applications communicating with each other via RESTful calls.
Client-Server Architecture allows web clients and mobile apps to communicate with the same infrastructure (such as a server-side API) to provide a seamless user experience.
In this tutorial, I will show you how to build a RESTful API using the Yii framework (version 2)- a high-performance, component-based PHP framework.
Prerequisites
A basic understanding of the Yii framework and PHP will be of help in this tutorial. However, I will provide brief explanations and links to the applicable parts of the official documentation throughout the tutorial. If you’re unclear on any concept, you can review the linked material before continuing.
Additionally, you need to have the following installed on your system:
- PHP version 7 or higher with the PDO extension enabled.
- Composer globally installed
- A local database server. While MySQL will be used in this tutorial, you are free to select your preferred database vendor.
- Postman, or a similar application, to test endpoints. You can also usecURL to test your endpoints.
What we’ll build
In this tutorial, we'll build an API for a library app. This application will handle two major resources, Members and Books. The application will allow basic CRUD operations for both resources. Additionally, members will be able to borrow books. When a book has been borrowed, it won't be possible for another user to borrow the same book.
Getting started
Creating the application
To get started, create a new application called library-api
and switch to the project directory using the following commands.
Verify that the application was created successfully using the following command.
By default, the application will be served onhttp://localhost:8080/. Navigate to the URL and confirm that it shows the welcome page, which you can see below.
Return to the terminal and press Control + C
to quit the server.
Setting up the database
Using your preferred database management application, create a new database called library-api
. Next, update the database connection parameters to link your application with the newly created database. To do this, open config/db.php
and update the returned array to match the one shown below, carefully replacing the placeholders with the username and password for your database.
Create migrations
Next, create the migrations for the database tables. To put the migrations in context, the application will have three entities, namely:
- Member: This entity will represent a member of the library. For this article, the member table will contain the name of the members along with the start date of the membership.
- Book: This entity will represent a book available in the library. For this article, the book table will contain the name of the book, the author, year of release, and whether the book is available on loan or not.
- Loan: This entity will manage the data related to the process of "borrowing" a book. For this article, it will contain the book being borrowed, the member who borrowed it, the date it was borrowed, and the expected return date.
To create a migration, use the yii migrate/create
command providing the name of the migration to be created. When asked for confirmation, type yes
for the migration to be created. For this article, use the commands below to create the needed migrations.
By default, migration files are located in the migrations directory. Migration file names are prefixed with the letter "m" and the UTC datetime of its creation. For example m210408_150000_create_member_table.php.
Open migrations/m<YYMMDD_HHMMSS>_create_member_table.php and modify the safeUp
function to match the following code.
Edit the safeUp
function for migrations/m<YYMMDD_HHMMSS>_create_book_table.php to match the following code.
Edit the safeUp
and safeDown
functions for migrations/m<YYMMDD_HHMMSS>_create_loan_table.php to match the following code.
Seeding the database
To have some data available when the tables are created, we can create migrations to insert fake data into the database. Create two new migrations using the following command:
Open migrations/m<YYMMDD_HHMMSS>_seed_member_table.php and modify the safeUp
function and add the insertFakeMembers
function after it, as in the code below.
Next, open migrations/m<YYMMDD_HHMMSS>_seed_book_table.php and modify the safeUp
function and add the insertFakeBooks
function after it, as in the code below.
With the changes made, run the migrations to create the tables using the following command:
When prompted, type “yes” and press “Enter” to run the migrations. Open the library-api
database in your preferred application to see the new table structure.
The book table with sample books is shown below.
The member table with sample members is shown below.
Create the models
Instead of writing raw SQL queries to interact with the database, we will create Active Record classes for our models. These will give us an object-oriented means of accessing and storing data in the database. Create Active Record classes for the Member, Book and, Loan entities using the commands below. When prompted type yes
and press Enter
to continue.
The model classes are saved in the models directory. Interestingly, they help us generate functions to handle intricate relationships in our database structure. For example, in models/Member.php, a getLoans
function was created for us, which retrieves all loans associated with a given member. The same is the case for the models/Book.php.
Create the controllers
With the database and models in place, we can create controllers to handle RESTful calls. Yii bases controllers on yii\rest\ActiveController, which provides common RESTful actions. This allows us to create endpoints to handle CRUD actions without the stress of writing the boilerplate code ourselves.
To start off, create controllers for the Member and Book entities using the commands below. Type “yes” and press “Enter” when prompted.
The controllerClass
argument specifies the name of the controller to be created. You are expected to provide a Fully Qualified Namespaced class.
Note: The double backspaces (\\
) used in specifying the namespace are necessary to escape the single backspace in the fully-qualified class name.
The controller classes are stored in the controller directory. Open controllers/BookController.php and edit the content to match the following.
In the same way, open controllers/MemberController.php and edit the content to match the following.
Next, modify the urlManager
component in your application configuration, which you will find in config/web.php.
In config/web.php
, an array, stored in $config
, is returned. This array contains a components
element In that element, replace the commented out version of the urlManager
element with the following:
This change adds a URL rule for the Member and Book controllers so that associated data can be accessed and manipulated with pretty URLs and meaningful HTTP verbs.
The components
element also contains a request
element which holds the configuration for the request Application Component. To enable the API to parse JSON input, add the following to the request
element.
At this stage, we have an application that can handle the following requests:
Method |
Route |
Description |
GET |
/{members, books} |
List all members or books page by page; |
POST |
/{members, books} |
Create a new member or book; |
GET |
/{members, books}/123 |
Return the details of the member or book 123; |
PATCH and PUT |
/{members, books}/123 |
Update the member or book 123; |
DELETE |
/{members, books}/123 |
Delete the member or book 123; |
Serve the application by running php yii serve
and test your newly created endpoints.
For example, to retrieve the lists of books from the database, send a GET request to http://localhost:8080/books
. To do that, launch Postman if you don't have it open already.
If this is your first time using Postman, you need to enter the API endpoint where it says ‘Enter request URL’ and select the method (the action type) on the left of that field. The default method is GET and this is suitable for our use case. Next press the Send button, which is located to the right of the request URL field. This process is depicted by the image below:
If successful, you will see a JSON response containing the lists of books from the database and a status code of200 Ok.
Next, create a new member by sending a POST request to http://localhost:8080/members
and input the appropriate details as shown in the screenshot below
Note that your details might not be similar to this, but here is what the raw JSON requests should look like:
If the request is successful, you will receive a JSON response containing a 201 Created status code.
The last controller we need is the LoanController
to manage loan-related requests. With regards to loans, the API should only permit requests to create a new loan i.e., borrow a book or view all the loans on the system. Create the LoanController
using the following command. Type yes and press Enter when prompted.
Note: Because we do not need all the RESTful actions made available by the ActiveController class, we did not specify a base class. The generated controller will extend the yii/web/Controller class by default.
Before we create actions to handle requests, we need to add the new routing rules for the new API endpoints. In config/web.php, add the following to the end of the rules
element’s array in the urlManager
element.
When completed, the urlManager
should look like the code below:
Using the shorthand notation provided by Yii, we can specify the route for a given URL. The URL is provided as the key with the route to the appropriate action as the value. By prefixing the URL with an HTTP verb, the application can handle URLs with the same pattern (for different actions) accordingly. You can read more about this here.
To allow the API to handle POST requests, CSRF validation will be disabled in the LoanController
. To do that, in controllers/LoanController.php, add the following member variable.
Note: Disabling CSRF without additional checks in place may expose your application to security threats. Read more about thishere.
Next, update LoanController
's actionIndex
method to handle the request to get all loans by replacing the method's existing code with the code below.
NOTE: Don't forget to import the loan model
Before creating the action to handle the creation of a new loan, add a helper function to return an error response from the API, by adding the code below to the end of LoanController
.
NOTE: Don't forget to import Yii.
With the changes made, before creating a new loan, the application will run the following checks:
- Ensure that the
book_id
provided matches an existing book in the database. - Ensure that the selected book can be borrowed i.e.,
is_available_for_loan
is set totrue
. - Ensure that the
member_id
provided matches an existing member in the database.
If any of the above conditions are not satisfied, the errorResponse
function should be called, returning an appropriate response message.
Before creating the action, add a function to the Book model which allows the book to be marked as borrowed. To do that, in models/Book.php, add the following code.
Next, create an action to handle the request to borrow a book by adding the following code to controllers/LoanController.php
.
NOTE: Don't forget to import the Book and Member models
Test the new routes
You can test your new routes to see them in action. To borrow a book, you will send a POST HTTP request to this endpoint http://localhost:8080/loans. Enter the API endpoint in the URL field and select POST from the action dropdown field. Next, select Body on the next line and use the following code as an example of a raw JSON request:
If the request is successful, you will get a JSON response similar to the response below, along with an HTTP 200 OK status code:
Conclusion
In this article, we built a RESTful API for a small library application with the Yii2 framework. During the process, we saw some advantages of developing with the Yii2 framework, such as generation of features (models, controllers, etc.) with minimal code/boilerplate, its secure-by-default features to protect applications from SQL injection, and CSRF attacks, to name but a few.
Additionally, the underlying philosophy in how the code was structured allows us to take advantage of best practices and OOP patterns, thus resulting in code that is easier to maintain.
The entire codebase for this tutorial is available on GitHub. Feel free to explore further. Happy coding!
Oluyemi is a tech enthusiast with a background in Telecommunication Engineering. With a keen interest to solve day-to-day problems encountered by users, he ventured into programming and has since directed his problem-solving skills at building software for both web and mobile.
A full-stack software engineer with a passion for sharing knowledge, Oluyemi has published a good number of technical articles and content on several blogs on the internet. Being tech-savvy, his hobbies include trying out new programming languages and frameworks.
- Twitter: https://twitter.com/yemiwebby
- GitHub: https://github.com/yemiwebby
- Website: https://yemiwebby.com.ng/
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.