Start Design Your Online Store

Calendar is loading...
- Available
 
- Booked
 
- Pending
Whats App

RESTful API Documentation via Symfony and Angular

Rami AlSalloum

Documenting a RESTful API in Symfony via Swagger version 4.x which is being called officially OpenAPI. 

Swagger: an open source API documentation interface.

What is being used?

  • Skeleton Symfony project version 5.2.6

Create a new Symfony project via composer by typing the following statement in CMD:

composer create-project symfony/website-skeleton my_project_name

How to do that?

Via the NelmioApiDocBundle bundle, which allows us to generate documentation in the OpenAPI (Swagger) format and provides an interactive environment with the APIs.

What bundles are required?

NelmioApiDocBundle

Install via the command

composer require nelmio/api-doc-bundle

Register the bundle

Done via Flex in Symfony 5 and above, also when the version of the nelmio/api-doc-bundle is below 4. 

Register the documentation route

To browse the documentation with Swagger UI, register the following route in config/routes.yaml:

app.swagger_ui:
    path: /doc
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger_ui }

Moreover, to get a Jason format of the documentation, we have to added the following route settings:

app.swagger:
    path: /doc.json
    methods: GET
    defaults: { _controller: nelmio_api_doc.controller.swagger }

NelmioApiDocBundle Configuration file

By default, the file config/packages/nelmio_api_doc.yaml will be generated by Flex. We just have to adapt it to our project.

nelmio_api_doc:
    documentation:
        info:
            title: My App
            description: This is an awesome app!
            version: 1.0.0

    areas:
        path_patterns: # an array of regexps
            - ^/api(?!/doc$)

Documenting an API

Added the API to the documentation:

The default configuration of the file config/packages/nelmio_api_doc.yaml will require us to add the prefix api/ before the route of the API in order to put it in the documentation. However, we can reconfigure that for displaying all the endpoints without the prefix by set the value of the path_patterns as this: ^/[a-z]

Note: we can keep the Symfony annotation beside the OpenAPI annotation, and all together will be used to generate the required documentation.

Documenting the request:

* @OA\RequestBody(
*      description="Creates user and profile at the same time",
*      @OA\JsonContent(
*          @OA\Property(type="string", property="userID"),
*          @OA\Property(type="string", property="password"),
*          @OA\Property(type="string", property="userName"),
*          @OA\Property(type="string", property="email")
*      )
* )

Request Body Object

Describes a single request body. It contains two fields, description, and content. 

  1. Description: may contain a brief description of the request body, or an example. 
  1. Content: refers to the type of the content of the request body. As we see from the provided example, the type of the content of the request body for the endpoint is JsonContent, and to represent that we used the Json Content Object of OpenAPI.

To also represent the fields of the json request we used the Property object.

Documenting the response

We may need to represent the content of the response. For example, to represent a response in Jason format with three fields: status_code, msg, and Data, as the following image shows. And the last field, in return, may contain other Jason data.

* @OA\Response(
*      response=200,
*      description="Returns the new user's role",
*      @OA\JsonContent(
*          @OA\Property(type="string", property="status_code"),
*          @OA\Property(type="string", property="msg"),
*          @OA\Property(type="object", property="Data",
*                  @OA\Property(type="array", property="roles",
*                      @OA\Items(example="user")),
*                  @OA\Property(type="object", property="createdAt")
*          )
*      )
* )

As we can note from annotations, we represent the json content of the response in the same way we did for the content of the request previously. Except we used Items object in order to represent the array property which is called “roles”. We use the Items object as long as the type of the property is of type Array.

Group specific endpoints together

In OpenAPI we use the Tag object to group specific operations together. When we want to list all the APIs that are related to the user profile, for example, under one title, we can add a tag annotation to each one of them as this:

@OA\Tag(name="UserProfile")

The Tag object takes three fields: name, description, and externalDocs, which is of the type External Documentation Object. 

Documenting bearer-authentication API 

Some endpoints require bearer authentication because they depend on the token being sent in the header. So, we have to document the api as it requires a bearer token. In order to do that we have first to define a security scheme in the config/packages/nelmio_api_doc.yaml

We added the following part to the file in the documentation section of the file config/packages/nelmio_api_doc.yaml:

components:
            securitySchemes:
                Bearer:
                    type: http
                    scheme: bearer
                    bearerFormat: JWT
        security:
            - Bearer: []

In OpenAPI 3.0, Bearer authentication is a security scheme with type: http and scheme: bearer. We first need to define the security scheme under components/securitySchemes, then we use the security keyword to apply this scheme to the desired scope – global (as in the example above) or specific operations.

The optional setting bearerFormat specifies how the bearer token is formatted.

In the example above, Bearer authentication is applied globally to the whole APIs. If we need to apply it to just a few operations, add security on the operation level instead of doing this globally:

paths:
  /something:
    get:
      security:
        - bearerAuth: []

However, we could use annotation instead of the previous configuration like this:

@Security(name="Bearer")

Rendering the documentation

Using Angular application:

Displaying the API documentation via a simple Angular project and by reading the response of the route /doc.json and displaying it in an Angular View. That’s done by follow this:

Note: we have to make sure that installed Angular CLI is of version 12 at least.

After creating new angular project by running the command

ng new app_name

Install swagger-ui-dist

npm install swagger-ui-dist --save

Next, we have to include the swagger-ui.css in our project by adding it to the style option in the angular.json besides the required scripts like this:

"styles": [
              "node_modules/swagger-ui-dist/swagger-ui.css",
              "src/styles.css"
            ],
"scripts": [
              "node_modules/swagger-ui-dist/swagger-ui-bundle.js",
              "node_modules/swagger-ui-dist/swagger-ui-standalone-preset.js"
            ]

app.component.ts in src/app of our project will take this code:

import { Component, OnInit } from '@angular/core';

declare const SwaggerUIBundle: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'swagger-ui-dist-angular';

  constructor() { }

  ngOnInit(): void {
    const ui = SwaggerUIBundle({
      dom_id: '#swagger-ui',
      layout: 'BaseLayout',
      presets: [
        SwaggerUIBundle.presets.apis,
        SwaggerUIBundle.SwaggerUIStandalonePreset
      ],
      url: 'http://161.35.29.131/doc.json',
      docExpansion: 'none',
      operationsSorter: 'alpha'
    });
  }
}

url option as we can note takes the URL of OpenAPI documentation in the Jason format which is available at the route /doc.json as we mentioned earlier.
Meanwhile, app.component.html in src/app will just take this line:

<div id="swagger-ui"></div>

Finally, running the Angular server and opening the url of the homepage, in our example is localhost:8000/4200, we can see the documentation presented in a formatted style

References

https://symfony.com/doc/current/bundles/NelmioApiDocBundle/index.html

https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md

https://www.npmjs.com/package/open-swagger-ui

https://stackoverflow.com/questions/44894013/adding-swagger-ui-to-angular-app

Categories : Angular, Blog, Php, Symfony
Tags: , , ,

User Avatar
Rami ( Rami )

There Is No Biography


«

No Comments


Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2021 Yes Soft - All right reserved.
Implemented By Yes Soft Team.