drew.d.lenhart

programming, software, technology, anything on my mind...

st-slim3-skeleton & Swagger

2018/08/24

st-slim3-skeleton

I use Slim 3 Framework for many projects personally and professionally. Sometimes having a quick skeleton with the dependencies you use quite frequently is beneficial. Hence making this package. Wether you need to make a quick Restful API, MVC application, or a small web site, this can get you up an running. I originally used HelloSlim3 as a boilerplate for quite a few projects, but ended up swapping out a lot of the dependencies. This project is largely based on HelloSlim3 package.

View on GitHub


Here are some of the st-slim3-skeleton features...

-Eloquent ORM integration
-Bootstrap integration
-Twig example
-Basic controller example
-Basic model example
-Swagger example
-SQLite example


Fun with Swagger


The Swagger integration was the most challenging I think. There wasn't a whole lot of documents out there for Swagger & Slim until I stumbled on a Swagger article for Laravel Framework. After reading this, it was quite easy to pick up.

You absolutely need the zircote/swagger-php package or none of this would not be possible.

composer require zircote/swagger-php

Next we need set up a new route that scans the Controller folder of this project. I think this is the downside of the project or I am totally missing something. You are able to scan the directory for the annotations, it does not automatically scan and build everything from your code.


$app->get('/v1/docs', function ($request, $response, $args) {
    $dir = __DIR__ . '/../Controller'; // Scan Controller folder
    $swagger = \Swagger\scan([$dir]);
    $response->write($swagger);
    $response = $response->withHeader('Content-Type', 'application/json');
    return $response;
});

What we did here was make a new url, e.g. http://localhost:8000/vi/docs and returns JSON, everything we need for the Swagger UI component! Hold on to this for later.


The st-slim3-skeleton package makes use of extending AbstractController, so I put the base information here:

/src/Controller/AbstractController.php

/**
 * Class AbstractController
 *
 * @package App\Http\Controllers
 *
 * @SWG\Swagger(
 *     basePath="",
 *     host="localhost:8000",
 *     schemes={"http"},
 *     @SWG\Info(
 *         version="1.0.0.0",
 *         title="Sample Application",
 *         @SWG\Contact(name="Drew D. Lenhart", url="https://drewlenhart.com"),
 *     )
 * )
 */
class AbstractController
{}

Add annotations to one of the API routes ( see github project ).

/src/Controller/ApiController.php

public function example(Request $request, Response $response, $args)
{
  /**
   * Query database table
   *
   * @return Response
   *
   * @SWG\Get(
   *     path="/api/sample",
   *     description="Returns entries in table.",
   *     produces={"application/json"},
   *     tags={"Sample"},
   *     @SWG\Response(
   *         response=200,
   *         description="OK"
   *     ),
   *     @SWG\Response(
   *         response=401,
   *         description="Unauthorized action.",
   *     )
   * )
   */
    $sample = new Sample;
    $sample = Sample::all();
    $response->write($sample);
    $response = $response->withHeader('Content-Type', 'application/json');
    return $response;
}

Remember the route set up earlier ( /v1/docs )? We are basically setting up the annotations for the scanner to read and build JSON. Open up this url in a browser. If everything is done right, you should see valid JSON. If there is an error, or something is off, Swagger UI will not be unable to build correctly. Make sure your annotations are correct and formatted correctly.



Example POST annotation

public function examplePost(Request $request, Response $response, $args)
{
  /**
   * Some description here
   * @SWG\Post(
   *     path="/api/samplePost",
   *     description="Sample Post",
   *     operationId="",
   *     produces={"application/json"},
   *     tags={"Sample"},
   *      @SWG\Parameter(
   *          name="body",
   *          in="body",
   *          default="{}",
   *          description="blah blah blah",
   *          required=true,
   *          @SWG\Schema(
   *             @SWG\Property(property="foo", type="string", example="1234"),
   *             @SWG\Property(property="bar", type="string", example="5678")
   *             )
   *      ),
   *
   *     @SWG\Response(
   *         response=200,
   *         description="OK"
   *     ),
   *     @SWG\Response(
   *         response=422,
   *         description="Unprocessable Entity"
   *     )
   * )
   */
}

Above is example annotations for a POST. This lets you get more granular in what you can display on Swagger UI.


If everything is up and working. It's time for the Swagger UI. I've already included it in this project and is included the /public/swagger folder. You don't need to put it here, it can live wherever you want.

Swagger UI
Download and copy the contents of the "dist" folder.

Lastly, update 'index.html' of the Swagger UI code to point to your JSON output ( e.g. http://localhost:8000/v1/docs ). You should be able to visit the Swagger url:

Yay!


I suggest browsing the examples in zircote/swagger-php!

I'm still adding and fixing the skeleton project as I go!

-drew