There is plenty of talk about Apigility, so I will not spend a ton of time going over what Apigility is. But for those that have been living under a Developers Rock, it is a project that was started by Zend about a year ago I think. It allows making API’s dead stinking simple. If you don’t know what an API is, then I will refer you to this article over on Wikipedia. Start there, then investigate the aspects that you don’t understand. For this investigative test, we are going to do a really simple test of the capabilities of this system.
Getting Started with Apigility
It super simple to get started using Apigility. From a terminal or command line, enter the root of your web directory and enter the following, using Composer
composer create-project apigility-test -sdev zfcampus/sf-apigility-skeleton
This tells composer to create a project directory from where you are, titled what you tell it. In our case that will be “api-test”, and load “zfcampus/sf-apigility-skeleton” into that directory. Once downloaded, Composer will download all required dependencies needed for the project. In the case of Apigility, that will include Zend Framework 2.3. The product is built using ZF, so… if that bothers you, and it will some, just stop right now and walk away. No harm done. But if you are looking into building out an API anytime soon and it will be of any substanle size… you really should push on just a bit. I think you will find it worthwhile time spent.
So, now we have a project structure that looks a little like this…
.puppet (contains files, manifests and modules used by Vagrant) /config (contains application config, dev config, ignored by version control) /autoload (environment settings, some configed through admin dashboard) /data ( contains a cache folder) /cache (umm, yeah so…) /module(contains core app files) /Application (core files used by Apigility) /(your api core files will be created here) /public (root of the project, contains the projects index.php) /vendor (vendor files/dependencies downloaded by composer)
Vagrantfile (file used to spin up a VM with everything pre installed. NICE!)
Enable Development Mode
Before you can do anything, at this point, you must enable development mode. What this does , in the simplest terms I can think of, is makes the Apigility Admin dashboard available for you to use. To do this, while still in your command line,
cd apigility-test php public/index.php development enable
We are changing directories into our project dir. Once there, we are using php to tell public/index.php to be put in development mode. You will, of course, need to undo this when you get ready to put your API into production. To do so, make sure you are in the root of your api project and run :
php public/index.php development disable
At this point, the Apigility Admin dashboard is not accessible and you are ready for production. Ok, now that we have that covered…
Configure our Database Connection
I already have a little database set-up and a local/test version of the db running this blog. So I will use it for my data. You probably have one as well. If so, use it. If not, umm… get some!
At this point, you can go to “http://localhost/apigility-test/public/” and you will be greeted with a pretty landing page that is the Apigility Dashboard. First thing I did was configure my local database settings. To do that, from the Dashboard, under Settings, click on the link titled “Database Adapters”. Then click on the button on the right side of the page titled, “Create New DB Adapter”. This then opens a form for you to fill out or make selections from to configure your database. Pretty simple, nothing fancy. But it is well laid out. This is how I set mine up for this test -
- Adapter Name: “Blog\Adapter”;
- Driver Type: PDO_MYSQL;
- Database: “blog_local”;
- Username: “root” (it’s a local instance, ok! Give me a break!)
- Password: “ ”;
- Everything else is optional and not needed for my instance.
Once configured, you will be greeted with a message at the bottom of the Dashboard that tells you if it was successful or not. Hopefully all went well.
Creating our first API
At this point, take a look at the top nav bar and find the link titled “APIs”. This will take you to a page that allows you see the different APIs you currently have. In our case, it will be empty, so click the button in the left nav area titled, “Create New API”. You will be greeted with a small module window that will drop down from the top, allowing you to give your API a name. Name it and click ok. Next we need to set-up what is called a REST endpoint for our API, so click on the link titled, “Rest Services” in the left menu, followed by another button click on a button titled, “Create NEW Rest Service” located on the right side of the dashboard.
At this point, we must quickly discuss to two options we have in front of us at the moment. We have two tabs, one allows us to set-up a “Code Connected REST Service” and the other allows us to create a “DB-Connected RESET Service”. I am going to try and simplify this as much as possible without watering it down too much, but the “Code Connected” service allows you to actually write the code to fetch your data from your database tables. The other, which is what we will use for now, does most of the work for you by connecting to your database table and generate typical Restful points for you. We are going to use this simply because I was not going to have the time to dig into this app very much tonight.
So, we click the tab for “DB-Connected”. Choose the database adapter that we set up earlier and then enter the table name that your api will use. Now, at this point, I think you can see where the first option will come in handy. Currently, we can retrieve data from a table. Not always a big deal, but still. Either way, moving forward! Click the button titled, “Create DB-Connected REST Service.
Boo-Yaa! We are done! Let’s take a look what routes/endpoints are possible at this point. Click the link titled, “Overview” in the navigation on the left side of the window. Then click on the name of the table that you connected to, under the table heading of “Rest Services”, we have quit a lot of info we can take a look at. At the very top though, you can see that there is already a “route” assigned to the restful endpoint. It is a route, with a parameter. This parameter is most likely an “id” field. So, that means, that we should be able to hit our base_url/posts/1 to retrieve the first post from our local blog database. And our base_url/posts uri should return all posts.
Instead of building out a bunch of different views to display that this is working, I will be using PostMan Client. And what do I get when I enter the following in Postman: “http://localhost/apigility-test/public/posts/3”
So! All things considered, without having to write an ounce of code, I was able to create a very simple API that I can actually use in my blog. Pretty sweet! The default content-type return by Apigility is JSONH or HAL (Hypertext Application Language). I might stick with it, but if you need to change the output to something different, you can do so from the Dashboard. Simply click on the API link on the top nav bar. Then, select REST Services in the left nav. Choose your API that you want to change. Once you have selected it, when you hover of the table header that is now displayed you will see two icons appear. Choose the green one. This makes all the fields editable. Look to the lower half of the fields and find one titled “Content Negotiation”. In the drop down, choose json and you are good to go, You can also add other types, but that’s a bit beyond the scope of this article.
The version that I am working with on this night is v1.0beta. And you can tell that it still a beta. The primary thing that got on my nervous was the fact that the Dashboard UI was very unresponsive on almost every click. Why is this such an issue, given that it’s still in beta? The UI is written using AngularJS. I love AngularJS and have played with it a lot and I have never written or seen anything written in Angular that was this sluggish. Hell, at first, I thought it was my laptop, plugged in a jump drive and allocated 2 gigs of extra ram. Nothing changed. I have not dug into the UI with devtools too much, but page loads of 4 to 6 seconds is not uncommonly reported from the Timeline, so… There are improvements that could be made. Firing up Batarang displays loads of info and a complicated dependence structure, but the performance issues do not seem to be coming directly from Angular. Even on the most data heavy pages, Angular was able to get it's methods called and returned in no more than 4ms - 5ms. It will be fun digging into this more since I am learning more and more on the front-end of the development spectrum.
As for the overall usefulness of the app, I can see where it could and will have its place in someones arsenal of api tools. For a large API, I can see how this would be the way to go. Especially if you are not very well versed in best practices of building a quality Restful API. But in general everyday use, such as a personal blog/cms, this tool would be total overkill. But if you are building the next Twitter style startup/kickstarter, it might just be worth a very close look.
From the look of things, all the controls are within a Zend Framework world. What do I mean by that? Well, let’s say you want to develop a large complex API. That would mean that you would want to create a “Code-Connected REST Service” from within the app. When you create a new endpoint service, the application creates a few files for you in the /module/
/V1 /Rest /Posts - PostsCollection.php - PostsEntity.php
There is a really good tutorial that covers creating this type of API here and I suggest you give it a read. But essentially, you write the code that fetches your data, validates your data, puts your data… I think you get the idea. You do this with three files,
I did not touch on a few other things that are very worthy of noting. The API documentation that is generated by the app is awesome! Hands down cool as heck and worth an install and an hour of your time just to look it over. Will I use Apigility in the future. Possible so, yes. Will I play with this again? Hell, yes. It’s cool and can be used to learn or understand API best practices as much as reading any tutorial can. Plus, I spent all of 30 mins tops getting my simple API test up and running. It has taken me 3 times that long to document and type this up. How could this tool not be useful, in the right environment?
Also, the built-in version control? Yeah, that's pretty sweet too. Notice in the above directory structure example, there is a "V1" folder, with the core of your app in it. Well, if you create a new version, the app creates a new "V2" folder, with new files in it. You would then edit these files through manually making code changes or through the Dashboard. You can then access that new API by changing your api routes ever so slightly, like so : http://yourdomain.com/v2/posts/1 would grant you access to version two of your api, whereas http://yourdomain.com/posts/1 would still grant you access to your old API. Nice!
That’s my quick take, anyway. What does everyone else think?