Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
  1. Code
  2. APIs

Building Your Startup: Designing a RESTful API

Read Time:13 minsLanguages:
This post is part of a series called Building Your Startup With PHP.
Building Your Startup: Running Multiple Domains
Building Your Startup With PHP: Bootstrap Your Home Page
Final product imageFinal product imageFinal product image
What You'll Be Creating

This tutorial is part of the Building Your Startup With PHP series on Envato Tuts+. In this series, I'm guiding you through launching a startup from concept to reality using my Meeting Planner app as a real-life example. Every step along the way, I'll release the Meeting Planner code as open-source examples you can learn from. I'll also address startup-related business issues as they arise.

Why Build an API for Your Startup?

The main reason I'm adding an API to Meeting Planner at this time is to create a foundation for building an iOS mobile application. The mobile app will use the API to register and log in users and then allow them to schedule meetings.

APIs also have a secondary effect of helping you rethink and better organize all the code you've written to date. There are certainly places within the Meeting Planner code that have become convoluted. Now I have to simplify them again for mobile apps to replicate the features above the fray.

There could be other reasons in the future for building the API. For example, perhaps I want to enable third-party developers to extend the kinds of meetings and events that Meeting Planner schedules—allowing them to collect and share additional data in the process.

As a reminder, all the code for Meeting Planner is provided open source and written in the Yii2 Framework for PHP. A significant portion of this episode describes how to use the Yii Framework to support an API. If you'd like to learn more about Yii2, check out my parallel series Programming With Yii2

Before I dive into the API code, I'd like to encourage you to try scheduling your first meeting so you know what I'm talking about. 

If you have questions about this tutorial or the application itself, I do participate in the discussions below, and you can also reach me @lookahead_io on Twitter. I'm always open to new feature ideas for Meeting Planner as well as suggestions for future series episodes.

Designing Your API

As I prepared to build the API, there were various concepts that I needed to understand. I addressed some of these in Programming With Yii2: Building a RESTful API (Envato Tuts+).

First, I needed to create an endpoint for the API where all of the calls from mobile apps would arrive. I decided to use an independent third tree in the Yii Advanced Application framework, e.g. https://api.meetingplanner.io instead of https://meetingplanner.io/api/. This allows a clean separation of API code from the rest of the service.

Second, I needed to design security into the API. In today's tutorial, I'll demonstrate the simple, alpha security we're using, but we'll strengthen it over time, and I'll likely write more about this in the future. There's an aspect to security in how we use and transmit the API keys and request, but it's also important to ensure the API enforces the application security protocols. For example, a user can't request the participants of a meeting if they're not the meeting organizer or one of its participants.

Third, I would like to prepare the API code for versioning. For example, an older iOS application that hasn't been updated might use API v1.0, while a later update might call API v2.0. Yii provides methods for doing this, but I haven't yet implemented them in the current design.

Fourth, I wanted to conform as much as possible to REST standards. That's something that I've begun to do but will require more research to fully implement.

Finally, for now, I needed to address the breadth of functionality that the API would provide. Initially, for the mobile application development, I focused on creating read-only functionality. Today's tutorial and code will focus primarily on read-only application functionality, i.e. show me the user's meetings. But it does include user registration as well. In the near future, we'll add more write functions such as create a meeting, add a participant, add a meeting place, finalize an invitation, etc.

So consider this tutorial a first step towards a robust, completed services API for our application. 

Building the API

Creating the API Service Tree

Building Your Startup - the API treeBuilding Your Startup - the API treeBuilding Your Startup - the API tree

Meeting Planner uses the Yii Advanced Application framework, which includes a front-end tree for the application and a back-end tree for the administrative component, and we'll create a third tree for the API. 

I described how to do this earlier in Programming With Yii2: Building a RESTful API (Envato Tuts+)

First, I duplicated the back-end tree and related environment settings:

And I added the @api alias to /common/config/bootstrap.php:

Next, we'll start to build the core functionality.

Securing the API

I've created some basic security as we build and test the iOS application. I'll make this more robust in the future.

All API calls will need to know an app_id and app_secret. These will be transmitted in some form of HTTPS. However, there's no guarantee that we can protect these, so we have to ultimately design the application to be resistant to these keys being discovered.

For the moment, I've expanded the mp.ini file in /var/secure to include these:

Then, I created a Service.php model to manage verification of these keys. As we make this more robust, I'll only need to modify one piece of code.

Next, I set up a beforeAction in all the API controllers to reuse the above method:

The key weaknesses here are that the security keys are transmitted with each call and the query parameters aren't signed. Transmitting them over HTTPS helps, but it's not fully secure. I'll improve this in the future.

Registration and Login

The only two API calls that completely rely on API keys are registration and login. Mobile users can register via OAuth and send us their OAuth service tokens, or they can provide their email address to us directly.

Once received, each user is given a unique token, and this token secures that user's future API calls.

There is also more I need to do to improve the security of this, but I won't cover that today either.

Here's the initial code to register a user via the API and create a token:

The UserToken is a unique 40-digit random string, which makes it even more difficult to guess than believing that America would elect Donald Trump to lead them.

The Meeting Controller

Now, let's look at calls for a specific area of the API, requesting information about meetings. Here's the initial part of /api/controllers/MeetingController.php:

Notice above how every action verifies the tokens are correct.

Then, every API call for Meetings is identically structured, as shown below (commend my attempt at discipline):

For the time being, each call includes the $app_id, the $app_secret and the $token for the logged-in user. I will change this for security in the near future. It's secure, but not robustly secure.

Let's look at actionList, which lists the user's meetings filtering by the $status argument to filter them:

Eventually, the API may limit the number of meetings requests for each status, i.e. show me the most recent 15 meetings in planning mode by this user.

All the Meeting methods are built into the MeetingAPI model. Here's the code for the meetinglist() method:

First, the method verifies the token as belonging to the user:

Here's the code for UserToken::lookup():

Then, we check the filter for $status and fetch the user's $timezone:

And finally, we query a list of the user's meetings and transpose them manually into an array of objects:

While there may be an easier way to map the database results to return in the API, manually transposing the most complex table, Meeting, allows me to control what the API results provide programmers. It's actually a chance for me to improve and simplify the API over the original code and database properties.

For example, there's code that Meeting Planner has to generate sub-headings in the user interface that aren't stored in the database. Rather than require the iOS application to duplicate this complex code, we just generate the sub-heading and return it in the API results.

Making API Calls

Here's a preliminary way to make and test the API calls. For example, if I make the following URL call:

That will work. But, for testing and to see it in action, I used Postman, a Chrome app extension, that is extremely useful.

Here's how you can build an API call with the Postman UX:

Building Your Startup - Postman API RequestsBuilding Your Startup - Postman API RequestsBuilding Your Startup - Postman API Requests

And here's what the results look like:

Building Your Startup - Postman API ResultsBuilding Your Startup - Postman API ResultsBuilding Your Startup - Postman API Results

That's just an easy way to browse the raw result of my development server showing all my meetings:

That's it for now. You can browse through the release at the API tree and view many of the other methods. As I upgrade the security and improve the functionality of the API, I'll try to write more about it.

Looking Ahead

I hope you've enjoyed today's tutorial. Obviously, the API will grow and change as our mobile development goes forward. As I said earlier, I will be enhancing security and expanding the functionality.

Again, if you haven't yet, go schedule your first meeting with Meeting Planner now! 

You can also reach out to me @lookahead_io. I'm always open to new feature ideas and topic suggestions for future tutorials. Or try out our helpdesk and open a bug report or feature request ticket. 

Stay tuned for all of this and more upcoming tutorials by checking out the Building Your Startup With PHP series.

Related Links

Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.