Swagger

A swagger egy végpontokat dokumentáló és a működő végpontokat meghívni tudó eszköz. Pár egyszerű példa következik Symfony-hoz és Laravel-hez.

Az alkalmazásunkban fut és egy külön oldalra gyűjti össze a controllerek felé írt annotációkban megfogalmazott végpont definíciókat. Ezeket beolvasva áll össze a swagger dokumentáció.

Symfony-hoz (4.4) használhatjuk a nelmio/api-doc-bundle -t. Ami egyébként a zircote/swagger-php -re épít.
 
# composer require nelmio/api-doc-bundle

Symfony-ban még bekell állítani a config/routes/nelmio_api_doc.yml-ben az ui útvonalát, amennyiben szeretnénk át állítani pl így:
 
# Expose your documentation as JSON swagger compliant
app.swagger:
    path: /api/doc.json
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger }

# Requires the Asset component and the Twig bundle
# $ composer require twig asset
app.swagger_ui:
    path: /public/apd
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger_ui }


A config/packages/nelmio_api_doc.yaml -fájlban pedig kitölthetjük a nevét verziót számát stb és az authentikációt is itt állíthatjuk be:
 
nelmio_api_doc:
    documentation:
        info:
            title: Working Schedule
            description: Working Schedule Backend in Symfony!
            version: 1.0.0
        securityDefinitions:
            Bearer:
                type: oauth2
                description: provides a password flow access_token
                flow: password
                tokenUrl: /oauth/v2/token
                name: Authorization
        security:
             - Bearer: []
    areas: # to filter documented areas
        path_patterns:
            - ^/api(?!/doc$) # Accepts routes under /api except /api/doc

A kontrollerekben importáljuk be a swaggert:
 
use Swagger\Annotations as SWG;

Példa egy get action-re egy controller-ben:
 
  /**
     * @SWG\Get(
     *        path="/api/settings/{locationId}",
     *        tags={"Settings"},
     *        operationId="listSettings",
     *        summary="List settings entry",
     *      @SWG\Response (
     *          response=200,
     *          description="Success response",
     *          @SWG\Schema (
     *               @SWG\Property(
     *                    property="id",
     *                    type="integer",
     *               ),
     *               @SWG\Property(
     *                    property="name",
     *                    type="string",
     *               ),
     *               @SWG\Property(
     *                    property="value",
     *                    type="string",
     *               ),
     *               @SWG\Property(
     *                    property="description",
     *                    type="string",
     *               ),
     *               @SWG\Property(
     *                    property="locationId",
     *                    type="integer",
     *               ),
     *          ),
     *      )
     *    )
     *
     * @Rest\Get("/api/settings/{locationId}")
     *
     * @return Response
     */
    public function getAction($locationId = NULL)

Hozzáadás (itt én egy base64-el encode-olt tömböt adtam át), de értelemszerűen, több @SWG\Parameter -t kell írni, ha nem így egyben adtuk át:
 
    /**
     * @SWG\Post(
     *        path="/api/settings/add/{locationId}",
     *        tags={"Settings"},
     *        operationId="createSettings",
     *        summary="Create new settings entry",
     *      @SWG\Response (
     *          response=200,
     *          description="Success response",
     *      ),
     *      @SWG\Parameter(
     *         name="body",
     *         in="body",
     *         description="Base64 encode object example: xxx",
     *         required=true,
     *         @SWG\Schema(
     *              @SWG\Property(property="data", type="string"),
     *         )
     *      )
     *    )
     *
     * @Rest\Post("/api/settings/add/{locationId}")
     *
     */
    public function addAction(Request $request, $locationId = NULL)
    {

A többi példa ugyanez lenne, csak PUT-al és DELETE-vel. Lehet törölni kell a cache-t a symfony-ban, hogy az első swagger dokumentum megjelenjen a böngészőben.



Laravelhez pedig a darkaonline/l5-swagger-t.
 
# composer require darkaonline/l5-swagger

Laravel-ben az app/Http/Controllers/Controller.php-ban kell beállítanunk a swagger beállításait, beállíthatunk több szervert is:
    /**
     * @OA\Info(
     *      version="1.0.0",
     *      title="L5 OpenApi",
     *      description="L5 Swagger OpenApi description",
     *      @OA\Contact(
     *          email="teszt@pelda.com"
     *      ),
     *     @OA\License(
     *         name="Apache 2.0",
     *         url="http://www.apache.org/licenses/LICENSE-2.0.html"
     *     ),
     * ),
     * @OA\Server(
     *         description="Base url local",
     *         url="http://teszt-app.local/",
     * ),
     * @OA\Server(
     *         description="Base url other server",
     *         url="http://192.168.1.2:8000/",
     * ),
     *
     */

Példa egy get action-re egy controller-ben:
 
    /**
     * @OA\Get(
     *      path="/api/city",
     *      operationId="getCityList",
     *      tags={"City"},
     *      summary="Get list of city",
     *      description="Returns list of city",
     *      @OA\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *       @OA\Response(response=400, description="Bad request"),
     *       security={
     *           {"api_key_security_example": {}}
     *       },
     *       security={{"bearerAuth":{}}}
     *     )
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {

Hozzáadás (itt nincs base64 encodeolva az adat):
 
   /**
     * * @OA\Post(
     *      path="/api/city/store",
     *      operationId="storeCity",
     *      tags={"City"},
     *      summary="Add new city",
     *      description="",
     *      @OA\Response(
     *          response=200,
     *          description="successful operation"
     *       ),
     *      @OA\Parameter(
     *         name="name",
     *         in="query",
     *         description="",
     *         required=true,
     *         @OA\Schema(
     *           type="string",
     *         ),
     *       ),
     *     @OA\Parameter(
     *         name="post_code",
     *         in="query",
     *         description="",
     *         required=true,
     *         @OA\Schema(
     *           type="string",
     *         ),
     *       ),
     *       @OA\Response(response=400, description="Bad request"),
     *       security={{"bearerAuth":{}}}
     *     )
     *
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {

A többi példa ugyanez lenne, csak PUT-al és DELETE-vel.

Generáljunk json-t:
 
# php artisan l5-swagger:generate

A böngészőben egy példa:



Online swagger editor:
https://editor.swagger.io/

Olvasnivaló:
https://en.wikipedia.org/wiki/Swagger_(software)
https://en.wikipedia.org/wiki/OpenAPI_Specification
https://packagist.org/packages/nelmio/api-doc-bundle
https://packagist.org/packages/zircote/swagger-php
https://packagist.org/packages/darkaonline/l5-swagger
https://symfony.com/doc/current/bundles/NelmioApiDocBundle/index.html
2019.09.02.