By Theodore Mandilaras
This API was implemented with the Laravel Framework. More specifically:
- PHP Version: 8.0
- Laravel Version: 9.1
As for the database I used MySQL, which gets migrated and populated by the API.
The application can be easily build and deployed using Docker.
The api and the database can be build by running:
docker-compose build
docker-compose up
To create the database schema and to populate it by the track data, run:
docker exec -it vessel_api php artisan app:setup
The application can be found at: localhost:8000
.
For the needs of the API, two tables have been created:
Tracks: contains all the necessary fields
- mmsi
- status
- stationId
- speed
- lon
- lat
- course
- heading
- rot
- timestamp
IncomingRequests: In which the application logs all the incoming requests.
- id
- ip_address
- method
- endpoint
- params
- requested_at
The migration files for both of the tables can be found at database/migrations
.
The logic of the CRUD operations along with the requested filters can be found at app/Http/Controllers/TaskController.php
,
For the filtering of the data, I developed a service which uses the Query Builder of Laravel. This service builds the proper SQL statement according to the requested filters. The name of this service is TrackFilterer.php
.
To filter, the client has to provide one of the below params in the URL:
- mmsi: an array with one or more mmsis
- lon_range: an array with the min and max lon values. It must have exact 2 elements.
- lat_range: an array with the min and max lat values. It must have exact 2 elements.
- interval: an array with the starting and ending timestamps of interest. It must have exact 2 elements.
For example:
localhost:8000/api/tracks?mmsi[]=311040700&lon_range[]=30&lon_range[]=45&lat_range[]=10&lat_range[]=50
For the request logging, a middleware have been used, named LogRequests.php
. All the requests, before ending to the
Controller have to pass from it. There, it stores the request in the database, at the requests
table.
The rate limiting is configured at the app/Providers/RouteServiceProvider.php
file.
To support different content type, also a middleware have been created, which detects this types and process the data in order to suit with the controllers needs.
The name of this middleware is: ContentTypeMiddleware.php
An example of the accepted XML is:
<track>
<mmsi>247039300</mmsi>
<status>0</status>
<stationId>81</stationId>
<speed>180</speed>
<lon>15.4415</lon>
<lat>42.75178</lat>
<course>144</course>
<heading>144</heading>
<rot>xx</rot>
<timestamp>1372683960</timestamp>
</track>
and of a CSV is:
mmsi,status,stationId,speed,lon,lat,course,heading,rot,timestamp
123456789,1,54,122,15,16,142,144,?,1372683960
To test the application use:
docker exec -it vessel_api php artisan test
There is a test for all the CRUD operations and the filtering. They can be found at tests/Feature/ApiTest.php
For testing, I use a memory-stored SQLite database, which is migrated and populated before the tests start.
To better evaluate the API, a Postman Collection can be found here
If there is any issue in setting up or testing this api, please don't hesitate to ask me.
Your task is to create a RESTful API that serves vessel tracks from a raw vessel positions data-source. The raw data is supplied as a JSON file that you must import to a database schema of your choice.
Fields supplied are:
- mmsi: unique vessel identifier
- status: AIS vessel status
- station: receiving station ID
- speed: speed in knots x 10 (i.e. 10,1 knots is 101)
- lon: longitude
- lat: latitude
- course: vessel's course over ground
- heading: vessel's true heading
- rot: vessel's rate of turn
- timestamp: position timestamp
The API end-point must:
- Support the following filters:
- mmsi (single or multiple)
- latitude and longitude range
- as well as time interval.
- Log incoming requests to a datastore of your choice (plain text, database, third party service etc.)
- Limit requests per user to 10/hour. (Use the request remote IP as a user identifier)
- Support the following content types:
- At least two of the following: application/json, application/vnd.api+json, application/ld+json, application/hal+json
- application/xml
- text/csv
Share your work:
- Fork this repo and create a pull request that contains your implementation in a new branch named after you.
Notes:
- Please include your Tests with your source code
- Include instructions
- Feel free to use the framework, libraries of your choice or plain PHP to implement the assignment
Have fun!