Endpoint is representation of a unique url (like a /api/v1/users) and one or multiple operations (HTTP methods)

In our case endpoint is implemented as a controller method.

# Controllers

Create base controller with root path to your api

  • controller must implement Apitte\Core\UI\Controller\IController
namespace App\Api\V1\Controllers;

use Apitte\Core\Annotation\Controller\Path;
use Apitte\Core\UI\Controller\IController;

/**
 * @Path("/api/v1")
 */
abstract class BaseV1Controller implements IController
{
}
1
2
3
4
5
6
7
8
9
10
11

Create an endpoint

  • Controller must have annotation @Path() and be registered as service
  • Method must have annotations @Path() and @Method()
services:
    - App\Api\V1\Controllers\UsersController
1
2
namespace App\Api\V1\Controllers;

use Apitte\Core\Annotation\Controller\Method;
use Apitte\Core\Annotation\Controller\Path;
use Apitte\Core\Http\ApiRequest;
use Apitte\Core\Http\ApiResponse;
use Nette\Utils\Json;

/**
 * @Path("/users")
 */
class UsersController extends BaseV1Controller
{

    /**
     * @Path("/")
     * @Method("GET")
     */
    public function index(ApiRequest $request, ApiResponse $response): ApiResponse
    {
        // This is an endpoint
        //  - its path is /api/v1/users/
        //  - it should be available on address example.com/api/v1/users/

        $response = $response->writeBody(Json::encode([
            [
                'id' => 1,
                'firstName' => 'John',
                'lastName' => 'Doe',
                'emailAddress' => 'john@doe.com',
            ],
            [
                'id' => 2,
                'firstName' => 'Elon',
                'lastName' => 'Musk',
                'emailAddress' => 'elon.musk@spacex.com',
            ],
        ]));

        return $response;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

Tip Use the @Path("/") annotation on a Controller and its method to target the homepage, e.q. example.com/.

# List of annotations / attributes

You can use seamless PHP 8 attributes.

@Id

  • Must consist only of following characters: a-z, A-Z, 0-9, _
  • Not used by Apitte for anything, it may just help you identify, group, etc. your endpoints

@Path

  • See example controllers above
  • Must consist only of following characters: a-z, A-Z, 0-9, -_/
  • The @Path annotation can be used on:
    • abstract controller to define a group path for multiple controllers (e.g. example.com/v1/...)
    • final controller to define a path for that particular controller (e.g. example.com/v1/users)
    • method to define a path for a specific endpoint
  • This hierarchy is then used to build the schema and make routing possible.

@Method

  • Allowed HTTP method for endpoint
  • GET, POST, PUT, OPTION, DELETE, HEAD
  • @Method("GET")
  • @Method({"POST", "PUT"})
  • Defined on method

@Tag

  • Used by OpenApi
  • Could by also used by your custom logic
  • @Tag(name="name")
  • @Tag(name="string", value="string|null")
  • Defined on class and method

Mapping

  • Validate and map data from request and map data to response
  • @RequestParameter, @RequestParameters
  • @RequestBody
  • See mapping chapter for more info.

Negotiations

  • Response transformations
  • @Negotiation, @Negotiations
  • See negotiation chapter for details.

# Automatic controllers registration

It's boring to register each controller one by one as a service. You can make your life easier and use contributte/di (opens new window) and let register all controllers themself.

composer require contributte/di
1

Configure resource extension and profit.

extensions:
    # This must be first extension!
    resource: Contributte\DI\Extension\ResourceExtension
    api: Apitte\Core\DI\ApiExtension

resource:
    resources:
        App\Api\V1\Controllers\:
            # where the classes are located
            paths: [%appDir%/Api/V1/Controllers]
1
2
3
4
5
6
7
8
9
10