Skip to content

MikeO89/AddressBookAPI_TechnicalTest_PHP

Repository files navigation

Propel - Technical Test Instructions

Introduction

This technical assessment is designed to give us an understanding of your capabilities. We aren’t necessarily looking for you to complete the task, but rather that you have solid understanding of the technologies you will be using in the job you are applying for at Propel.

Task Summary

We would like you to build an address book API, with all data stored in a JSON flat file. You need to be able to list, view, add, edit and delete records. As part of the application, you should implement the following:

Object-orientated code

All code should be fully object-orientated and namespaced. Bonus marks for demonstration of dependency injection and/or unit tests.

Programming Language

We don’t prescribe which language you should use; we want you to use what your most familiar with so you can show off your skills.

Build Brief

You should build the app in two stages, using Git for source control. Commit after each step so we can see how the system progressed:

Step 1 – Initial Build

Build the initial app using your favoured programming language. Make sure the user can list, amend and search all records.

Step 2 – Integrate API

Add endpoints to your application for all common functions. These should accept and return JSON. You should write unit tests to test your code, ideally in a TDD manner.

Submission

• Go back to the ‘Invite to complete technical test’ email. • Click on the ‘show questions’ button • A new browser window should open • Paste the link to Github or similar service in the box as directed

If you need any assistance please email [email protected] and someone will get back to you.

Implementation (PHP - v8.1.12)

Architecture

sequenceDiagram
    %% @config(config.json)
    box Create Address Book Entry

    participant Client
    participant API
    participant AddressBook
    participant Database
    participant JSON MySQL MSSQL S3
    end
    autonumber

    Client->>+API: Create Entry
    API->>+Database: database := new(databaseType)
    Database->>+JSON MySQL MSSQL S3: instance := new
    JSON MySQL MSSQL S3-->>-Database: instance
    Database-->>-API: database
    API->>+AddressBook: new(database)
    AddressBook->>+Database: array of AddressBookEntry := readData(mapper)
    Database->>+JSON MySQL MSSQL S3: array of AddressBookEntry := readData(mapper)
    JSON MySQL MSSQL S3-->>-Database: array of AddressBookEntry
    Database-->>-AddressBook: array of AddressBookEntry
    AddressBook-->>-API: database
    API->>+AddressBook: AddressBookEntry := addUpdateEntry(new AddressBookEntry)
    AddressBook->>AddressBook: AddressBookEntry := find([searchCriteria])

    opt if AddressBookEntry does not exist
    AddressBook->>AddressBook: AddressBook := serialise()
    AddressBook->>+Database: submit(AddressBook)
    Database-->>-AddressBook: saved
    end

    AddressBook-->>-API: AddressBookEntry
    API-->>-Client: 201 Created
Loading

Setup Instructions

Apache & PHP Install

  • Download the latest zip for Apache Windows x64 (containing ssl)

  • Extract the contents to C:/ - The folder inside the zip is Apache24, so the extracted structure should be C:/Apache24

  • Add 'C:/Apache24/bin' to the PATH variable

  • Download the latest version of x64 PHP for Windows (Thread Safe)

  • Extract the contents to the zip file name in C:/ and rename the folder to 'php'

  • Make a copy of 'php.ini-production' and rename it to 'php.ini'

  • Open php.ini

    • Ensure allow_url_fopen is set to on
  • Add 'C:/php' to the system PATH variable

  • Open C:/Apache24/conf/httpd.conf

    • Add LoadModule php_module C:/php/php8apache2_4.dll (the DLL file name may change with a new version)

    • Ensure config file has Listen 80 (443 is listened on by default, but SSL is not used for this technical task)

    • Add the directory of php.ini by adding: PHPINIDir "C:/php"

    • Add the below Virtual Hosts to handle the domain routing:

          <VirtualHost *:80>
              ServerAdmin [email protected]
              DocumentRoot "<path_to_www>"
              ServerName propeltech.co.uk
              ServerAlias *
      
              # Redirect / https://propeltech.co.uk/
              RewriteEngine on
      
              RewriteCond %{HTTP_HOST} (.+\.)?propeltech\.com$ [NC]
              RewriteRule (.*) https://%propeltech.co.uk$1 [R]
      
              RewriteCond %{HTTP_HOST} (.+\.)?localhost$ [NC]
              RewriteRule (.*) https://api.propeltech.co.uk/$1 [R]
          </VirtualHost>
      
    • Configure the number of threads (define based on your system architecture):

          <IfModule mpm_winnt_module>
              ThreadsPerChild      20000
              ThreadLimit          20000
              MaxRequestsPerChild    0
          </IfModule>
      
  • Change DocumentRoot to the location of AddressBookAPI_TechnicalTask/www (obtain from Code Commit)

  • Add AddType application/x-httpd-php .php to the mime types, to tell the server to run PHP files as PHP

  • Add the following line as an absolute path Include ../AddressBookAPI_TechnicalTask/conf/<environment>.conf

  • Uncomment 'LoadModule rewrite_module modules/mod_rewrite.so'

  • Uncomment 'LoadModule deflate_module modules/mod_deflate.so'

  • Change AllowOveride None to AllowOveride All inside <Directory ../AddressBookAPI_TechnicalTask/www>:

  • Change Require all denied to Require all granted inside <Directory ../AddressBookAPI_TechnicalTask/www>:

  • There is no need to configure the path / file-extension rewrite as this is configured in the .htaccess file located in '../AddressBookAPI_TechnicalTask/www'

  • If the Apache log files do not show errors, run 'httpd -e info' (add httpd to the PATH system variable to use without navigating to the directory of httpd)

Modify the system hosts file and append the lines below to change the DNS values, resulting in routing being to the local environment

127.0.0.1 api.propeltech.co.uk
127.0.0.1 api-staging.propeltech.co.uk
127.0.0.1 api-uat.propeltech.co.uk
127.0.0.1 propeltech.co.uk

Install Composer

Install UUID

UUID would be installed with composer require ramsey/uuid, but given UUID has previously been installed on the project, following the steps under installing composer will be sufficient.

Install PHPUnit

PHPUnit would be installed with composer require --dev phpunit/phpunit, but given phpunit has previously been installed on the project, following the steps under installing composer will be sufficient.

Fast CGI

Fast CGI speeds up the server by spawning x threads to process pass requests (not process them), removing additional overhead at the time a given request is made.

  • Add ‘C:/Program Files (x86)/Windows Kits/10/bin/10.0.20348.0/x64’ to the system PATH variable.

  • Download mod_fcgid

  • Download APR ysource

  • Extract both archives.

  • Place the contents of apr-1.7.4 in mod_fcgid-2.3.9\modules\fcgid.

  • Using the VS x64 console as administrator, navigate to 'mod_fcgid-2.3.9\modules\fcgid'.

  • Run the following commands:

        set APACHE2_HOME=C:\Apache24
        NMAKE /f "mod_fcgid.mak" CFG="mod_fcgid - Win32 Release"            
    
  • Move file ‘mod_fcgid-2.3.9\modules\fcgid\Release\mod_fcgid.so’ to 'C:\Apache24\modules'

  • Open 'C:/Apache24/conf/httpd.conf'

    • Append LoadModule fcgid_module modules/mod_fcgid.so to the LoadModule section
    • At the bottom of the file append the following:
          <IfModule fcgid_module>
              Include conf/extra/httpd-fcgid.conf
          </IfModule>
      
  • Create a file named ‘C:\Apache24\conf\extra\httpd-fcgid.conf’ and write the following:

        <IfModule fcgid_module>
            FcgidInitialEnv PHP_FCGI_MAX_REQUESTS 0
            FcgidMaxProcesses 1000
            FcgidMaxRequestsPerProcess 1500
            FcgidIOTimeout 40
            FcgidProcessLifeTime 3600
            FcgidMinProcessesPerClass 3
        </IfModule>
    
  • Add the httpd service by running httpd -k install -n "Apache2.4" - the service name can be anything. Run the terminal window with administrative priviledges.

Stress Testing Apache

- The Apache Benchmark tool is useful to stress test the configuration. Open a command line terminal - machine used is irrelevant - and run the following command:
    ```console
        abs -H "Accept-Encoding:gzip,deflate,br" -H "Authorization:<API_KEY>" -n 1000 -m GET https://api.propeltech.co.uk/book
    ```

Unit Testing

Run the tests with vendor/bin/phpunit tests/AddressBookTest.php

Debugging (Visual Studio Code)

  • Install the Visual Studio Code 'PHP Debug' extension.
  • Download the relevant version of xdebug
  • Name the download 'php_xdebug.dll' and place it within your 'C:/php/ext' folder
  • Add the following to your php.ini file:
[XDebug]
zend_extension=xdebug
xdebug.mode = develop,debug,gcstats,profile,trace
xdebug.start_with_request = 1

Set the following Windows environment variable using the CLI:

set XDEBUG_SESSION=1

Postman

A postman collection has been created to showcase/test the implementation - simply import 'AddressBook.postman_collection.json' using Postman and run the relevant requests.

Notes

  • To preview this markdown in Visual Studio Code, hold 'Ctrl', hold 'Shift', and press 'V'.

  • The mermaid diagram will only display with the Visual Studio Code 'Markdown Preview Mermaid Support' plugin installed.

About

PHP technical assessment: Address Book prototype with API

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published