josepcrespo / tenejob-laravel-api

A Laravel project to demo my skills building a REST compliant API. The entire environment is built on top of Docker.

Home Page:https://tenejob-laravel-api.herokuapp.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

You can visit a demo of the project visiting the following Heroku App instance:

https://tenejob-laravel-api.herokuapp.com/


Table of contents:


TeneJob Laravel API Demo

Disclaimer

This is a demo project to provide an example of my skills for building a REST compliant API, using Laravel, writing PHPUnit unitary tests and, taking advantage of tools like Composer (a dependency manager for PHP), Git (a distributed version control system) and, the Unix Shell. The full development environment is built on top of Docker (using the Laradock project). Also reflects my knowledge of modern development platforms like GitHub (an online source code repositories hub).

This project has not been wrote in any case thinking to be used in production, but can be used as you wants under your total responsability. You can also fork it and, use as a foundation for your own project if you found it useful.


Introduction

The temporary recruitment agency called TeneJob wants to optimize the way they assign their workers to the different shifts of the jobs they work with.

In order to help them with this mission, you need to build an API endpoint that will accept a list of workers and shifts and return the best pairing options.


Problem domain

The problem has 3 main entities: Worker, Shifts, and Matchings.

A Worker has a weekly availability which is the days of the week (not including weekends) they can work. For example, a worker might only be able to work on Mondays and Wednesdays. Also, a worker might have a payrate, which is the amount of money paid to him for each shift he works on.

A Shift is a piece of work that needs to be done by a worker. To simplify the problem, you can consider a shift takes a whole day to be completed.

A Matching is the pairing of one worker with one shift. Two rules apply to shifts:

  • A worker can only work on one shift during the same day
  • A shift can only be matched with one worker

Solution

This API provides an endpoint that receives a list of workers and a list of shifts and returns the optimal list of matchings. A list of matchings is optimal if each worker is paired with at least one shift. In some scenarios, the algorithm won't able to get an optimal solution. In that case, the algorithm detects the situation and returns a message indicating this.


Implementation requirements

Build a dockerized system that can run as a docker container, to test the solution. This requirement is mandatory. The endpoint input and output should be sent in JSON format and it need to be REST compliant. The structure and an example of these are provided in the next section of this README.md file.

This project demo focuses on:

  • Organization of the code, the structure, scaffold and design patterns
  • The efficiency to generate the matchings
  • Documentation and code readability
  • Good development practices:
    • Unit tests
    • Input data validation o Error handling

Data input example

Structure example of the JSON data that the /api/matchings/auto-generate endpoint will expect:

{
  "workers": [
    {
      "id": 1,
      "availability": ["Monday", "Wednesday"],
      "payrate": 7.50
    },
    {
      "id": 2,
      "availability": ["Monday", "Tuesday", "Thursday"],
      "payrate": 9.00
    },
    {
      "id": 3,
      "availability": ["Monday", "Friday"],
      "payrate": 18.00
    },
    {
      "id": 4,
      "availability": ["Monday", "Tuesday", "Friday"],
      "payrate": 12.25
    }
  ],
  "shifts": [
    {
      "id": 1,
      "day": ["Monday"]
    },
    {
      "id": 2,
      "day": ["Tuesday"]
    },
    {
      "id": 3,
      "day": ["Wednesday"]
    },
    {
      "id": 4,
      "day": ["Thursday"]
    }
  ]
}

Data input validations

The /api/matchings/auto-generate endpoint will validate the data sent through POST.

One of the validations to be considered first of all is that all the shifts and workers should already exist on the database. The endpoint will validate that each ID of shifts and workers exists on the DB and, it will also compare the data of each shift and worker against the each ones stored on the DB. The endpoint will also return verbose error messages if invalid data is sent. So, consider login trough the web interface and put some data for your testing purposes.


Local development

In this section, you can get the instructions to setup this project on your local machine for development and testing purposes.


Requirements

This project has a few mandatory requirements. Make it sure you you have installed:

Git >= 2.13

Docker Engine >= 17.12


Get a copy of the project

Clone the project (and it's git submodules) using Git:

git clone --recurse-submodules https://github.com/josepcrespo/tenejob-laravel-api.git


Setup the Docker environment, Laradock

  1. Enter the /laradock folder and rename env-example to .env.

cp env-example .env

  1. Open the .env file of this project (tenejob-laravel-api) and set the following:

DB_CONNECTION=mysql
DB_HOST=mysql
DB_PORT=3306
DB_DATABASE=tenejob
DB_USERNAME=root
DB_PASSWORD=root
REDIS_HOST=redis
QUEUE_HOST=beanstalkd
MAIL_DRIVER=smtp
MAIL_HOST=maildev
MAIL_PORT=25
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

  1. Execute the following command inside the laradock folder, to build an run the containers:

docker-compose up -d nginx mysql workspace maildev

  1. Execute the following command inside the laradock folder, to get access to the MySQL Command-line Client inside the mysql container:

docker-compose exec mysql mysql -u root -proot

  1. Create the database for the app:

CREATE DATABASE tenejob;

  1. To install the defined dependencies for your project (don't execute Composer inside the workspace as is not recommended to run it as root), just run the composer install command into the project root directory using the Terminal.app (if you are using macOS) or with your preferred Shell:

php composer.phar install

You may want to look into the official Composer guidelines for Installing Dependencies for more details.

⚠️ If you used the --filename option on the Composer installation

  • Maybe you installed your Composer using the --filename installer option, for example in this way: php composer-setup.php --filename=composer In that case, you should run composer install in order to install the dependencies.
  1. Laradock introduces the Workspace Image, as a development environment. It contains a rich set of helpful tools, all pre-configured to work and integrate with almost any combination of Containers and tools you may choose. We should use this workspace container to execute the Laravel migration files.

docker-compose exec workspace bash

  1. Run the Laravel migration files to create all the tables into the MySQL container.

artisan migrate

  1. Open your browser and visit localhost:

http://localhost


Possible Laradock installation errors

This are the main problems (and the solutions) I've found executing the docker-compose up command the first time, when Docker downloads and installs all the containers needed.

  1. Problems with the mysql Docker volume:

Everything works again after deleting the data folder of the mysql Docker volume:

rm ~/.laradock/data/mysql

(This is the path in my macOS machine)

  1. Service aws failed to build:

As pointed here, a GitHub thread of the Laradock project repository. You should:

mkdir aws/ssh_keys/
touch aws/ssh_keys/id_rsa.pub
docker-compose build --no-cache

  1. SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client:

As pointed here, a GitHub thread of the Laradock project repository. You should:

Change MYSQL_VERSION to 5.7 in laradock/.env and, then execute:

docker-compose build --no-cache mysql


Laravel initial setup

After installing Laravel, you may need to configure some permissions. Directories within the storage and the bootstrap/cache directories should be writable by your web server or Laravel will not run.

First, enter your Laradock Workspace:

docker-compose exec workspace bash
chmod -R 777 ./storage ./bootstrap

Set your application key to a random string.

artisan key:generate


Read the API documentation

Read the API documentation through the Swagger Web Interface at:

http://localhost/api/docs


Maildev or Mailtrap email server

If you want to use the "forgot password" feature…

On your local development environment with Laradock:
the email with the link to restore your password will be sent to MailDev (a local mail server for local development). You can easily access the web interface at:

http://localhost:1080/

On the Heroku instance environment: the email with the link to restore your password will be sent to Mailtrap Heroku Add-on (a local mail server for testing purposes). You can easily access the web interface at:

https://heroku.mailtrap.io/inboxes/520364/messages


Run the Tests

The Unitary Tests has been made using PHPUnit.

Assuming that you have all the dependencies installed using Composer, you can run the Unitary Tests by simply executing entering the Docker Workspace and typing the following command in the root directory of the project:

phpunit

The project have some basic unit tests but, the testing environment are not configured properly so, is expected to get all of them throw a Fail o Error message.


Deployment on Heroku


Install the Heroku CLI

First of all, install the Heroku CLI in order to be able to continue with the following steps. To do so, execute the following command in case you are using macOS and have Homebrew installed. In other cases, please read on the Heroku Dev Center the official documentation for installing the command line interface.

brew install heroku/brew/heroku


Initializing a Git repository

Initialize a Git repository in the root of the project if you don't already have one.

git init

Commit any changes you want to deploy into the master branch (this is the one used by Heroku to deploy new changes into his servers).


Creating a Procfile

echo web: vendor/bin/heroku-php-apache2 public/ > Procfile
git add .
git commit -m "Procfile for Heroku"


Creating a new application on Heroku

heroku create [your-app-name]

The string that you uses on the placeholder of [your-app-name] on the command above will be your name on your Heroku Dashboard and also, the sub-domain of the URL provided by Heroku for you application. In the case of this project, the command was executed as following:

heroku create tenejob-laravel-api

and, the resulting URL for the app is:

https://tenejob-laravel-api.herokuapp.com/


Setting a Laravel encryption key

heroku config:set APP_KEY=$(php artisan --no-ansi key:generate --show)

Also, you need to set all the keys/values stored on your .env file but with the appropriate values for your Heroku instance. This project's config variables can be set using the Heroku Dashboard if you login into your app instance at heroku.com.


Pushing to Heroku

git push heroku master


Provision your Heroku instance with a compatible MySQL add-on

Add ClearDB:
heroku addons:create cleardb:ignite

Retrieve the values of your ClearDB setup to be able to connect to your app with the Heroku DB:
heroku config | grep CLEARDB_DATABASE_URL

For example, from this URL:
mysql://b6de34rj38adfad3:a10cd36db@us-cdbr-iron-east-05.cleardb.net/heroku_c40fa7a488382ef?reconnect=true

  • the string between mysql:// and : is your DB_USERNAME i.e b6de34rj38adfad3
  • the string between : and @ is your DB_PASSWORD i.e a10cd36db
  • the string between @ and the next / is your DB_HOST i.e us-cdbr-iron-east-05.cleardb.net
  • the string between / and ? is your DB_DATABASE i.e heroku_c40fa7a488382ef

You should set all this values on your Heroku App Dashboard or using the Heroku CLI.


Run the Laravel migrations

heroku run php artisan migrate


Open your shiny app deployed on Heroku

heroku open


Bibliography

Project development tools

Laravel, a MVC PHP Framework based on Symfony
Laradock, a full PHP development environment for Docker
Docker, operating system level virtualization
Git, a distributed version control system

Heroku

Getting Started on Heroku with PHP
The Heroku CLI
Getting Started with Laravel on Heroku
Configuration and Config Vars
ClearDB Mysql
Rename your Heroku app

How to deploy a Laravel 5 app to Heroku step by step:

About

A Laravel project to demo my skills building a REST compliant API. The entire environment is built on top of Docker.

https://tenejob-laravel-api.herokuapp.com


Languages

Language:PHP 77.9%Language:HTML 21.9%Language:Vue 0.2%