dunglas / vulcain

Fast and idiomatic client-driven REST APIs.
https://vulcain.rocks
GNU Affero General Public License v3.0
3.5k stars 104 forks source link

Vulcain does not work "out of the box" with API Platform #109

Open JeremyPasco opened 1 year ago

JeremyPasco commented 1 year ago

Hi, I've been trying for a long time to set up Vulcain with Api Pltform without success. I have the feeling that it is more a Vulain issue as I never found how to make it work through Caddy module.

Here are my steps to reproduce the issue (largely inspired form your demo):

Download Api Platform v3.0.9 release

curl -L https://github.com/api-platform/api-platform/archive/refs/tags/v3.0.9.tar.gz
tar xzvf v3.0.9.tar.gz
cd api-platform-3.0.9

Fix PNPM issue as stated here: https://github.com/api-platform/api-platform/issues/2417

Configure the API to be Fully Normalized

# api/config/packages/api_platform.yaml
api_platform:
    defaults:
        normalization_context:
            iri_only: true
    # ...

Start the app

docker compose up -d

Create entites like here https://github.com/dunglas/demo-vulcain-api-platform

Update schema + load fixtures :

docker compose exec php bin/console doctrine:schema:update --force
docker compose exec php composer req --dev alice
# api/fixtures/data.yaml
App\Entity\Conference:
    conference_{1..10}:
        name: '<catchPhrase()>'

App\Entity\Session:
    session_{1..100}:
        conference: '@conference_*'
        title: '<catchPhrase()>'
        summary: '<sentences(3, true)>'
        author: '<name()>'

App\Entity\Feedback:
    feedback_{1..100}:
        session: '@session_*'
        comment: '<sentences(3, true)>'
        rating: '<numberBetween(0, 5)>'
docker compose exec php bin/console hautelook:fixtures:load

Try with this code: (inspired from your demo)

<!DOCTYPE html>
<title>Maximum waterfall: API Platform X Vulcain</title>
<script>
  async function fetchJson(url, opts = {}) {
    const resp = await fetch(url, opts);
    return resp.json();
  }

  (async function() {
// Load ALL data from the API
    console.time('download');
    const conferences = await fetchJson('/conferences', { headers: { Preload: '/hydra:member/*/sessions/*/feedback/*' }});
    // const conferences = await fetchJson('/conferences');

    // Fetch conferences
    conferences['hydra:member'].forEach(async conferenceRel => {
      const conference = await fetchJson(conferenceRel);

      // Fetch sessions
      conference.sessions.forEach(async sessionURL => {
        const session = await fetchJson(sessionURL);

        // Fetch feedback
        session.feedback.forEach(async feedbackURL => {
          const feedback = await fetchJson(feedbackURL);
        })
      })
    })
    console.timeEnd('download');
  })();
</script>

With Slow 3G throttling + Disable cache in Chrom DevTools I get the the cascade profile like here on the left: image

Is there anything more to do to enable Vulcain?

sneycampos commented 7 months ago

Is any news here about the issue after so many time or the project is not active?

JeremyPasco commented 6 months ago

No idea, I've tried StackOverflow, Symfony Vulcain dedicated channel and here: no response. I might be wrong but api platform seems to have definitely abandoned standard PHP distribution in favor of FrankenPHP. FrankenPHP has Early Hints and HTTP3 implemented and relies on Vulcain. So I think Vulcain will still be maintained (FrankenPHP seems gaining a lot of attention).

I haven't tried Vulcain features through api-platform+FrankenPHP yet. But I'd like to use Vulcain without having to migrate everything to FrankenPHP.

@dunglas I now you're very busy but could you at least give us hints on what's happening here?

dunglas commented 6 months ago

Chrome removed support for HTTP/2 Server Push, consequently the Vulcain server doesn't work anymore with Chrome with Server Push.

However, we collaborated with the Chrome and Go team to add support for Early Hints in Vulcain. It's supported as of v1.0 of Vulcain. Early Hints work only when HTTP/2 is enabled, and so far only in Chrome.

Vulcain is still maintained both as a standalone Caddy module, as a standalone binary, and as part of FrankenPHP (which uses the Caddy module).