api-platform / admin

A beautiful and fully-featured administration interface builder for hypermedia APIs
https://api-platform.com/docs/admin/
MIT License
487 stars 131 forks source link

hydraAdmin expects json body of 204 post response #156

Open andytson-inviqa opened 5 years ago

andytson-inviqa commented 5 years ago

I've been trying to implement a bulk action in react-admin which uses the Symfony Messenger integration in the backend api-platform api. This is from following: https://api-platform.com/docs/core/messenger/ https://marmelab.com/react-admin/Actions.html#using-a-custom-action-creator

At first I used http status 202 as the first guide mentioned, but api-doc-parser's fetchJsonLd expects a JSON response from that, as it returns a Content-Type: application/ld+json ... and doesn't like it otherwise. https://github.com/api-platform/api-doc-parser/blob/master/src/hydra/fetchJsonLd.js#L32

I changed the http status to 204, however that then causes hydraClient.js convertHydraResponseToReactAdminResponse to try to parse a undefined json property: https://github.com/api-platform/admin/blob/master/src/hydra/hydraClient.js#L327

Should convertHydraResponseToReactAdminResponse be updated to handle this http status for POST/PUT, as it does inherently for DELETE? It then allows me to let react-admin continue on with a chosen side effect.

e.g.

      default:
        if (response.status == 204) {
          return Promise.resolve({data: {id: null}});
        }
        return Promise.resolve( ...
dunglas commented 3 years ago

In my opinion we shouldn't check for the specific status code (a 202 response may contain a valid JSON-LD document) but simply ignore responses with a 20x status code and a content type different from JSON-LD. WDYT?

kennaar commented 2 years ago

Hi, I'm having a similar issue.

Package version:

$ yarn info @api-platform/admin
└─ @api-platform/admin@npm:2.7.2
   ├─ Instances: 1
   ├─ Version: 2.7.2
   │
   └─ Dependencies
      ├─ @api-platform/api-doc-parser@npm:^0.12.0 → npm:0.12.0
      ├─ history@npm:^4.7.0 → npm:4.10.1
      ├─ jsonld@npm:^5.2.0 → npm:5.2.0
      ├─ lodash.isplainobject@npm:^4.0.6 → npm:4.0.6
      ├─ prop-types@npm:^15.6.2 → npm:15.8.1
      └─ react-admin@npm:^3.0.0 → npm:3.19.6

$ composer info api-platform/core
name     : api-platform/core
descrip. : Build a fully-featured hypermedia or GraphQL API in minutes!
keywords : Hydra, JSON-LD, api, graphql, hal, jsonapi, openapi, rest, swagger
versions : * v2.6.8
type     : library
license  : MIT License (MIT) (OSI approved) https://spdx.org/licenses/MIT.html#licenseText
homepage : https://api-platform.com
source   : [git] https://github.com/api-platform/core.git ff3aab5b196709c721960c0bb4f1d52759af737d
dist     : [zip] https://api.github.com/repos/api-platform/core/zipball/ff3aab5b196709c721960c0bb4f1d52759af737d ff3aab5b196709c721960c0bb4f1d52759af737d
path     : /var/www/pss/current/api/vendor/api-platform/core
names    : api-platform/core

ApiResource:

#[ApiResource(
    collectionOperations: [
        'get',
        'approve' => [
            'status'    => 204,
            'messenger' => 'input',
            'input'     => SalesOrderApproval::class,
            'output'    => false,
            'method'    => 'post',
            'path'      => '/sales_orders/approval',
        ],
    ],
    itemOperations: ['get'],
)]

Request info:

REQUEST HEADERS:
POST /api/sales_orders/approval HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:96.0) Gecko/20100101 Firefox/96.0
Accept: application/ld+json
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8001/
content-type: application/ld+json
Origin: http://localhost:8001
Content-Length: 37
DNT: 1
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Pragma: no-cache
Cache-Control: no-cache

RESPONSE HEADERS:
HTTP/1.1 204 No Content
Date: Wed, 09 Feb 2022 07:59:53 GMT
Server: Apache/2.4.38 (Debian)
Vary: Accept
X-Content-Type-Options: nosniff
X-Frame-Options: deny
Cache-Control: no-cache, private
Access-Control-Allow-Origin: http://localhost:8001
Access-Control-Expose-Headers: link
Link: <http://localhost:8000/api/docs.jsonld>; rel="http://www.w3.org/ns/hydra/core#apiDocumentation"
X-Debug-Token: 18938c
X-Debug-Token-Link: http://localhost:8000/_profiler/18938c
X-Robots-Tag: noindex
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive

RESPONSE BODY:

Stack trace:

SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
    transformJsonLdDocumentToReactAdminDocument dataProvider.js:60
    convertHydraResponseToReactAdminResponse dataProvider.js:526
    node_modules bundle.js:5366
    promise callback*fetchApi dataProvider.js:548
    create dataProvider.js:599
    create dataProvider.ts:26
    performPessimisticQuery performPessimisticQuery.js:36
    doQuery doQuery.js:59
    get useDataProvider.js:188
    mutate useMutation.js:163
    create useCreate.js:60
    handleClick ApproveButton.tsx:38
    handleClick ApproveButton.tsx:37
    React 14
    unstable_runWithPriority scheduler.development.js:468
    React 15
    tsx index.tsx:8
    factory react refresh:6
    Webpack 3
react_devtools_backend.js:4061:25
    overrideMethod react_devtools_backend.js:4061
    performPessimisticQuery performPessimisticQuery.js:56
    (Async: promise callback)
    performPessimisticQuery performPessimisticQuery.js:53
    doQuery doQuery.js:59
    get useDataProvider.js:188
    mutate useMutation.js:163
    create useCreate.js:60
    handleClick ApproveButton.tsx:38
    handleClick ApproveButton.tsx:37
    React 14
    unstable_runWithPriority scheduler.development.js:468
    React 15
    tsx index.tsx:8
    factory react refresh:6
    Webpack 3

When I change the ApiResource status to 200 and return something from my handler, the admin app doesn't throw the error anymore and I get a "success" pop-up notification.