ApiDoc is a tool that automatically creates documentation for your RESTful API. It is available for multiple languages, including PHP, Java, C#, JavaScript, Python, Perl, Ruby, Erlang, Elixir and CoffeeScript.
ApiDoc can be easily installed through npm:
npm install apidoc -g
Basic Usage
ApiDoc is run from the command line. It can create documentation out of the box, without any additional configuration needed. To do that, execute the following command:
apidoc -i path/to/myproject/ -o path/to/documentation/
Myproject is the input directory, i.e. the directory where your code is located, while the documentation is the output directory, i.e. the location where the generated documentation will be stored. ApiDoc will scan the input directory and its subdirectories, find all supported files and generate the documentation in form on an HTML page.
Configuration
Filter Files
It is possible to scan only files with specific extensions using the -f parameter. For example, to document PHP and JS files only, the command would look like this:
apidoc -f ".*.php$" -f ".*.js$"
Templates
ApiDoc uses a default HTML page template to display the documentation. However, that template can be changed. To use a custom template, add the following to the apidoc command:
apidoc -t customtemplate/
The default template source can be found here.
General Project Information
General information about the project, such as the title, description and version, can be configured in apidoc.json file in your root directory. This file is optional and would look something like this:
{
"name": "myapp",
"version": "0.1.0",
"description": "REST API for MyAPP",
"title": "MyApp",
"url" : "https://mydomain.com/api/v1"
}
Annotations
Annotations are used to further configure the documentation output. They are added inside the comment blocks above class methods. An example REST method, whose documentation is configured with annotations, would look like this:
/**
* @api {get} /post/:id Fetch a single post
* @apiName GetPost
* @apiGroup Post
*
* @apiParam {Number} id Unique ID of the Post.
*
* @apiSuccess {Object[]} post Object containing post information.
* @apiSuccess {number} post.post_id ID of the post.
* @apiSuccess {String} post.post_title Title of the post.
* @apiSuccess {String} post.post_content Content of the post.
*
* @apiSuccessExample Success-Response:
* HTTP/1.1 200 OK
* {
* "post": {
* "post_id": 156,
* "post_title": "My first blog post"
* "post_content": "This is an example post"
* }
* }
*
* @apiError PostNotFound The id of the Post was not found.
*
* @apiErrorExample Error-Response:
* HTTP/1.1 404 Not Found
* {
* "error": "PostNotFound"
* }
*/
public function getAction($id)
{
$post = $this->getDoctrine()
->getRepository('AppBundle:Post')
->find($id);
if (!$post) {
throw $this->createNotFoundException();
}
return $this->view(['post' => $post])->setStatusCode(200);
}
@api, @apiName and @apiGroup annotations should always be used, while other parameters are optional.
Using ApiDoc with PHP Frameworks
ApiDoc can be used with the most popular PHP frameworks, such as Laravel and Symfony. Although it is mostly the same, the installation and the syntax are slightly different.
Laravel
In Laravel, we will first install the ApiDoc Elixir module:
npm install laravel-elixir-apidoc --save-dev
And then add the following code to the gulpfile.js:
var elixir = require('laravel-elixir');
require('laravel-elixir-apidoc');
elixir(function(mix) {
mix.apidoc();
});
After adding the annotations, run the following command to create the documentation:
gulp apidoc
Symfony
In Symfony, we will use Nelmio ApiDoc bundle, which is installed through Composer:
"nelmio/api-doc-bundle": "2.12.0"
After that, add the following to the $bundles array in app/AppKernel.php:
new NelmioApiDocBundleNelmioApiDocBundle()
A sample get request would look like this:
/**
* @ApiDoc(
* section="Post",
* resource=true,
* description="Fetch a single post",
* requirements={
* {
* "name"="id",
* "dataType"="integer",
* "format"="d+",
* "description"="Post id"
* }
* },
* output={
* "class"="AppBundleEntityPost",
* "groups"={"post", "post-details"}
* },
* statusCodes={
* 200="Success. Returned JSON array is wrapped in 'post' : returned_value array",
* 400={
* "Bad request"
* },
* 404={
* "Not found"
* },
* }
* )
public function getAction($id)
{
$post = $this->getDoctrine()
->getRepository('AppBundle:Post')
->find($id);
if (!$post) {
throw $this->createNotFoundException();
}
return $this->view(['post' => $post])->setStatusCode(200);
}