Skip to content

Lecture 2.6: REST ful APIs

DA edited this page Oct 7, 2019 · 7 revisions

REST API

A REST API or more appropriately, a RESTful API uses the fundamentals of a REST (Representational State Transfer) communication protocol to break down a transaction received through HTTP and translate them into small modules that your application can make sense of and act on.

RESTful APIs take advantage of HTTP methodologies. They use GET to retrieve data. They use POST to create a resource. They use DELETE to delete a resource. They use PUT to update a resource.

In the Routing section, we explained how this framework deeply relies on such a protocol to route a Request to a corresponding Controller action. It is therefore already built-in and ready to receive API calls using the same routes that your application uses.

API in 4 steps

The most effective way to test the API is to use a service like Postman. Postman is a great tool that allows to create GET, POST, PUT and DELETE requests without any extra coding. We will use the example of the book application throughout.

1. API Authorization: API access must be authorized. The purpose of an API is to open up your services for third-parties to use them. There needs to be a way in your RESt-API to provide authorization for access. Caligrafy does this for you in a seamless way. By providing you with the tools to generate API tokens that sign all HTTP requests to your server even if you want your services to be openly accessible to any party.

  • Single API key for public use Caligrafy provides you with an easy way to generate an APP_KEY and an API_KEY from the terminal using Caligrafer. From the terminal, run ./caligrafer.php generatekeys or php caligrafer.php generatekeys. Caligrafer will give you a pair of key/value pairs to put in your .env file.

  • Generate Multiple API keys for distribution If you have an APP_KEY and API_KEY already defined in your .env file or if you created them through Caligrafer, you might need to generate more API_KEY(s) to hand over to third-parties. You can do this with Caligrafer. From the terminal, run ./caligrafer.php generateapikey or php caligrafer.php generateapikey. This will generate a new API_KEY for you to give away.

2. Enabling API Access: In the /application/config/routing/web.php, you will need to activate API access and define the routes. By default the API access is enabled through Auth::activateAPI(). By commenting out the statement, you disable all API accesses.

try {
    // Activate the API access
    Auth::activateAPI();

    Route::get('/books', 'BookController@readAll'); // returns all books in the database books table
    Route::post('/books', 'BookController@create'); // expects a form with all book attributes to create a book record
    Route::put('/books/{id}', 'BookController@update'); // expects a form with all the book attributes to update for book with specified id
    Route::delete('/books/1', 'BookController@remove'); // deletes book with specified id

    Route::run();

} catch(Exception $e) {
  // error handling goes here
}

3.Create a Model: Create a books table in your database and a Book model.

If you need to know more about creating a Model, you can read further about it in the respective section of this documentation

4.Create a Controller:

In order to output a result, whether an HTML page or a JSON output, you need to return a View from the Controller. When you first start your project, you most likely don't have any HTML pages or Pug pages created. You however might want to test your api service. In order to help you achieve that, you can return a view that has a null template name.

use Caligrafy\Controller;

class BookController extends Controller {
    public function readAll()
    {
       $this->associate('Book', 'books'); // define the context
       return view(null, $this->all()); // notice the null 
    }

    public function create()
    {
      $this->associate('Book', 'books'); // define the context
      $parameters = $this->request->parameters(); // get all the parameters posted
      $book = new Book();
      $book->title = isset($parameters['title'])? $parameters['title'] : $book->title;
      $book->author = isset($parameters['author'])? $parameters['author'] : $book->author;
      return view(null, $this->save($book));
    }

    public function update()
    {
      $this->associate('Book', 'books'); // define the context
      $book = $this->find(); // finds the book from id specified in the URI

      $parameters = $this->request->parameters(); // get all the parameters posted
      $book->title = isset($parameters['title'])? $parameters['title'] : $book->title; // take the title only if it is set in the post
      $book->author = isset($parameters['author'])? $parameters['author']: $book->author;
      return view(null, $this->save($book));
      
    }

    public function remove()
    {
      $this->associate('Book', 'books'); // define the context
      $book = $this->find(); // finds the book from id specified in the URI
      return view(null, $this->delete());
    }

}

In the future, when you have Pug template created, you just replace the null with the name of the template. And guess what? this does not impact the output of your api.

If you need to know more about creating a Controller, you can read further about it in the respective section of this documentation

Testing the API

Several ways can be used to test the API. We recommend using Postman as an API client to avoid extra coding.

  • Headers: For all requests through Postman, you need to do the following: In the Headers tab, add an 'Accept' key and give it a value 'application/json'. This instructs the server that the client needs a JSON output.

  • Authorization: For all requests, you need to add an Authorization header: In Postman, you can go to the Authorization tab and select Bearer Token from the Type selector. You will need to enter the API_KEY in the Token field provided.

  • GET and DELETE: For GET and DELETE, you can test them without any additional settings. All you need to do is enter the respective URI for each.

  • POST: For POST you need to provide inputs through the Body of the request. There are different ways to do this in Postman

    • Option 1 - In the Body tab, select form-data: this option allows you to mimic an HTML form that could support both text and files. You need to make sure that all the required inputs for the model are entered appropriately. If your application supports file uploading, then you would probably want to test the API using this option.

      After you add your form-data inputs, verify that in the Headers section, you have another key Content-Type that got added with value either multipart/form-data or application/json. If not, you should add it manually.

    • Option 2 - In the Body tab, select x-www-form-urlencoded: this option allows you to send the entire content as a giant query string. This option could be used if you don't have large inputs (such as files) that need to be transferred to the server. Similarly, you need to make sure that all the required inputs for the model are entered appropriately. If your application supports file uploading, this option will not work.

      After you add your x-www-form-urlencoded inputs, verify that in the Headers section, you have another key Content-Type that got added with value application/x-www-form-urlencoded. If not, you should add it manually.

    • Option 3 - In the Body tab, select raw: this option allows you to send a raw file using the format of your choice. The format could be changed to Text or JSON or XML etc. by clicking on the Text dropdown. Then you could type directly in the body the content you want to send in the desired format.

      After you add your raw inputs in a format, verify that in the Headers section, you have another key Content-Type that got added with value application/json (if the format you chose was JSON).

  • PUT: For PUT, since our framework spoofs a POST method, options 1 and 2 above won't work. Only option 3 could work. If your application supports file uploading, then you should test the API as a POST and add a _method key in the Body that has the value PUT.

Clone this wiki locally