This is a small example application that implements the required API endpoint.
Please clone the repository using Git:
git clone https://github.com/agmckee/solid-octo-fiesta.git
To set up, you must already have PHP and composer. Then use composer to install the required dependencies:
composer install
Once the dependencies have been installed, copy the .env file:
cp .env.example .env
Generate an application key:
php artisan key:generate
You can then run the tests:
php artisan test
Or you can test the application using an API client tool such as Yaak, Postman or Insomnia. I used Yaak due to Insomnia not working on my system.
You can test the implemented API endpoint by running the included seeder.
php artisan db:seed --class=CallSeeder
Then using an API client request the following URL and request JSON.
http://localhost:8000/api/work-tasks/resolutions
You may set the from and to query parameters manually or using your API client. The API
endpoint should return HTTP 422 if one query parameter is given but the other is not,
or if the dates are not valid dates.
The API endpoint was implemented as a Laravel resource controller. This wasn't necessary for the purpose of a single endpoint but in my experience an API rarely stays as a read-only resource. Using Laravel's resource controller from the beginning provides a good structure to build on. The methods that are presently unimplemented have been commented to show to other developers that this is deliberate, but I would not consider this ready for use without at least throwing an exception in those methods such as a "MethodNotImplemented" domain exception, which could then be handled appropriately, perhaps to log attempted uses and certainly to return an appropriate HTTP response.
I've used Laravel's request class feature to validate the requests, ensuring that the from
and to query parameters are valid dates. This is simple and practical and keeps the controller
uncluttered. It also makes it simpler to reuse validation logic between different endpoints if
that is desirable, keeping the application DRY.
In this example I've assumed that the from and to parameters will always be required together,
or both omitted. This is just a simplification for the purposes of this code test, in a real application it may be
desirable to support either parameter at a time.
The basic relations between the models have been set up. I wrote a seeder and seeded some data and then wrote a simple SQL query in DBeaver initially to test the joins.
SELECT *, count(*) FROM resolution_types rt INNER JOIN work_tasks wt, calls c WHERE c.stage NOT IN ('draft', 'archived') AND wt.resolution_type_id = rt.id AND wt.call_id = c.id GROUP BY resolution_type_id
I found it tricky to get Eloquent to generate the right query using the defined relations only. As there was a time-limit I chose to write the query using Laravel's query builder facade instead. I wrote the tests first and then used the tests to check the correctness of the response. I am reasonably happy with the correctness of the data, if I had more time I would write additional tests to try to exhaustively prove the correctness of the approach.
I believe this completes the code test as described in the supplied brief.