-
-
Notifications
You must be signed in to change notification settings - Fork 868
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
API Platform 3.2 #5845
Comments
Hello! I'm currently migrating one of the 2.6 projects. JFYI the migration process is from scratch (install the new 3.2 version and migrate the files one by one I know it might take a longer time but would like to make sure that I'm using the latest features).
Uncaught PHP Exception Symfony\Component\Serializer\Exception\UnsupportedFormatException: "Serialization for the format "html" is not supported." at /app/vendor/symfony/serializer/Serializer.php line 134 Visiting This is the line problematic line (source): docs_formats:
jsonld: ['application/ld+json']
jsonopenapi: ['application/vnd.openapi+json']
html: ['text/html'] EDIT: core/src/Symfony/EventListener/AddFormatListener.php Lines 76 to 79 in 7ebff27
EDIT: Created a PR api-platform/api-platform#2523
Looking at # If you develop on Mac or Windows you can remove the vendor/ directory
# from the bind-mount for better performance by enabling the next line:
- /app/vendor Doesn't start the container, throwing
That's all for now, continuing the migration and I'll let you any issues I'm having. Thanks! |
@divine I can't reproduce your bug. Starting from a fresh install of api-platform/api-platform, then starting the project thanks to Can you try to clean your local environment just in case you're using an old version of containers? |
I'm going to need it to allow I guess there might be some other overrides from ApiProperty which we want too - but schema is the only one I'm using. An example would be:
|
Thanks guys - I'll try it over the weekend and make sure my issue is fixed (I suspect it is). |
Ok, I'll try again and let you know. Another behavior changes: Order of the data has changed (previously): {
"@context": "/contexts/Book",
"@id": "/books",
"@type": "hydra:Collection",
"hydra:member": [
{
"@id": "/books/1",
"@type": "Book",
"id": "1",
"name": "test"
}
],
"hydra:totalItems": 1
} Now 3.2 (see {
"@context": "/contexts/Book",
"@id": "/books",
"@type": "hydra:Collection",
"hydra:totalItems": 1,
"hydra:member": [
{
"@id": "/books/1",
"@type": "Book",
"id": "1",
"name": "test"
}
]
} This might break some tests. Ok, another "bug" or "behavior change that I've found: This is the code with custom controller to return currently authenticated user: #[ApiResource(
operations: [
new Get(
uriTemplate: '/myself',
controller: GetUserController::class,
security: 'is_granted("IS_AUTHENTICATED_FULLY")',
read: false,
),
]
) This is the controller: <?php
namespace App\Controller;
use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Core\User\UserInterface;
class GetUserController extends AbstractController
{
public function __invoke(): UserInterface
{
/* @var User $user */
return $this->getUser();
}
} Previous version: {
"@context": "\/contexts\/User",
"@id": "\/users\/1",
"@type": "User",
"id": "1",
"username": "test",
"createdAt": "2023-10-01T22:16:56+00:00",
"updatedAt": "2023-10-01T22:16:56+00:00"
} Now: {
"@context": "\/contexts\/User",
"@id": "\/myself",
"@type": "User",
"id": "1",
"username": "test",
"createdAt": "2023-10-01T22:16:56+00:00",
"updatedAt": "2023-10-01T22:16:56+00:00"
} @id field should be Otherwise new version looks neat even though I'm still having an issues with custom DTO which I gave up as it generates weird open api documentation, I might add more details if you're interested to take a look. Thanks! |
@divine do you have other operations on your User resource? Can you copy/paste the complete resource code please? The order of the operations matters! |
We have added a custom serialized name on a property like this Before/after
|
Hi @dannyvw, can you provide a reproducer please, with the same environment you used to reproduce this issue (Doctrine ORM vs ODM or any other data provider, XML/YAML/Attribute format, etc.)? You can use https://github.com/api-platform/api-platform to create this reproducer |
Hello, Here is a reproduction repository https://github.com/divine/apipbug. I've removed only PWA as I don't use Next.js frontend. Run the following commands from documentation: docker compose build --no-cache
docker compose up --pull --wait Thanks!
Even if keep only one operation it's still the same, Thanks! |
@divine I've recreated a use-case for your User Reproducer is available here: https://github.com/api-platform/demo/tree/test/user-myself
Then, go to https://localhost/docs, log in using |
Hello, I've just pushed up my demo as well, however it's the same as what results you've got. So basically what I'm saying is this latest version returns: {
"@context": "\/contexts\/User",
"@id": "\/myself",
"@type": "User",
"id": "1",
"username": "test",
"createdAt": "2023-10-01T22:16:56+00:00",
"updatedAt": "2023-10-01T22:16:56+00:00"
} but version of APIP 2.6 returns for custom {
"@context": "\/contexts\/User",
"@id": "\/users\/1",
"@type": "User",
"id": "1",
"username": "test",
"createdAt": "2023-10-01T22:16:56+00:00",
"updatedAt": "2023-10-01T22:16:56+00:00"
} Which one is correct? I think the second one as it returns the resource path so it can be fetched. I have now checked it up the behavior was changed in version 3.0.0. This is the ApiResource for version 2.6 that returns #[ApiResource(
collectionOperations: ['post'],
itemOperations: [
'get' => ['security' => "is_granted('ROLE_ADMIN') or object == user"],
'get_me' => [
'method' => 'GET',
'path' => '/myself',
'controller' => GetUserController::class,
'read' => false,
'security' => "is_granted('IS_AUTHENTICATED_FULLY')",
],
],
denormalizationContext: ['groups' => ['user:write']],
normalizationContext: ['groups' => ['user:read']],
)] Is it incorrect to expect the "@id" data to be the resource path or was it a bug in version 2.6 that was fixed in 3.0.0? My personal view that if the Thanks! |
@divine You're comparing 2.6 features to 3.x. They are different major versions which use a totally different metadata system. If you're still using API Platform 2.x, please upgrade your projects to API Platform 3.x following the upgrade guide.
When calling
IMO it was a bug on 2.6, but it can depend on the use-case and the implementation. Also keep in mind the metadata system is totally different between 2.x and 3.x.
Not necessarily. Maybe If you want to return a different IRI than the called operation, you should use |
Gotcha. I've tried to upgrade and only thing left is this custom controller action which gave a different path than I've expected.
Thank you for your detailed reply regarding this.
Thanks! |
Sorry guys - I don't think PR 5855 is having the intended effect. I'm still getting a "String value found, but an object is required" in my assertMatchesResourceItemJsonSchema(). And it looks like the test uses "maxLength" rather than "type"? Tested with the current dev-main (2e48c7e) |
Indeed, in fact you should probably have a You're trying to create a stateful route in a stateless environment which is why it's not really working. Also you're using a controller so you'd be better off not using API Platform for this route, but instead use our serializer inside your controller to get json-ld. I'm looking at your issue @dannyvw and @vincentchalamon checks @paullallier's schema issue. |
@soyuka I was trying to create a testcase, this one is green on 3.1.x. Does this help?
|
I think I've found an issue that triggers an error only in debug mode - it's taken me most of the day to work out what's happening! If I have an entity with an id field defined as When env When env I seem to get the same IRI error with a patch request if the custom provider throws an exception, though I haven't dug into that as much. If I change the id definition to In v3.1.16, both cases (id initialised to null or uninitialised) return the exception throw in the processor. Possibly defining the id in the entity as defaulting to null is wrong, but it worked before and I suspect I won't be the only person relying on it working. If the custom processor doesn't throw an exception, either definition of the id property is fine. Sidenote: Not directly related to the bug. I'm using lexik/jwt-authentication-bundle to handle user authentication - and it correctly kills request very early if the JWT is missing or expired. But a correctly authenticated user might not have the right permission level to GET or POST to a particular endpoint - and this is checked in the constructor for the custom processors / providers. As a result they can throw a 403 error, which is what lead me to this issue. It might be more optimal for me to move the endpoint permission check to earlier - currently the incoming JSON body is deserialised and, for a PATCH / PUT request, the current version of the entity might be retrieved from the DB, before the request is blocked for the user having the wrong permission level. There's a trade-off between having the check "live" with the code that serves the request, or more centralised - and I might change to the more centralised (earlier) option at some point.] |
And one related to the (fixed) missing html swagger page on the API root (in my case at https://main-api/). In Chrome, both https://main-api/ and https://main-api/docs show the html swagger page, but the debug web toolbar says that the first one is throwing a 500 error (even though it returns the correct html, which Chrome displays): Similarly, I have a test which uses the |
@paullallier the
Weird, we need to investigate and we've a test on that IIRC.
This is an internal type it should definitely not be left in the Schema, thanks for the reproducer we need to add another test case. |
Sorry - this was wrong. I thought I was grabbing the latest with composer, but I was stuck with one from a few days ago. The latest dev-main works in Chrome - 200 status code - but my test case with ApiPlatform\Symfony\Bundle\Test\Client still throws a 406 error. I might have a malformed request though - not sure. |
Thank you for your kind reply. Looks like {
"title": "An error occurred",
"detail": "Could not find stage with index 0.",
"status": 500,
"trace": [
{
"file": "/app/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php",
"line": 274,
"function": "getStage",
"class": "Doctrine\\ODM\\MongoDB\\Aggregation\\Builder",
"type": "->",
"args": [
0
]
},
{
"file": "/app/vendor/doctrine/mongodb-odm/lib/Doctrine/ODM/MongoDB/Aggregation/Builder.php",
"line": 235,
"function": "getPipeline",
"class": "Doctrine\\ODM\\MongoDB\\Aggregation\\Builder",
"type": "->",
"args": []
}, Here is a Get resource: new Get(
uriTemplate: '/myself',
status: 302,
extraProperties: [
'canonical_uri_template' => '/example',
]
), Anyways, looks like I can't simply modify 'canonical_uri_template' => '/users/' . $this->getUser()->getId()
This is definitely some use-case as almost all frontends gets It would be great to "hook" into that logic and modify it's redirect path based on some custom logic. Thanks! |
@divine an uri template must be referencing one of another resource, please just use a controller in that case as it's too hard to make this fit. @paullallier did you add |
@soyuka: No, I had missed that. I've done it now, and I have this:
Using curl to load the pages, I get this: And the profiler on the curl request throwing the 406 error shows this: So it looks like the issue is that the /docs page uses the docs_formats list, but the / page uses the formats list. If I add |
I am seeing a regression in OpenAPI json docs generation. Example entity snippet: #[ApiResource(
operations: [
new Get(normalizationContext: ['groups' => ['Book:V']]),
],
)]
class Book
{
#[ApiProperty(fetchEager: true)]
#[ORM\ManyToOne]
#[ORM\JoinColumn(nullable: false, onDelete: 'CASCADE')]
#[Serializer\Groups([
'Book:V',
])]
public User $user;
{
"components": {
"schemas": {
"Book-Book.V": {
"properties": {
"user": {
"$ref": "#/components/schemas/User-Book.V",
},
{
"components": {
"schemas": {
"Book-Book.V": {
"properties": {
"user": {
"owl:maxCardinality": 1,
"type": "unknown_type",
}, I think potentially all EDIT: Whoops, I see this was fixed 6 hours ago... sure enough, on |
released a new beta version next week we'll tag as stable I think :) |
@soyuka:
Or... it's working. I think I must have been having a caching issue. |
Right. I had to make a couple of changes to $id parameters initialised to null, as this comment: #5845 (comment) But other than that, I now have |
Hello, The deprecation notice that I've reported in #5705 is still an issue:
Hopefully it will fixed before a stable release. Thanks! |
I think that this is still an issue I would like to reproduce, could you give me a full stack trace (preferably on gist.github.com or via slack)? @divine I think this is harder to do, might be linked to doctrine/mongodb-odm#2546 as I can't really test the new version without that... |
@soyuka: Demo project here: https://github.com/paullallier/iri-failure-on-exception POST on the bad_entity should show the error. POST on the good_entity gives the expected exception. Not got it failing on the PUT endpoints yet. EDIT: I've done some more digging - the PUT request only gives the IRI error if the StateProvider succeeds and the StateProcessor then throws an exception. It's almost certainly the same failure mechanism as the POST request, so I think you can ignore PUT. |
@paullallier I can't reproduce am I missing something? |
@soyuka: good_entity should give the correct response - that permission denied exception. If you do the same, but hitting bad_entity, you should get the "can't make IRI for..." error instead, which is the issue? |
@soyuka: You might need the accept header too, but I'm struggling to get that working with curl (I probably have a syntax error). It fails if you use the SwaggerUI: EDIT: curl wasn't working because jq wasn't happy with the data it was getting: |
Maybe I have missed something and this was an intentional decision, but I notice in the OpenAPI schemas, APIP 3.2 has dropped the This was actually discussed before, in v2.5.6, and Dunglas suggested those fields should be in the schema: #3667 (comment) -- can't remember which version they got added in, but by v3.0.0 (maybe earlier) they were included, but have now disappeared again. |
@soyuka, GraphQL docs (GraphiQL) doesn't work: It seems ApiPlatform is sending the wrong header |
@lermontex see https://github.com/api-platform/core/blob/main/CHANGELOG.md#notes Maybe that we need to fix this though, can you give me your current |
@soyuka, I ran The configuration file:
|
ApiPlatform 3.2 fails (in development) when data is POSTed that cannot be denormalized, e.g. because a property has an invalid type ( In that case a Full trace from the failing unit test:
|
@lermontex can't reproduce. @j-schumann looks like the same issue as @paullallier but I didn't manage to reproduce... |
@soyuka, I see earlier you have already fixed a similar error for OpenAPI (PR #5868) After updating to version 3.2, none of these addresses work:
Server returns incorrect header ( I tried disabling the cache:
This worked, however there is another error: If you add the json format to the formats section there is no error, but shouldn't this format be added by default?
|
thanks to @paullallier I think I found the weird exception (same thing that @j-schumann reported). @lermontex you should definitely allow |
@soyuka As far as I understand, GraphQL support is enabled by default, so why isn't json enabled by default? Please note that if there is no Try disabling cache_headers and check this |
Okay nice thanks @lermontex I reproduced patch incoming |
Please report 3.2 issues here:
The text was updated successfully, but these errors were encountered: