Swaggervel (Swagger PHP and Swagger UI in Laravel)

Introduction

The [Swaggervel] "package combines swagger-php and swagger-ui into one Laravel-friendly package" - https://github.com/slampenny/Swaggervel.

I couldn't get the installation working with Laravel 4.1 due to dependency problems but it worked fine upgrading to Laravel 4.2 (see upgrade guide here).

Swagger allows you to create API documentation like this (taken from swagger-ui pet store example here):

Screenshot of Swagger UI

Swagger-php is used for annotating PHP code and creating JSON that can be used by swagger-ui to generate HTML documentation.

Installation

Add the package to composer.json:
"jlapp/swaggervel": "1.0.*@dev"
and do the following (taken from GitHub page):

Add Jlapp\Swaggervel\SwaggervelServiceProvider to your providers array in app/config/app.php above your routes provider (to avoid catch all routes).

Run php artisan vendor:publish to push config files to your app folder.

Running

Access Swagger UI to see your controller changes: http[s]://your-api-endpoint.com/api-docs. You can see the JSON that is generated too: http[s]/your-api-endpoint.com/docs.

You can see your changes on page load if generateAlways is set to true in app/config/packages/jlapp/swaggervel/app.php. In production you will want to turn this option off in your local configuration. If you want to manually generate the documentation then run swagger on your code:

./vendor/bin/swagger app/ -o app/storage/docs/

Controller Annotation

You can get a Swaggervel API call working by adding some annotation to a single controller class. The following example shows how to document two API calls for a fictional "animal API":
use Swagger\Annotations as SWG;

/**
 * @SWG\Resource(
 * 	apiVersion="1.0",
 *	resourcePath="/animal",
 *	description="Animal operations",
 *	produces="['application/json']"
 * )
 */
class AnimalController extends \BaseController {

	/**
	 * @SWG\Api(
	 * 	path="/animals",
	 *      @SWG\Operation(
	 *      	method="GET",
	 *      	summary="Fetch animals"
	 *   	)
	 * )
	 */
	public function index()
	{
		// index code
	}

	/**
	 * @SWG\Api(
	 * 	path="/animal/{animal_id}",
	 *      @SWG\Operation(
	 *      	method="GET",
	 *   		summary="Displays an animal",
	 *		@SWG\Parameter(
	 *			name="animal_id",
	 *			description="id of animal to fetch",
	 *			paramType="path",
	 *      		required=true,
	 *      		allowMultiple=false,
	 *      		type="integer"
	 *      	),
	 *		@SWG\ResponseMessage(code=404, message="Animal not found")
	 * 	)
	 * )
	 */
	public function show()
	{
		// show code
	}
}
Above shows five annotation types: @SWG\Resource, @SWG\Api, @SWG\Operation, @SWG\Parameter and @SWG\ResponseMessage. Make sure you get the hierarchy correct, it should be like this:
- @SWG\Resource
  - @SWG\Api
    - @SWG\Operation
      - @SWG\Parameter
      - @SWG\ResponseMessage

Model Annotation

You can use model annotation to document what an Animal is:
use Swagger\Annotations as SWG;

/**
 * @SWG\Model(
 * 	id="Animal",
 * 	@SWG\Property(name="id", type="integer", required=true),
 * 	@SWG\Property(name="slug", type="string", required=true),
 * 	@SWG\Property(name="name", type="string", required=true),
 * 	@SWG\Property(name="carnivore", type="boolean", required=false),
 * 	@SWG\Property(name="obligate_carnivore", type="boolean", required=false),
 *	...
 *	...
 * )
 */
class Animal extends Eloquent implements AnimalInterface {

	// model implementation
}
Add the type to your controller annotation like this:
/**
 * @SWG\Api(
 * 	path="/animal/{animal_id}",
 *      @SWG\Operation(
 *      	method="GET",
 *   		summary="Displays an animal",
 *		type="Animal",
 *		@SWG\Parameter(
 *			name="animal_id",
 *			description="id of animal to fetch",
 *			paramType="path",
 *      		required=true,
 *      		allowMultiple=false,
 *      		type="integer"
 *      	),
 *		@SWG\ResponseMessage(code=404, message="Animal not found")
 * 	)
 * )
 */
public function show()
{
	// show code
}

This will show a Model link in Swagger UI so API consumers can understand what an Animal looks like.

Learn more about annotations here.

Tips

If you are running swagger from the command-line, ensure you parse both your models and controllers so you can see the models in the UI. I.e. ./vendor/bin/swagger app/ -o app/storage/docs/ not ./vendor/bin/swagger app/models -o app/storage/docs/ and not ./vendor/bin/swagger app/controllers -o app/storage/docs/.

Final notes

I have found that using Swagger is pretty neat because: