phpsymfonyenumsapi-platform.comphp-8.1

Using Native Enum in Api-Platform / OpenApi


I am learning OpenApi/Swagger API with Api-Platform. I created a new endpoint, that accepts values of an enum as a parameter:

#[ApiResource(
itemOperations: [
    'get_by_name' => [
        'openapi_context' => [
            ....
            'parameters' => [
                [
                    'in' => 'header',
                    'name' => 'X-Server-Region',
                    'schema' => [
                    'type' => 'string',
                    'enum' => ['server1', 'server2'],
                    'example' => 'server1',
                 ],
                 'description' => 'Server to select',
                 'required' => true
             ],
...
)]

However, this is a rather common param and values can be updated frequently (as more servers are added), I'd like to use some kind of template.

So I tried:

<?php

namespace App\Enum;

enum Server: string
{
    case SERVER1 = 'server1';
    case SERVER2 = 'server2';
    ...
}

with

'enum' => [...Server::cases()],

or

'enum' => [Server::class],

and many other forms of that, to no avail.

I tried to understand the concept of components, but could not find a way to use them in Symfony/Api Platform.

How could I reuse an enum at different endpoints?


Solution

  • Enums being fairly new to PHP, they are not yet directly supported by Api-Platform.

    Support will come, but for the time being you'll have to explicitly list each of the cases manually on the configuration.


    While you could also store the list of 'cases' in a constant in a class (you could even do it in the enum itself):

    enum Server : string {
       const CASES = ['server1', 'server2']
       case SERVER1 = 'server1';
       case SERVER2 = 'server2';
    }
    

    And then use that constant directly in annotations or attributes:

    parameters' => [
                    [
                        'in' => 'header',
                        'name' => 'X-Server-Region',
                        'schema' => [
                        'type' => 'string',
                        'enum' => Server::CASES,
                        'example' => 'server1',
                     ],
                     'description' => 'Server to select',
                     'required' => true
                 ],
    

    ... this wouldn't be really using the enum advantages, as you would still need to edit the cases in two places instead of only just the one; and would only be convenient for annotations or attributes. If you used XML or YAML configuration for your API resources, it wouldn't be that great.