In this video, Keith Casey demonstrates using a service container to retrieve data, implement simple error handling, and add the first (logging) middleware.
- [Teacher] Now we're going to start plugging in some components to make our first API call. But before we can do anything in our code, we need the database. Since I installed php in MySQL via MAMP, I'm going to open phpMyAdmin and create the database. We'll call the database Chatter, and go ahead and create it. I'm also going to create a username of chatter_api, and we'll also set the password to chatter_api. Do not use this in production instances. I'm doing this because this is a local development that will never make it outside this class.
When you're setting up your own database, please choose a secure password. MySQL is smart enough to realize that since I named a database Chatter, and the username chatter_api, it'll automatically connect the two for us. But now we need actual data to put into our database. So when we go back to Sublime Text, there's a folder here called database with a file called create.sql. I'm going to open that file and select the whole thing. Copy and paste that into phpMyAdmin on the SQL tab.
It should execute with no errors. Then we go to the structure, we can see there's messages with four rows and a users table with four rows. Now that the database is ready, let's get into the code. So go back to Sublime Text and start building up our first route. In this case, we'll take the existing route, remove everything from inside, and change it to say messages. So this will catch the messages route, but isn't going to do anything with it. So let's make it do something just to prove that it's working. So now, when we hit the messages route, it'll return "This will return a list of messages." and that's it.
So let's go back to our browser and see it in action. This will return a list of messages, just as we expected. So far, so good. But now, we need to get our data from the database into the API. A couple different approaches for that. We're going to use eloquent. So on the command-line, we'll do composer require illuminate/database and we'll get version 5.2. So now behind the scenes, composer will go ahead and download and install all of our dependencies for us.
Now some people get a little nervous on this screen. They see all these log messages, and they think there's a problem. It's not a problem. What it's doing is it's saying, "If you want to do these other things, "you'll also need these components." Right now, we're not doing those other things, so don't worry about it. So we'll clear this screen and go back to our application. So we have our library, we have our database, now we need to connect the two. So we'll go ahead and create a new file called bootstrap, and within there, we'll go ahead and get things set up.
So we'll include the autoloader, we'll use Illuminate, the Database library specifically, within that, let's call the Capsule and the Manager. We'll abbreviate this to Capsule just to make it a little bit easier. We'll create the new capsule, and Capsule is really just an object that holds a bunch of parameters for us. So it knows how to connect to the database, we don't need to figure that out ourselves. The first time, we do have to tell it. So we have capsule, addConnection, and we have to feed it an array of values.
So in this case, we'll need the driver, which is just mysql, we'll need a host, which is just localhost, we'll need a database, this is the name of the database we set up, so it's just simply chatter, we'll need a username, which is chatter_api, we'll need a password, which we also set up to be chatter_api, and finally for safety sake, we wanna specify a few more parameters. So we'll specify the character set as utf8, specify the collation as utf8_general_ci, and then finally, we'll give it a prefix.
In this case, the prefix is just a zero-line string, nothing all that exciting about it, but it's there in case we ever need it. So now we've built our capsule, we've added a connection to it, now we need to do something with it. So the capsule needs to bootEloquent, and that's it. So now, we have a database connection. We're not doing anything with it, but now we have a way to go between our code and our project. So back here, after its require autoload, we'll go ahead and include bootstrap.php. So now that database connection is available to us.
But what's there? Well, we need to connect something to the database. So let's do that. We'll create a new folder called src for source. Once in there, we'll create a folder called Chatter. And finally, once in there, we'll create a folder called Models. And the models will handle all the database access for us. And luckily, they're really pretty simple. So we'll start our first model, Message.php. Say namespace so that the system knows where to find it, Chatter\Models, class, Message, extends, this is where things get a little more challenging.
Illuminate\Database\Eloquent\Models. And realistically, that's it. So the Eloquent model will give us a lot of functionality to read, write, update, and even delete from the database without us having to do anything. It's incredibly powerful. But before we can actually use this, we still need to tell the system where to find our stuff. So go back to composer and add one more parameter here. We'll tell it how to autoload our code. So we add an autoloader, we tell it it's psr-4, and then we say when you see the Chatter namespace, that maps to source Chatter.
Then we have to go back to the terminal and do a composer update. And composer will read that file for us, and regenerate new classes that include all those automatically. There's nothing else we have to do there. Now that we have that, let's do something with it. So go back to index.php, and right now, it's still just returning that list of messages. There's nothing all that exciting. So let's make something more exciting. We'll say use Chatter\Models\Message, so now we've got that class available to us.
So within this route here, we'll delete our previous message which really didn't tell us anything anyway. Say _message equals new Message, and that's our custom Message class. Within there, we'll get a list of messages by simply calling all. Now let me warn you, this is not something you'd wanna do in production. This is a starting point to prove that yes, this is working as we expect. We'll go ahead and start building a simple payload. We'll say foreach messages as _msg.
Let's create a new item in the payload, _msg, so this is an indexed array, and within that, let's go ahead and add a couple parameters. First, let's add the body so that's available to us, _msg, body. We'll add the user_id, we wanna know who actually sent this message; _msg, user_id. And then we'll throw in one more field, created_at; _msg, created_at.
So now when we refresh our application, we can see the result. And it didn't work. Okay, so what happened? Well there's a couple different options. One, depending on our editor, it could give us some hints to what's wrong. Quite often, classes that are not found, or syntax errors, are highlighted or underlined in red. Don't see anything here, so there's nothing that pops out immediately. The other alternative is the php error log. If we look at this, we can see, there's our error. Class 'Illuminate\Database\Eloquent\Models' not found.
Well, we use this over here in the Message class, and the secret is this shouldn't be plural. If we get rid of the s, we come back to our application, should this work? We're still missing one thing. Do you see it? We're doing all this work in the application, but at no point are we actually outputting the results. So let's do that. return, json_encode, payload. Now when we go back to the browser and we hit Refresh, we get back a result. Now this isn't exactly pretty, so what we use to make this more useful, that's where our good friend Postman comes to the rescue.
It's an incredibly powerful tool that lets us accomplish big things with almost no effort. So here we've got the URL, we hit Send, and sure enough, there's our data. Still not super pretty, but it's there, and it's available for us. Now let's start talking about middleware. When we start looking at how to string these things together, we'll wanna be able to share access and share information. So the quickest and easiest way to do that is with middleware. So let's go ahead and wire our first middleware. Over on the left-hand side here, in the Chatter folder, we're going to create a new folder called Middleware.
Within that folder, we'll create a file called Logging. So we have Logging.php. Now middleware in Silex is a lot simpler than some other frameworks. It doesn't take much to get going. So go ahead and set up a namespace, Chatter\Middleware, just to keep everything organized, set up the class and call it Logging. Within that, we'll say public static function log, and we'll accept the request and the app just in case we need those.
Now what do we do? There's a variety of things we could do. Not all of them are going to be useful. In this case, let's do the bare minimum possible. So we'll set up the error_log, which we showed briefly, to request the method, getMethod, we'll insert a couple spaces here just for clarity, and then we'll say request, getUri, and that's it. So now the middleware's there, it's in place. Now we need to wire it in to our application. So up above here, let's go ahead and use it to make sure it's included.
Chatter\Middleware\Logging as ChatterLogging. So we have that available now. So let's add it to the app itself. So say app, before, function, get the request and the app itself, and then within this function, we'll go ahead and call the ChatterLogging, call it log, we'll pass in that same request and that same app. So now the way this is wired is that when the application opens, before it does any of the route-matching, it's going to attempt to resolve this middleware.
So it should write it to disk. Go back to our window here. And this is the error log that we had before. It's a little bit bigger. Give it just a second and it'll make sense. Now when we go to Postman and we hit Send, we still get back exactly what we got back before, nothing changes there. But in the back end, you can see, GET silex-app/messages. We just embedded logging in throughout our entire application with just a few lines of code. That's the power of middleware.
This course begins with a simple application specification and builds it one step at a time. Each chapter includes a key concept, with examples from other public APIs, and then shows how to build it yourself with Silex. Learn about URL routing, validating input, and generating response codes and hypermedia payloads. Like any project, the first implementation may be a little messy, but don't worry. The last chapter covers refactoring and what it takes to scale and support the API going forward.
- Understanding the project goals
- Adding authentication with Silex
- Using cross-framework and authentication middleware
- Creating a read-write API in Silex
- Uploading files via an API
- Adding file security
- Creating payloads and response codes in Silex
- Scaling your API