Skip to content

3.4: Add Documentation

Sebastian Schendel edited this page Jun 17, 2023 · 1 revision

Since version 1.3.0 AppApi can generate a simple OpenAPI documentation JSON for you, which is a perfect way to get an overview of all the endpoints that are registered in your api. You can easily give the OpenAPI JSON to your frontend-coworkers or customers that should use the api-endpoints. Or you can even import the JSON into tools like Postman or the Swagger Editor and get a fully functioning api-test environment.

Let us start at AppApi's default documentation generation, and look into ways to customize your endpoint-documentation after that. Without any changes in your api-routes, AppApi will give you a JSON which includes all registered endpoint-paths and methods with minimal boilerplate code to make the file valid for the OpenAPI 3.0.3 specification. I have also included very detailed input-parameter and response documentations for the auth-routes that the module automatically sets up. The various security mechanisms like apiKey, basicAuth (login via header), bearerAuth (JWT access-token) and bearerRefreshAuth (JWT refresh-token) and the default syntax for AppApiException responses are predefined, too. Click on the button "Get OpenAPI JSON" on the Endpoints page to get a detail look at the automatically generated documentation parts.

I have extracted the significant parts of a single api endpoint path, to let you get a feeling for how the OpenAPI path definition works:

{
    "openapi": "3.0.3",
    "info": {
        "title": "AppApi Endpoints",
        "version": "1.0.0"
    },
    "paths": {
        "/auth": {
            "get": {
                "summary": "Get the current user",
                "description": "Get the user from the current session.",
                "tags": [
                    "Authentication"
                ],
                "security": [
                    {
                        "apiKey": []
                    },
                    {
                        "bearerAuth": []
                    }
                ],
                "parameters": [],
                "responses": {
                    "200": {
                        "description": "Successfull operation",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "required": [
                                        "id",
                                        "name",
                                        "loggedIn"
                                    ],
                                    "type": "object",
                                    "properties": {
                                        "id": {
                                            "type": "integer",
                                            "format": "int64",
                                            "example": 42
                                        },
                                        "name": {
                                            "type": "string",
                                            "example": "sebi"
                                        },
                                        "loggedIn": {
                                            "type": "boolean"
                                        },
                                        "nickname": {
                                            "type": "string",
                                            "example": "Sebi"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "default": {
                        "description": "Unexpected error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/AppApiException"
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

The entire object under paths["/auth"].get can be defined on index 5 in the PHP routes definition array. Look at the following PHP definition of that auth-get-route:

<?php
['GET', '', Auth::class, 'currentUser', [], [
	// documentation
	'summary' => 'Get the current user',
	'description' => 'Get the user from the current session.',
	'operationId' => 'getCurrentUser',
	'tags' => ['Authentication'],
	'security' => [
		['apiKey' => []],
		['bearerAuth' => []]
	],
	'parameters' => [],
	'responses' => [
		'200' => [
			'description' => 'Successfull operation',
			'content' => [
				'application/json' => [
					'schema' => [
						'required' => ['id', 'name', 'loggedIn'],
						'type' => 'object',
						'properties' => [
							'id' => [
								'type' => 'integer',
								'format' => 'int64',
								'example' => 42
							],
							'name' => [
								'type' => 'string',
								'example' => 'sebi'
							],
							'loggedIn' => [
								'type' => 'boolean'
							]
						]
					]
				]
			]
		],
		'default' => [
			'description' => 'Unexpected error',
			'content' => [
				'application/json' => [
					'schema' => [
						'$ref' => '#/components/schemas/AppApiException'
					]
				]
			]
		]
	]
]];

As you may realize - it is simply the PHP equivalent to the OpenAPI json. OpenAPI calls that object an "Operation object". You can find more infos about all the possible values here: OpenAPI 3.0.3 - Operation Object.

Let us look at the parts used in our example above.

  • 'summary' represents a short description for the endpoint.
  • 'description' is a longer description, which may consist of multiple sentences or even paragraphs to explain the functionality, if needed.
  • 'operationId' is an optional individual ID, that may be used by some api-tools.
  • 'tags' can be used to group endpoints. If not defined, the tag default will be used
  • 'security' marks the used security mechanisms. AppApi requires you to use the security mechanism apiKey, so that is mandatory. If your application uses single or double JWT authentication, you need to add bearerAuth to this array as well. Api-tools like Postman or the Swagger-Editor will automatically give you inputs for an api-key and an access-token, if these security entries are present.
  • 'params' holds the definition of your input-params. That could be GET-params, a POST-request-body or variable url-path-params. Since the output of the current user needs no input data, this array is empty for this special case.
  • 'responses' is used to demonstrate all possible outcomes of calling this endpoint. In most cases you can simply copy the default part. When an error occurs, the output of our AppApiExceptions will be the same. Use the 200 object to define what are the normal outputs of your endpoint, if no Exception was thrown. There's a big variety of possible data-values, so please look into OpenAPI`s documentation to find out more about that.

I hope you got a good introduction about the big opportunities that the documentation feature of AppApi`s routes provides. More complex OpenAPI features, like a global scheme definition, must be added manually, if needed.


➡️ Continue with 4.0: AppApi-Modules ⬅️ Back to 3.3: Example: Listing Users