How to create a RESTful API with PHP and the Elementary Framework
Tags: php, elementaryframework, rest, api
Published: 2019-01-11 02:14:53

---
title: How to create a RESTful API with PHP and the Elementary Framework
published: true
description: Want to write a fully RESTful API with PHP? You are on the right place. With this How-To, you will learn to use the Elementary Framework for your API, especially by using his routing module, WaterPipe.
tags: php, ElementaryFramework, REST, API
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ngdldm0fsrhgtq3t44y9.png
series: Elementary Framework
---

## Introduction

With new web technologies, when we want to build a web site we think about front-end frameworks like [React.js](https://reactjs.org/), [AngularJS](https://angularjs.org/), [Vue.js](https://vuejs.org/) and so on... But what happen for the dark side of the website, the back-end?

For a simple website, like a one page portfolio or a landing page, the development of the back-end is not very necessary. But when we want to interact with a database or upload files, this become mandatory.

The problem is when we use front-end web technologies like React.js, we cannot directly interact with any back-end server language (PHP, Python, Ruby, and even Javascript with Node.js, etc...). This is where the [RESTful API model](https://en.wikipedia.org/wiki/Representational_state_transfer) takes place.

With a back-end server implementing the REST software architecture, the only thing you have to do from the front-end is to make an [AJAX](https://en.wikipedia.org/wiki/Ajax_(programming)) request for an URI to your server, passing to it some values as **request** parameters, and waiting for the server **response**.

This is what we will learn with this How-To. We will create a RESTful API server, using the PHP language, and a framework I have built, the [Elementary Framework].

## Prerequisites

Before start, make sure you have:

- **A PHP IDE or editor**: Guys at Microsoft have made an awesome work on [Visual Studio Code](https://code.visualstudio.com/), a free and powerful code editor.
- **Composer**: Composer is a dependencies manager for PHP projects. You can download it at https://getcomposer.org/
- **A RESTful API development environment**: Since we will not create a front-end app in this How-To, we will use instead a RESTful API  development environment. You can check the [Postman project](https://www.getpostman.com/), it's a complete API development environment software, and the one I we will use for our project.

## Part 1 - Preparing the project

We will start by creating our new project. Create a new folder, with the name you want (in this tutorial, the project name will be `php_rest_api`) and open a terminal into it.

Since Elementary Framework modules are composer packages, we will install the module responsible of our API ([WaterPipe]) with composer. In the terminal you have previously opened, type:

```bash
composer init
```

This will initialize an empty composer project. Just follow the initialization process to the end. When the process finish, you can now install [WaterPipe] with:

```bash
composer require elementaryframework/water-pipe
```

And wait the process finish, this will download the source code of the project and install it in your own. When the installation succeed, type again:

```bash
composer dump-autoload -o
```

This will generate an *optimized* autoloader file (useful for production). For a normal autoload file, just omit the `-o` switch.

Now we have installed [WaterPipe], the next step is to create the *entry point* of our API. For our project, it will be a simple `index.php` file. So, create a file named `index.php` and insert into it:

```php
<?php

// Require composer autoload file
require "./vendor/autoload.php";

// Require the main WaterPipe class
use ElementaryFramework\WaterPipe\WaterPipe;

// Create the base pipe
$basePipe = new WaterPipe;

// Run the pipe and serve the API
$basePipe->run();
```

What we are doing ?

- We first require the autoloader file from composer
- We can now require the main class of WaterPipe, using the namespace (this is the magic of the autoloader)
- We create a new instance of WaterPipe into `$basePipe`
- We run the pipe with `$basePipe->run()`

This is the minimal content of our project. If you upload this to your server and open the web page into your browser, you will surely get an error, don't worry, this is because we are running an empty *pipe*, we have to add some *water* to it ;-)

## Part 2 - Thinking our API

Before write an API, we have to know exactly what we want to do, and how it will be done. You have to make this work alone for your project, since you exactly know your needs.

### What we want to do?

Here we have to find API requests we have to write, from analyzing the front-end requirements (user registration, files uploading, database access, etc...).

For example, in this project we will:

- Create an URI used to login the user
- Create an URI used to retrieve a list blog posts
- Create an URI used to retrieve a single blog post
- Create an URI used to access an asset file stored into the server
- Disallow access to all other requests

### How it will be done?

Here we have to find how requests will be executed. Just take a paper and imagine a request sent to your server and how the server handle it, what kind of data have to be sent from the browser, what will be sent back from the server, what resource will be used, etc... This is an important process not only in this case but in the software development generally.

For example, in this project, the */api/login* URI have to receive, with the *POST* method, the *username* and the *password* of the user who want to login, if informations are correct, we can create a *session* with these informations, and then, return a *successful signal* to the client. If informations are incorrect, return an *unsuccessful signal* to the client, followed by an *error message*.

Repeat these steps until you have reviewed all you have to do in your API. If so, you can go ahead and continue to the next part.

## Part 3 - Writing our API

### Receiving requests

The API of [WaterPipe] is designed to be easily understandable. When you are writing your API with it, there are some methods you have to know:

- `get(string $uri, callable $action)` : Which run the specified `$action` when receiving a `GET` request at the given `$uri`
- `post(string $uri, callable $action)` : Which run the specified `$action` when receiving a `POST` request at the given `$uri`
- `put(string $uri, callable $action)` : Which run the specified `$action` when receiving a `PUT` request at the given `$uri`
- `delete(string $uri, callable $action)` : Which run the specified `$action` when receiving a `DELETE` request at the given `$uri`
- `patch(string $uri, callable $action)` : Which run the specified `$action` when receiving a `PATCH` request at the given `$uri`
- `head(string $uri, callable $action)` : Which run the specified `$action` when receiving a `HEAD` request at the given `$uri`
- `request(string $uri, callable $action)` : Which run the specified `$action` when receiving any kind of request at the given `$uri`

So going to more practice! Open our `index.php` file in your code editor/IDE, we are going to write our first request:

```php
<?php

// Require composer autoload file
require "./vendor/autoload.php";

// Require the main WaterPipe class
use ElementaryFramework\WaterPipe\WaterPipe;

// Require the Request class
use ElementaryFramework\WaterPipe\HTTP\Request\Request;
// Require the Response class
use ElementaryFramework\WaterPipe\HTTP\Response\Response;

// Create the base pipe
$basePipe = new WaterPipe;

// Handle any kind of requests made at the root of the pipe
$basePipe->request("/", function (Request $req, Response $res) {
    $res->sendText("Welcome to my API");
});

// Run the pipe and serve the API
$basePipe->run();
```

What we are doing ?

- We require the `Request` class
- We require the `Response` class
- We write a request handler for the `/` URI (the root URI)
- We send the text `Welcome to my API` as the response

Upload this to your server and open your browser, you certainly see the text `Welcome to my API` shown into your browser, you have wrote your first request ! Nothing awesome, I know...

I think you have now some ideas on how to write request handlers with [WaterPipe]. This request was just used for a demonstration, you can now delete it and just leave use statements.

#### Handling a POST request

Now we can go ahead and write our first request defined in the part 2, the login URI:

```php
<?php

// Start a session
session_start();

// Require composer autoload file
require "./vendor/autoload.php";

// Require the main WaterPipe class
use ElementaryFramework\WaterPipe\WaterPipe;

// Require the Request class
use ElementaryFramework\WaterPipe\HTTP\Request\Request;
// Require the Response class
use ElementaryFramework\WaterPipe\HTTP\Response\Response;

// Create the base pipe
$basePipe = new WaterPipe;

// Our login request
$basePipe->post("/api/login", function (Request $req, Response $res) {
    // Get request data sent by the client
    $body = $req->getBody();
    $username = $body["username"];
    $password = $body["password"];

    // Check data
    // Since this How-To will not handle connections to database,
    // We will made a simple comparison here...
    if ($username === $password) {
        // Create the user session
        $_SESSION["username"] = $username;
        // Send a successful signal to the client
        $res->sendJson(array(
            "success" => true
        ));
    } else {
        // Send an unsuccessful signal to the client
        $res->sendJson(array(
            "success" => false,
            "error" => "Username and password mismatch"
        ));
    }
});

// Run the pipe and serve the API
$basePipe->run();
```

What we are doing ?

- We start a session with `session_start()`
- We create our login request with the `POST` method
- We retrieve request body through `$req->getBody()`
- We compare retrieved data for equality (you have to use your own login algorithm here)
    - On comparison success
        - We create the user session
        - We send the successful signal to the client (as a JSON response)
    - On comparison fails
        - We send the unsuccessful signal with the error message to the client (as a JSON response)

Now we are going to test our API. Start you API development environment software, and configure it to test the API we have just wrote. Send some data and see what is returned, when the username and the password sent to the server are equals, you will certainly get a successful signal:

![Successful signal](https://thepracticaldev.s3.amazonaws.com/i/zgnnan8ibi6hggd36lua.png)

And when these informations mismatch, you got an unsuccessful signal:

![Unsuccessful signal](https://thepracticaldev.s3.amazonaws.com/i/lakgh4gew3hm8sy5yre2.png)

#### Handling a GET request

Now we are about to write one of our blog posts requests. We will write the request responsible to return the list of published posts. I think you certainly have some ideas on what we have to do ;-)

For next examples, to do not repeat code, consider that we are writting code snippets just **before** the `$basePipe->run()` instruction:

```php
// Our posts retrieving request
$basePipe->get("/api/posts/get", function (Request $req, Response $res) {
    // Retrieve posts from the database, or any other data storage...
    // Since this How-To will not handle connections to database,
    // We will just return static data here...
    $res->sendJSON(array(
      "success" => true,
      "posts" => array(
        array(
          "title" => "First blog post",
          "description" => "The first public post of this blog",
          "author" => "Nana Axel"
        ),
        array(
          "title" => "Second blog post",
          "description" => "The second public post of this blog",
          "author" => "Nana Axel"
        ),
        array(
          "title" => "Another blog post",
          "description" => "Just another public post of this blog",
          "author" => "Nana Axel"
        )
      )
    ));
});
```

Simple I know, but the logic is here, you just have to retrieve the list of blog posts somewhere, send the list as a JSON object to the client, and parse it with your front-end framework to display it into your web page.

Now we will made something more excitant, we will retrieve data for a single post:

```php
// Our single post retrieving request
$basePipe->get("/api/posts/get/:id", function (Request $req, Response $res) {
    // Get the id parameter from the URI
    $params = $req->uri->getParams();
    $postId = intval($params["id"]);

    // Retrieve post from the database, or any other data storage...
    // Since this How-To will not handle connections to database,
    // We will just return static data here...
    $post = array();
    $success = true;

    switch ($postId) {
      case 1:
        $post = array(
          "title" => "First blog post",
          "description" => "The first public post of this blog",
          "content" => "This first post is not very excitant, just a way for me to say Hello, World !",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:01",
          "category" => null
        );
        break;

      case 2:
        $post = array(
          "title" => "Second blog post",
          "description" => "The second public post of this blog",
          "content" => "I love C#, Microsoft guys have built an awesome language! Now I'm developing a game engine with it. It will support all platforms and allow user to also make game scripts with Lua and Javascript :-D",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:05",
          "category" => "Dev"
        );
        break;

      case 3:
        $post = array(
          "title" => "Another blog post",
          "description" => "Another public post of this blog",
          "content" => "React.js or AngularJS? Who is the best? Just leave your opinion as comment ;-)",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:07",
          "category" => "Poll"
        );
        break;

      default:
        $success = false;
        break;
    }

    // Send the retrieved post
    $res->sendJSON(array(
      "success" => $success,
      "post" => $post
    ));
});
```

Have you seen how we have got the `id` of the post to retrieve? Now, using your API development environment software, try to access to `/api/posts/get/1` for example and see the result, it is the first post which is returned!

This is the way [WaterPipe] uses to get values from the request URI. You are able to use an infinite number of parameters, [WaterPipe] will just check if a request URI matches with the given one, and will automatically parse this URI to retrieve parameters value.

Now going to a more complex request, we want to send an image to the client. Reading this, some people will say:

> Why a request like that? We can just use the URL to the file!

Some times, it is not possible... Due to the project architecture, or when it is necessary to do not let the user know how files are structured in your server.

```php
// Our image retrieving request
$basePipe->get("/assets/images/(.+)", function (Request $req, Response $res) {
    // Retrieve the path to the image from the request
    $params = $req->uri->getParams();
    $path = $params[0];

    // Just send the image file from our secret folder
    $res->sendFile("/path/to/our/secret/assets/folder/images/{$path}");
});
```

Hell yeah! [WaterPipe] have a full support of regex-based requests! The only difference with the previous example is when using named parameters in requests, the parameter value is accessed from the request URI with his name (`$params["id"]`). And when using regex-based parameters in request, the parameter value is accessed from the request URI with his position in the URI (`$params[0]`).

#### Hacking requests

It is possible to combine named and regex-based parameters. Even in this case, the previous rule apply.

```php
$basePipe->get("/assets/:type/(.+)", function (Request $req, Response $res) {
    // Retrieving parameters from the request
    $params = $req->uri->getParams();
    $type = $params["type"];
    $path = $params[1]; // Position 1 because the parameter :type occupy the position 0

    // Just send the file from our secret folder
    $res->sendFile("/path/to/our/secret/assets/folder/{$type}/{$path}");
});
```

To handle request like `/path/of/request?param1=value1&param2=value2`, you don't have to explicitly specify GET parameters, and you dont have to use regex. Just create a request handler with the `/path/of/request` URI, and retrieve GET parameters into it:

```php
$basePipe->get("/path/of/request", function (Request $req, Response $res) {
    // Retrieving GET parameters from the request
    $params = $req->getParams();
    $param1 = $params["param1"];
    $param2 = $params["param2"];

    $res->sendText("param1={$param1}&param2={$param2}");
});
```

GET parameters are retrieved with the `getParams()` method of the `Request` class. This is totally different from the `getParams()` method of the `RequestUri` class which returns URI parameters.

### Sending responses

With the previous set of examples, we have used some shortcut methods to directly send a response in a predefined format. All shortcut methods are:

- `sendHTML(string $html, int $status = 200)`: Used to send an HTML response.
- `sendJSONString(string $json, int $status = 200)`: Used to send a JSON response.
- `sendJSON(array $json, int $status = 200)`: Used to send a JSON response.
- `sendText(string $text, int $status = 200)`: Used to send a plain text response.
- `sendFile(string $path, int $status = 200, string $mime = null)`: Used to send a file content as a response, can be an image, a css/js file, an HTML file, etc...

When you want to have the full power on the server response, you have to configure the response yourself.

To let you see how you can achieve this, we will send the successful signal to the client with *raw* methods.

The first step is to define the header of the response:

```php
// Create a new response header
$header = new ResponseHeader();

// Define the response header
$res->setHeader($header);
```

Since we want to send a JSON response, we have to define the `Content-Type` header value to `application/json`. If you don't know what we are talking about, I suggest you to read about [HTTP headers](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields) and [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types).

```php
// Create a new response header
$header = new ResponseHeader();
// Define header values
$header->setContentType("application/json");

// Define the response header
$res->setHeader($header);
```

The second step is to define the [response status](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status).

```php
// Create a new response header
$header = new ResponseHeader();
// Define header values
$header->setContentType("application/json");

// Create a new response status
$status = new ResponseStatus(ResponseStatus::OkCode);

$res
  ->setHeader($header) // Define the response header
  ->setStatus($status) // Define the response status
  ;
```

The last step is to define the response body.

```php
// Create a new response header
$header = new ResponseHeader();
// Define header values
$header->setContentType("application/json");

// Create a new response status
$status = new ResponseStatus(ResponseStatus::OkCode);

// Build the response body
$body = json_encode(array(
  "success" => true
));

$res
  ->setHeader($header) // Define the response header
  ->setStatus($status) // Define the response status
  ->setBody($body) // Define the response body as string
  ;
```

When you have finished to setup your response, just send it to the client.

```php
// Create a new response header
$header = new ResponseHeader();
// Define header values
$header->setContentType("application/json");

// Create a new response status
$status = new ResponseStatus(ResponseStatus::OkCode);

// Build the response body
$body = json_encode(array(
  "success" => true
));

$res
  ->setHeader($header) // Define the response header
  ->setStatus($status) // Define the response status
  ->setBody($body) // Define the response body as string
  ->send() // Send the response to the client and close
  ;
```

#### Manually send response parts

With WaterPipe, you are able to send manually response parts (headers and body) by using methods :
- `sendHeaders()` to send headers defined by `setHeaders(ResponseHeader)` ;
- `sendBody()` to send the response body defined by `setBody(string)` ;
- `close()` to ensure that your response is closed after everything is sent.

```php
// Define your headers using $res->setHeaders($headers) according to the request...

// Send the response headers first
$res->sendHeaders();

// Compute the response body (read database, file, custom content, etc...)

// Define the response body using $res->setBody($body)

// Send the response body
$res->sendBody();

// You can redefine the body and send it mutiple times in the same response!

// Doing some shutdown process...

// Close the response
$res->close();

// Everything after a $res->close() call will not be executed!
```

### Handling common HTTP errors

It's common that an user fall into a 404 error, or your server have some troubles and return a 500 error. [WaterPipe] allow you to easily handle these errors, for example we will disallow access to all other requests to our server.

```php
$basePipe->error(ResponseStatus::NotFoundCode, function (Request $req, Response $res) {
    // Just send a forbidden response
    $res->sendText("Forbidden.", ResponseStatus::ForbiddenCode);
});
```

What we are doing ?

- We create a request handler for the 404 HTTP error
- We send back to the client a 403 HTTP error (Forbidden error)

In other words we are transforming all possible 404 errors from our API to a 403 error.

Now you know all the **basics** to build your API with [WaterPipe]. If you are interested, just continue to play with it, or browse the source code to learn more.

## Part 3 - Some advanced tips

### Using sub-pipes

For now, our `index.php` file look at this:

```php
<?php

// Start a session
session_start();

// Require composer autoload file
require "./vendor/autoload.php";

// Require the main WaterPipe class
use ElementaryFramework\WaterPipe\WaterPipe;

// Require the Request class
use ElementaryFramework\WaterPipe\HTTP\Request\Request;
// Require the Response class
use ElementaryFramework\WaterPipe\HTTP\Response\Response;
// Require the ResponseStatus class
use ElementaryFramework\WaterPipe\HTTP\Response\ResponseStatus;

// Create the base pipe
$basePipe = new WaterPipe;

// Our login request
$basePipe->post("/api/login", function (Request $req, Response $res) {
    // Get request data sent by the client
    $body = $req->getBody();
    $username = $body["username"];
    $password = $body["password"];

    // Check data
    // Since this How-To will not handle connections to database,
    // We will made a simple comparison here...
    if ($username === $password) {
        // Create the user session
        $_SESSION["username"] = $username;
        // Send a successful signal to the client
        $res->sendJson(array(
            "success" => true
        ));
    } else {
        // Send an unsuccessful signal to the client
        $res->sendJson(array(
            "success" => false,
            "error" => "Username and password mismatch"
        ));
    }
});

// Our posts retrieving request
$basePipe->get("/api/posts/get", function (Request $req, Response $res) {
    // Retrieve posts from the database, or any other data storage...
    // Since this How-To will not handle connections to database,
    // We will just return static data here...
    $res->sendJSON(array(
      "success" => true,
      "posts" => array(
        array(
          "title" => "First blog post",
          "description" => "The first public post of this blog",
          "author" => "Nana Axel"
        ),
        array(
          "title" => "Second blog post",
          "description" => "The second public post of this blog",
          "author" => "Nana Axel"
        ),
        array(
          "title" => "Another blog post",
          "description" => "Just another public post of this blog",
          "author" => "Nana Axel"
        )
      )
    ));
});

// Our single post retrieving request
$basePipe->get("/api/posts/get/:id", function (Request $req, Response $res) {
    // Get the id parameter from the URI
    $params = $req->uri->getParams();
    $postId = intval($params["id"]);

    // Retrieve post from the database, or any other data storage...
    // Since this How-To will not handle connections to database,
    // We will just return static data here...
    $post = array();
    $success = true;

    switch ($postId) {
      case 1:
        $post = array(
          "title" => "First blog post",
          "description" => "The first public post of this blog",
          "content" => "This first post is not very excitant, just a way for me to say Hello, World !",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:01",
          "category" => null
        );
        break;

      case 2:
        $post = array(
          "title" => "Second blog post",
          "description" => "The second public post of this blog",
          "content" => "I love C#, Microsoft guys have built an awesome language! Now I'm developing a game engine with it. It will support all platforms and allow user to also make game scripts with Lua and Javascript :-D",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:05",
          "category" => "Dev"
        );
        break;

      case 3:
        $post = array(
          "title" => "Another blog post",
          "description" => "Another public post of this blog",
          "content" => "React.js or AngularJS? Who is the best? Just leave your opinion as comment ;-)",
          "author" => "Nana Axel",
          "published_date" => "01/10/2019 06:07",
          "category" => "Poll"
        );
        break;

      default:
        $success = false;
        break;
    }

    // Send the retrieved post
    $res->sendJSON(array(
      "success" => $success,
      "post" => $post
    ));
});

$basePipe->get("/assets/:type/(.+)", function (Request $req, Response $res) {
    // Retrieving parameters from the request
    $params = $req->uri->getParams();
    $type = $params["type"];
    $path = $params[1]; // Position 1 because the parameter :type occupy the position 0

    // Just send the file from our secret folder
    $res->sendFile("/path/to/our/secret/assets/folder/{$type}/{$path}");
});

$basePipe->error(ResponseStatus::NotFoundCode, function (Request $req, Response $res) {
    // Just send a forbidden response
    $res->sendText("Forbidden.", ResponseStatus::ForbiddenCode);
});

// Run the pipe and serve the API
$basePipe->run();
```

Imagine that in the next ages of our project we want to change our URI, replacing `/api/**` to `/backend/**`. With our current file, we have to replace `/api/**` at each requests, I know it will be not too difficult, but imagine if you have much more requests.

It's for these cases (and much more others) that *sub-pipe* becomes important. It allow you to run an entire pipe within a single base URI. Now let us edit our file to implement a sub-pipe for our api:

```php
<?php

// Start a session
session_start();

// Require composer autoload file
require "./vendor/autoload.php";

// Require the main WaterPipe class
use ElementaryFramework\WaterPipe\WaterPipe;

// Require the Request class
use ElementaryFramework\WaterPipe\HTTP\Request\Request;
// Require the Response class
use ElementaryFramework\WaterPipe\HTTP\Response\Response;
// Require the ResponseStatus class
use ElementaryFramework\WaterPipe\HTTP\Response\ResponseStatus;

// Create the base pipe
$basePipe = new WaterPipe;

// Create the sub-pipe for requests starting with /api/
$apiPipe = new WaterPipe;

// Our login request
$apiPipe->post("/login", function (Request $req, Response $res) {
  // Request execution...
});

// Our posts retrieving request
$apiPipe->get("/posts/get", function (Request $req, Response $res) {
  // Request execution...
});

// Our single post retrieving request
$apiPipe->get("/posts/get/:id", function (Request $req, Response $res) {
  // Request execution...
});

// Add the API sub-pipe to the base pipe
$basePipe->pipe("/api", $apiPipe);

$basePipe->get("/assets/:type/(.+)", function (Request $req, Response $res) {
  // Request execution...
});

$basePipe->error(ResponseStatus::NotFoundCode, function (Request $req, Response $res) {
  // Request execution...
});

// Run the pipe and serve the API
$basePipe->run();
```

To append a sub-pipe to the root pipe, we use the `pipe(string $baseUri, WaterPipe $pipe)` method from the `WaterPipe` class. This method will tell to the root pipe to run the given sub-pipe requests when and only when the client request starts with the given base URI.

This is helpful when your file is growing, and you want to separate your api within files, like `api.users.php`, `api.posts.php`, `api.assets.php`, etc... and merge all these files into `index.php`.

> Sub-pipes can also contains other sub-pipes, and so on... 

### Using middlewares

Now we want to allow access to our API only for connected users, and when a connected user send a request, we want to add into the response a custom HTTP header, which will hold the username. Instead of editing all request handlers to check if the user is connected and hack the response header, we can create a `Middleware`, to execute a specific action **before** the request is executed, and another **before** the response is sent.

```php
class ApiMiddleware extends Middleware
{
    public function beforeExecute(Request &$request)
    {
        // If the session doesn't exists and we are not executing the login request
        if (!isset($_SESSION["username"]) && !$request->uri->is("/api/login")) {
            // Just send a forbidden response
            (new Response)->sendText("Forbidden", ResponseStatus::ForbiddenCode);
        }
    }

    public function beforeSend(Response &$response)
    {
        // If the session exists
        if (isset($_SESSION["username"])) {
            $header = $response->getHeader();
            $header->setField("X-Username", $_SESSION["username"]);
            $response->setHeader($header);
            // DO NOT send the response here, except if you have to change the response to be sent (send an error instead for example)
        }
    }
}
```

And then use it into our base pipe.

```php
$basePipe->use(new ApiMiddleware);
```

## Part 4 - Deploy it!

Since when used, WaterPipe handle all your incoming requests, it's important to configure your HTTP server to redirect all (or some of) these requests to the root pipe of your project (in this case, `index.php`).

### Apache

For Apache, you have to edit the `.htaccess` file located in the root of your app, and add these lines:

```apache
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
```

This will send all requests to the `index.php` file (you can replace it with any other file which contains your root pipe).

### NGiNX

Configure NGiNX is pretty easy, you just have to add (or update) the `location /` command of your `server` block. It have to look like:

```nginx
location / {
    try_files $uri $uri/ /index.php?$args;
}
```

This will say to NGiNX to redirect all non existing paths to the `index.php` file (you can replace it with any other file which contains your root pipe).

If you want to redirect all paths without distinction, you have to do:


```nginx
location / {
    try_files /index.php?$args;
}
```

## Conclusion

With this article, we have learn **How to build a RESTful API server using PHP and the Elementary Framework**. We have seen steps by steps, the basics and some advanced tips, on how to use **[WaterPipe]**, the part of the Elementary Framework responsible of handling requests and sending responses. With what we have done, you surely know how to use this package to create more than a RESTful API, but also URL routing frameworks for your projects and more!

Thank you for reading this article to the end. I'm open to any questions, suggestions, and - constructive - critics about this article, and my framework, just post a comment! Sorry if you search for an API documentation of this framework, there is no one for now, but I'm actively working on this. Also, any contribution is kindly appreciated, just open an issue, or more, a pull request!

## What next?

- Browse the [WaterPipe] source code on GitHub - and give a star if you like it - ;
- Checkout other [Elementary Framework] modules

[WaterPipe]: <https://github.com/ElementaryFramework/WaterPipe>
[Elementary Framework]: https://github.com/ElementaryFramework

{% github ElementaryFramework/WaterPipe %}