-
-
Notifications
You must be signed in to change notification settings - Fork 874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[3.4] Improving handling of BackedEnums with ApiResource class attributes #6298
Comments
Sorry, maybe off-topic, but since you touched on the entire history of implementing Enum support in the Api Platform, I decided to mention it Working with Symfony + ApiPlatform (GraphQL) + FrankenPHP I had this strange problem To fix the issue I had to use unique Enum names
I tried using aliases (like Could this have something to do with ApiPlatform and the current implementation of BackedEnum in GraphQL? |
I disagree it should be IRIs, On graphQl we can also add: #6185 which isn't that wrong as maybe that backed enum is more about keys then values? |
Easy. I had incorrectly interpreted/assumed parts of what you explained in #6288 (comment) while trying to mentally reduce it down to the base parts. |
I presume this is also invalid then? |
From my point of view indeed, to use an Enum one should do:
(based on https://schema.org/VideoGame) API Platform's focuses on hypermedia formats, not sure that we really want to set up rules for plain JSON ( |
To be sure I understand correctly, these would roughly be the PHP classes that your example's implementation would have? #[ApiResource]
class VideoGame
{
public GamePlayMode $playMode;
}
#[ApiResource]
enum GamePlayMode: string
{
case CoOp = 'co_op';
case MultiPlayer = 'multi_player';
case SinglePlayer = 'single_player';
} |
I couldn't agree more. 👍 Honestly, I am just endlessly getting confused by what an PHP enum represents in terms of an API response. So my comments are probably inconsistent as a result. 🌞 An ongoing point of confusion for me is enum Enum: case ENGLISH = 'en'; JSON-(LD|API|HAL):
GraphQL
We know that is due to how Simply, should the API output of a property value of a (non-resource) enum typed property equal a) the PHP enums |
From what I understand from https://www.php.net/manual/fr/language.enumerations.backed.php, Backed enums wants their representation into databases or text as a string (or int). I suggest that we follow that and use values. Regular enums can't be serialized from what I read:
Wouldn't a patch on |
tl;dr: it looks like the
Maybe, but is the They also seem to be following the approach used in the reference implementation, and they have used that approach since "initial commit" in 2015 (v0.1). Digging in, I went back to the PHP RFC: Enumerations and this piqued my curiosity:
If I understand the author's point correctly, the To visualize, the RFC gives this example: enum Foo {
case Bar;
}
enum Baz: int {
case Beep = 5;
} They each Foo Enum
(
[name] => Bar
)
Baz Enum:int
(
[name] => Beep
[value] => 5
) … and E:7:"Foo:Bar";
E:8:"Baz:Beep"; But … 5 Note that Something also worth including here for consideration is this from the RFC:
i.e. it would conceptually be something like this pseudo-code: enum Boolean: int {
case true = 1;
case false = 0;
} Basically, in code we use ConclusionAdopting the assumption that the backing value is for storage and the name for everything else, then this: enum Kingdom: int {
case Animalia = 0;
// ...
}
class Bird {
public int $id = 1;
public Kingdom $kingdom = Kingdom::Animalia;
} … would be inserted into the database as: INSERT INTO bird (id, kingdom) VALUES (1, 0); … and {
"kingdom": "Animalia"
} Moving ForwardSuggestions:
|
It seems to me that the option of returning a key (as implemented in GraphQL) is more correct This makes it easier to use Enum values on the front end because we don't need to know what value we are storing in the database. Backend:
Frontend:
|
For the alternate option, core/src/GraphQl/Type/TypeBuilder.php Lines 216 to 217 in 5e908c8
|
We should follow symfony: symfony/symfony#40830 symfony/symfony#52676 And |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
To better understand where to go with #6288 I spent some time researching the history of (PHP 8.1+) enums in this library … i.e. what are the correct behavioural expectations, and any missing bits. So this issue is an attempt to bring together a bunch of context to discuss & find a clear path forward.
Right now the key questions are around how to handle
\BackedEnum
s containing theApiResource
class attribute:\BackedEnum
should always normalize to the enum->value
not an iriSchema properties of type\BackedEnum
should always be{"enum": [value1, value2, value3, ...]}
not the iri typename
&value
properties by defaultcases
should probably never be included as an enum item propertyGET
providersOne use-case for the latter is where there is a need to provide enum metadata lookup, e.g. in the example below a human friendly description of a Status' integer.
I'm happy to try and cover
json
andjsonapi
, and @soyuka is already working onjsonld
…jsonhal
is probably easy for me to fit in too if needed.Background
@soyuka's blog post API Platform 3.1 is out!
How to expose Enums with API Platform — a blog post that got attention showing how to expose enums as resources. This is what I have based my assumptions/approach around here. One has to start somewhere.
Issues
Implementation
Misc
Related to Symfony Changes
PRs
Current State Examples
Note
For simplicity I'm just sticking with
Accept: application/json
here.Enum as Property Value
This works and both the schema and JSON response are as expected.
Model
Schema
Enum Resource as Property Value
Model
Schema
This immediately breaks
Article::status
as it becomes an iri instead. Normal and correct for everything that's not an enum.… and the enum resource routes produce "interesting" responses …
Response
Response
The text was updated successfully, but these errors were encountered: