PHP developers often use an environment composed of Linux, Apache, MySQL, PHP — often this environment is called LAMP (Linux, Apache, MySQL, PHP). Many applications are developed on LAMP, however, for most of those applications, there is no API to easily connect them. In this article, you will learn first how to design an API for your existing applications. In the later portion of this article, you’ll learn how to code your API interface to give access to your application implementation.
Mulesoft uses the API-led connectivity model to create application networks. That way is also called contract-first approach.
Unfortunately, that approach is not always possible. For example, you already have a running application and you want to re-use part of that application in your application networks. To make it, you will have to design your API and connect it to your application. This approach is called “Meet in the middle,” that’s probably the worst approach in terms of development but sometimes you don’t have choices.
Here is what you will do to solve this problem:
- Find what functionalities from your application you want to reuse.
- Create an API specification to specify those functionalities.
- Create the interface for the API specification.
- Connect the API specification to your application implementation.
- Listen to the correct HTTP resource.
#1 Functionality to expose
Your application proposes a calendar to the customers, you want to be able to see the calendar outside of your application thanks to a Rest API.
Your goal is to design a REST API, implement the interface and link it to the existing code.
Of course, if it is possible you can try to get a similar structure and similar field names that what you already develop in your PHP. (meet in the middle approach)
#2 API specification
Based on the existing PHP code, you now have to create the API specification.
Here is an example of a RAML specification that you can create using Anypoint API Designer:
#%RAML 1.0 title: Calendar types: calendar: !include datatype/calendarDataType.raml mediaType: - application/json /calendar/{year}/{month}: uriParameters: year: type: string pattern: "[12][0-9]{3}" month: type: string pattern: "0[1-9]|1[0-2]" get: responses: 200: body: type: calendar
The calendar data type:
#%RAML 1.0 DataType type: object properties: month: string year: string days_in_month: string first_day_of_the_month: string events: type: array items: !include eventDataType.raml
The event data type:
#%RAML 1.0 DataType type: object properties: date: string text: string url: string type: string time: string
Of course, the event data type is probably a simple mapping of data type contained in your database.
The best practice is to provide an example of the data send back by the API into the specification, in this case:
{ "month": "03", "year": "2020", "days_in_month": "31", "first_day_of_the_month": "Sun", "events": [ { "date": "2020-03-05", "text": "Meeting Week 1", "url": "/news/meeting-05-03-2020/", "type": "Weekly meeting", "time": "20:30:00", }, { "date": "2020-03-12", "text": "Meeting Week 2", "url": "/news/meeting-2020-03-12/", "type": "Weekly meeting", "time": "20:30:00", } ] }
#3 Interface creation
In this section, you have to manually implement the PHP code attached to the specification. In the following code, this part is called CODE SECTION : INTERFACE. In that part, you have to be sure that your API specification is respected. For example, you can re-use regular expressions from your specification into your PHP code.
date=$year.'-'.$month.'-'.sprintf("%'.02d", rand(0,28)); $infos[$i]->text=$texts[$random]; $infos[$i]->url=$urls[$random]; $infos[$i]->type=$types[$random]; $infos[$i]->time="20:00:00"; } return $infos; } // CODE SECTION : INTERFACE $year_month_regex="#^/calendar/([12]d{3}/(0[1-9]|1[0-2]))$#"; if (preg_match($year_month_regex,$_SERVER['REQUEST_URI'],$match)) { // CODE SECTION : IMPLEMENTATION header('Last-Modified: ' . gmdate( 'D, d M Y H:i:s' ) . 'GMT' ); header('Cache-Control: no-cache, must-revalidate'); header('Pragma: no-cache'); header('Content-Type: application/json'); $cal =explode("/", substr($match[0],-7)); $year =$cal[0]; $month=$cal[1]; $infos=new stdClass(); $infos->month = $month; $infos->year = $year; $infos->days_in_month = date('j', mktime(0,0,0,$month+1,0,$year)); $infos->first_day_of_the_month = date('D', mktime(0,0,0,$month,1,$year)); $infos->events=my_calendar($month,$year); echo json_encode($infos); } else { header("Status: 404 Not Found", false, 404); } ?>
You can download the code here.
#4 Connect the interface to the application
Once the interface is ready, you have to connect it to the feature that you want to expose. In the previous code example it is done in the CODE SECTION : IMPLEMENTATION. Here is a description of the different steps:
- Specify that you don’t want cache. Here it is the role of the custom function header_no_cache.
- Specify the return type: application/json.
- Get the required information from the URL: date and year.
- The last step is to create an object to return and to return it as JSON: echo json_encode($infos).
#5 Listen to the correct HTTP resource
In the previously created code the url to access to the REST API is: http://www.site.com/calendar/index.php
The url we want to respond is: http://www.site.com/calendar/2020/03
To do that you have to create an Apache rule to redirect all the traffic http://www.site.com/calendar/* to http://www.site.com/calendar/index.php
You have to put the following .htaccess file in your application /calendar directory.
RewriteEngine On RewriteBase /calendar/ RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /calendar/index.php
Conclusion
You are now able to create a REST API in front of your PHP program to expose your services.
The next steps will be:
- Publish the specification in Anypoint Exchange.
- Link the Anypoint Exchange previously created asset to your running PHP code by setting the corresponding endpoint in the tool.
- Create the documentation of your service in Anypoint Exchange.
- Engage internal users with Anypoint Exchange.
- Engage external users with the Anypoint Exchange public portal or API Community Manager.
You can find the specification on my Anypoint Exchange public portal and the PHP code on GitHub.