Say Hello to Mercure 0.10!

I’m very excited to announce the immediate availability of the version 6 of the Mercure Internet Draft as well as of the version 0.10 of the reference implementation!

Mercure is a real-time protocol built on top of Server-sent Events and leveraging HTTP/2+. It allows to push messages to JavaScript webapps, mobile apps or IoT devices with ease. Client-side, it relies on the native EventSource class and doesn’t require any JS dependency. Server-side, it allows to use a Hub to handle persistent connections and dispatch messages sent, for instance, from your REST or GraphQL APIs. An open source Hub designed for performance and high loads is developed in parallel to the specification. Get started with Mercure.

Since the initial release of Mercure, we gather feedback from the ever-growing community of users and contributors. This allowed us to identify the pain points, some limitations and new use cases. It took months of work to get there, but these new versions of the protocol and of the FOSS hub (written in Go) fix all the limitations and design issues we identified so far. They are by far the best and the fastest versions ever released! Let’s discover these changes and new features.

Protocol Changes

Authorization Mechanism

One of the key features of Mercure is its authorization mechanism. It allows to send private updates, which will be received only by subscribers having the appropriate credentials.

Until the last version of the protocol, this mechanism was using the concept of targets, and was hard to understand for newcomers.
In the 6th version of the protocol, the authorization mechanism has been dramatically simplified, while staying as powerful as before.

The authorization mechanism has been totally revamped and the concept of targets is gone. Now, to send a private update, the publisher must only mark it as private when sending the POST request to the hub using the new private parameter.

On the other hand, to receive a private update, a subscriber must present a JWT to the hub containing a list of topic selectors in the mercure.subscribe claim of the token.

A private update will be received by a subscriber only if:

  • the topic of the update is contained in the list of topic selectors
  • the topic matches an URI template present in the list
  • the topic selectors list contains the special value *, which allows to receive all updates.

More advanced use cases such as cherry-picking which updates will be received by a subscriber are also supported thanks to existing features such as alternate topics.

Also, the new concept of target selectors can also be used to subscribe to (public or private) updates, making the whole protocol more consistent.

Learn more about topic selectors and the authorization mechanism.

Presence API

One of the most requested feature was the ability to retrieve the list of currently connected subscribers. This is now possible thanks to a new web API exposed by the hub! It’s also possible for a subscriber to receive Mercure updates when other subscribers connect or disconnect.

Hubs can now expose endpoints returning the list of connected users as JSON-LD documents:

  • /.well-known/subscriptions returns the list of all active subscriptions
  • /.well-known/subscriptions/{topic} returns the list of active subscriptions for a specific topic
  • /.well-known/subscriptions/{topic}/{subscriber} returns details for a single subscription

Also, after having fetched the initial list of connected users, clients can subscribe (using the standard subscription mechanism) to connection status updates by using these URIs as topics.

To access to this presence API, subscribers must be authenticated and have topic selectors matched by these URIs.

Finally, arbitrary data (such as the subscriber’s username or IP address) can be attached to a subscription and retrieved by other subscribers using the new mercure.payload JWT claim.

The debug UI shipped with the reference hub now supports this new feature:

Learn more about active Mercure subscriptions.

Event Sourcing

The native features of Mercure, including its built-in history and its state reconciliation mechanism make it a convenient solution to implement Event Sourcing.

The latest version of the protocol introduces changes making dedicated to this kind of usages.

First, it is now possible to set the value of the Last-Event-ID HTTP header (or of the query parameter with the same name) to earliest to retrieve the all past events. This allows to use the Mercure hub similarly to Apache Kafka, but directly from the browser (or any other kind of HTTP client).

Additionally, when a Last-Event-ID header or parameter is set, the hub will now always return a Last-Event-ID header in the HTTP response. If it matches the requested one, it means that all requested events have been returned, otherwise, it means that the requested event may have been deleted by the hub (if it stores a limited number of events for instance), or that this event ID doesn’t exist.

Learn more about Event Sourcing and state reconciliation capabilities of Mercure.

IRIs, Strings, and Fragment Identifiers

The protocol has been made more consistent by allowing to use IRIs (recommended) or plain strings (discouraged but sometimes practical) for every identifiers: topics, event IDs, subscriber IDs…

Event IDs starting by the # character (URI fragment) are now reserved for generation by the hub. This allows a hub to use offsets generated by systems such as Apache Kafka, Apache Pulsar or Redis Streams as update identifiers while keeping these identifiers globally unique (because they are relative to the Hub URI).

Changes in the Reference Implementation

All the features described previously have already been implemented in the reference implementation (the open source hub written in Go). But that’s not all! The hub has also been dramatically improved during the past few months.

New Engine

Until version 0.10, the reference hub was using an engine working like this: when a new update was posted by a publisher, a new light-weight process (goroutine) was started and the update was pushed to every active subscriber in a loop. If a Last-Event-ID header (or parameter) was passed by a subscriber to request past events, these past events were retrieved from the persistence layer and dispatched from another goroutine.

However, this approach had several drawbacks:

  • If a subscriber was slow to receive an update, it was slowing down the main loop, and so increasing the latency also for other subscribers.
  • If a Last-Event-ID was passed, new events could be received before events coming from the history (for example, when a new event was sent from the main goroutine while another goroutine was still retrieving past events from the persistence layer). The order in which events were received wasn’t 100% guaranteed.

Mercure 0.10 contains a brand new engine that fixes these issues! This new engine leverages thoroughly the iconic features of the Go programming language: channels and goroutines. Now, two buffers are assigned to each subscribers: the first one stores events coming from the history while the second one stores “live” events. When a new event is published, the main goroutine pushes this event in the “live” buffers without waiting for events to be dispatched. Then a dedicated goroutine per subscriber pops events from the buffers associated with it. So every subscriber can receive the events as its own pace, without impacting the rest of the system.

This buffer system also fixes the order issue: goroutines dedicated to specific subscribers wait for all updates coming from the history to be dispatched before starting to dispatch updates stored in the “live” buffer.

Last but not least, this new system allows to disconnect subscribers that are too slow to receive the updates. A new config option, dispatch_timeout, has been introduced to configure the maximum time that a subscriber can take to receive an update before being disconnected to free resources.

If you’re interested in the internals, take a look at this piece of Go code!

A big thanks to Dani Kaplan for his precious help testing and debugging this new engine under high loads!

Prometheus and Health Checks Support

Prometheus is a very popular monitoring system and time series database for Cloud Native applications. Jérémy Decool made a series of great contributions that add support for Prometheus to the Mercure hub. Metrics include (among other things) the number of currently connected subscribers, the number of dispatched updates, the number of served HTTP request segregated by status code, the memory usage, the current number of processes and the number of open file descriptors!

In addition, a new URL (/healthz) is now available to check if the hub is up and running without polluting the HTTP logs with useless entries. This particularly useful for Kubernetes’ liveness and readiness probes.

Version Flag

Jérémy Decool also contributed a new --version flag allowing to know what exact version of the Hub is being used. It looks obvious and priceless, but it was a missing feature. Thanks Jérémy for adding it!

Examples and Demos

We updated the documentation as well as all existing examples (in various programming languages) to be in sync with the latest version of the spec. I also added examples and demos illustrating new features, including a chat written in JavaScript and Python:

This demonstration chat is now available online, try it!

Community

Mercure is becoming more and more popular! It recently reached 2k stars on GitHub and integrations with existing ecosystems are now plenty. For this new version, we worked with the community to keep libraries and other Mercure-related projects in sync with the latest changes in the spec. Most of them are already compatible including (but not limited to):

For some others (for instance, the Java library and the Python library), Pull Requests are open. Finally, some tools still need to be updated including the awesome alternative Hub written in Node created by Nicolas Coutin and the Yii framework integration. Any help is very welcome!

To keep up with Mercure news, you can now follow our brand new Twitter account.

Finally, I’m very happy to announce that Les-Tilleuls.coop now provides official training for Mercure, in English and in French!

Improving Libraries Used by Mercure

One of the most powerful feature of Mercure is the ability to use URI templates to subscribe to topics matching patterns. Under the hood, the reference implementation of Mercure use the uritemplate Go library.

The performance of the Mercure hub highly depends of the performance of this library. So I worked with Kohei Yoshida (the author of this lib) to improve its performance, add benchmarks and fix some bugs! This also dramatically improved the performance of the hub (and of other projects using this library). Thank you Kohei for your quick reviews and releases!

The development of the new version of the hub also allowed me to find an issue in the Go standard library, and to open a Pull Request to fix it.

Hosted and High Availability Versions

Managed and On Premise High Availability (cluster) versions of the Mercure hub are available for a while now. They are already compatible with Mercure 0.10 and are now out of beta!

I want to thank very much our first customers, who trusted us, helped us to battle-test our hosting platform and gave us incomparable feedback allowing us to improve both the open protocol, the Managed and On Premise versions and the Open Source hub! They also allow us to invest more in the protocol’s development and in the Open Source version! So thank you again.

I also want to thank very much my GitHub sponsors, who allow me to work always more on my free software projects, including Mercure but also Vulcain, API Platform and the Symfony components I maintain.

Try and Star Mercure!

If you aren’t using Mercure yet, you can install a hub in a few seconds, or use the online demo, give it a try! If you like the project, show your support by starring it on GitHub!

Forum PHP 2019: Mercure – Real-Time for PHP Made Easy

Yesterday at Forum PHP 2019 I presented how easy it is to create real-time apps using PHP (among other languages) and the Mercure protocol.

I also introduced the shiny and new Mercure website (designed by Laury S.)!

A special thanks to Eric Comellas who jumped on stage to explain how iGraal uses Mercure on a large scale to serve simultaneously more than 100,000 of their customers!

Mercure: Real-Time APIs for Serverless and Beyond

Here is the slide deck I presented during API Days SF 2019:

Mercure is a protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. It is especially useful to publish real-time updates of resources served through web APIs, to reactive web and mobile apps. The protocol is designed for serverless, HTTP/2+, hypermedia and GraphQL, and is fully-featured: auto-discoverable, authorization, re-connection, state reconciliation…

[SymfonyLive Paris slides] Symfony on steroids
: Vue.js, Mercure, Panther

Thanks to the new capabilities of the web platform (web components, Progressive Web Apps…) and the rise of modern JS libraries (Vue, React, Angular) almost all modern Symfony applications must leverage the frontend ecosystem.
Symfony 4 embed many gems that make it easy to integrate modern JavaScript within the framework, including the first component entirely written in JS: Webpack Encore.

In Symfony 4.2, another component that is super convenient for apps containing JS code has been released: Panther, a PHP library compatible with BrowserKit, that drives real web browsers to create end-to-end (E2E) tests with ease.
During this talk, I’ll show you how to cleanly integrate modern JavaScript code with Symfony and Twig and how to test such applications using Panther.

The examples will use VueJS, because it’s probably the easiest JS framework to get started with as a PHP developer, but all the tips and tricks will be applicable with other libraries such as React or Angular.

Finally, we’ll add some real time capabilities to our app using Mercure.rocks

Symfony and API Platform get “push” and real-time capabilities (Mercure protocol)

Mercure.rocks is a brand new protocol allowing to push data updates to web browsers and other HTTP clients in a convenient, fast, reliable and battery-efficient way. It is especially useful to publish real-time updates of resources served through web APIs, to reactive web and mobile apps.

Both Symfony and API Platform now have an official support for this protocol!

From the ground, Mercure has been designed to work with technologies not able to maintain persistent connections. It’s especially relevant in serverless environments, but is also convenient when using PHP or FastCGI scripts.

Mercure is basically a higher-level replacement for WebSocket. Unlike WebSocket, it is compatible with HTTP/2 and HTTP/3.
It has been designed with hypermedia APIs in mind, is auto-discoverable through the Web Linking RFC and is also compatible with GraphQL.
It natively supports authorization, reconnection in case of network issue (with refetching of missed events), subscribing to several topics, topics patterns (using templated URIs)…

Because it is built on top of Server-sent Events and plain old HTTP requests, it is already compatible with all modern browsers, and requires 0 client-side dependencies.

The protocol is open (available as an Internet Draft), and a reference open source implementation of the server written in Go is available.—

API Platform 2.4: MongoDB, Elasticsearch, Mercure, OpenAPI v3, CQRS with Symfony Messenger, HTTP/2 Push, improved React apps and more!

I’m pleased to announce the immediate availability of API Platform 2.4 beta! This new version is a huge one, that comes with a large set of new features.

For newcomers, API Platform is a full-stack framework to develop in a breath high quality API-driven projects. Among other (lower level) libraries, API Platform provides:

API Platform supports modern REST formats (JSON-LD/Hydra, JSONAPI, OpenAPI, HAL…) as well as GraphQL.

To create your initial project, you just have to describe the public structures of the data to expose through the API. API Platform will take care of exposing the web API and bootstrapping the clients to consume it: get started with API Platform.

Version 2.4 introduces a lot of very interesting new features. Here is the curated list:

  • Read and write support for MongoDB, the reference document database, including a lot of useful filters
  • Read support for Elasticsearch, the open source search and analytics engine, including filters for advanced search
  • Automatic “push” of updated resources from the server to the clients using the brand new Mercure protocol
  • Integration with the Symfony Messenger component to easily implement the CQRS pattern and to handle messages asynchronously (using brokers such as RabbitMQ, Apache Kafka, Amazon SQS or Google PubSub)
  • Ability to leverage the “Server Push” feature of HTTP/2 to preemptively send the relations of a requested resource to the client
  • Automatic availability of list filters in the React-based admin when a corresponding one is available API-side
  • Full compatibility with the version 3 of the OpenAPI specification format (formerly known as Swagger), and integration of the beautiful ReDoc documentation generator
  • Improved DTOs support
  • Per resource configuration of HTTP cache headers
  • Ability to easily use the Sunset HTTP header to advertise the removal date of deprecated endpoints

The full changelog is available on GitHub.

Let’s dive into these new features!

MongoDB support

MongoDB is one of the most popular NoSQL database. Native support for MongoDB was the most requested, and the most awaited API Platform feature! Sam Van der Borght started the work in March 2016. In July 2017 the Pull Request has been ported to API Platform v2 by Pablo Godinez helped by Hamza Amrouche (API Platform Core Team), Alexandre Delplace and others. Finally, since August 2018 Alan Poulain (API Platform Core Team and author of the GraphQL subsystem) produced a huge effort to finish and polish the patch.

With 114 commits and 234 files changed over almost 3 years. This is one of the biggest contributions to the project.

The MongoDB integration relies on Doctrine MongoDB ODM 2.0 (currently in beta). To enable this feature, just install and configure DoctrineMongoDBBundle. API Platform will autodetect it. Then, create a class mapped with MongoDB, and mark it as an API resource:

namespace App\Document;

use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;

/**
 * @ApiResource
 * @ODM\Document
 */
class Book
{
    /**
     * @ODM\Id(strategy="INCREMENT", type="integer")
     */
    public $id;

    /**
     * @ODM\Field(type="string")
     */
    public $title;
}

The support for MongoDB leverages the flexibility of API Platform: it has been implemented as a data provider and a data persister. Relations, pagination as well as boolean, date, numeric, order, range and search filters are also supported!

A big thanks to all contributors of this amazing feature, and to Andreas Braun, the maintainer of Doctrine MongoDB ODM, for the in-depth reviews!

Elasticsearch support

Elasticsearch is another very popular open-source data store. It allows to perform full-text searches and advanced analyzes on very large datasets. Orange has sponsored the development of an Elasticsearch data provider for API Platform, as well as some interesting search filters. The implementation has been realized by Baptiste Meyer (API Platform Core Team). Thanks to Orange, this feature is now available for everybody in API Platform 2.4.

To enable and configure the Elasticsearch support, refer to the official documentation. Then, a simple resource class corresponding to an Elasticsearch index is enough to benefit from the full power of API Platform:

namespace App\Model;

use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Elasticsearch\DataProvider\Filter\MatchFilter;

/**
 * @ApiResource
 */
class Tweet
{
    /**
     * @ApiProperty(identifier=true)
     *
     * @var string
     */
    public $id;

    /**
     * @var User
     */
    public $author;

    /**
     * @var \DateTimeInterface
     */
    public $date;

    /**
     * @ApiFilter(MatchFilter::class)
     *
     * @var string
     */
    public $message;
}

Then, you can use an URL such as /tweets?message=foo to search using Elasticsearch.

Keep in mind that it’s your responsibility to populate your Elastic index. To do so, you can use Logstash, a custom data persister or any other mechanism that fits for your project (such as an ETL).

Baptiste also took this opportunity to improve the code handling the pagination. It is now a generic class used by all native data providers (Doctrine ORM, MongoDB and Elasticsearch), that you can reuse in your own.

Read and improve the Elasticsearch related documentation.

Real time update of client with Mercure

Mercure is a brand new protocol built on top of HTTP/2 and Server-sent Events (SSE). It’s a modern and high-level alternative to WebSocket (WebSocket is not compatible with HTTP/2). Mercure is especially useful to publish updates of resources served through web APIs in real time. It is natively supported by modern browsers (no required library nor SDK) and is very useful to update reactive web and mobile apps.

In version 2.4, I added Mercure support to the server component of API Platform and to the React and React Native app generators. The Docker Compose setup provided with API Platform has also been updated to provide a Mercure hub.

Configuring the framework to automatically dispatch updates to the currently connected clients is straightforward:

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;

/**
 * @ApiResource(mercure=true)
 */
class Book
{
    // ...
}

Thanks to the auto-discoverability capabilities of Mercure, the generated clients will automatically subscribe to updates, and render them when received:

Mercure in API Platform 2.4

Read and improve the Mercure subsystem documentation.

CQRS and async message handling with Symfony Messenger

Messenger is a new Symfony component created by Samuel Roze (Symfony and API Platform Core Team). It allows to dispatch messages using message queues (RabbitMQ, Kafka, Amazon SQS, Google PubSub…) and to handle them asynchronously. It provides a message bus that is very useful to implement the CQRS design pattern.

In API Platform 2.4, I added a convenient way to leverage the capabilities of Messenger. This new feature is particularly useful to create service-oriented (RPC-like) endpoints:

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(
 *     messenger=true,
 *     collectionOperations={
 *         "post"={"status"=202}
 *     },
 *     itemOperations={},
 *     output=false
 * )
 */
class ResetPasswordRequest
{
    /**
     * @var string
     *
     * @Assert\NotBlank
     */
    public $username;
}

Thanks to the new messenger attribute, this object will automatically be dispatched to the bus. It can then be handled (synchronously or asynchronously) by a message handler:

namespace App\Handler;

use App\Entity\ResetPasswordRequest;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;

class ResetPasswordRequestHandler implements MessageHandlerInterface
{
    public function __invoke(ResetPasswordRequest $forgotPassword)
    {
        // do something with the resource
    }
}

That’s all you need to use Messenger!

Read and improve the Messenger subsystem documentation.

Server Push

HTTP/2 allows a server to pre-emptively send (or “push”) responses (along with corresponding “promised” requests) to a client in association with a previous client-initiated request. This can be useful when the server knows the client will need to have those responses available in order to fully process the response to the original request.

RFC 7540


This is capability is especially useful for REST APIs performance: it allows the server to instantly push the relations of the current resource that will be needed by the client, even before the client knows that it will have to issue an extra HTTP request.

API Platform 2.4 makes it very easy to push relations using HTTP/2:

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;

/**
 * @ApiResource
 */
class Book
{
    /**
     * @ApiProperty(push=true)
     *
     * @var Author
     */
    public $author;
}

Thanks to the push attribute, if the client asks for /books/1 the web server will directly send both the requested book resource and the related author (e.g. /authors/12) to the client.

For best performance, this feature should be used in conjunction with the built-in HTTP cache invalidation system (based on Varnish).

Read and improve the HTTP/2 Server Push subsystem documentation.

Filters detection in API Platform Admin

Jean-François Thuillier and Arnaud Oisel patched API Platform Admin and the underlying API Doc Parser JavaScript library to automatically detect and use filters exposed by the API spec (Hydra or OpenAPI). A video is worth thousand words:

Filters support in API Platform

The only code that you need to get such UI is the following:

import React from 'react';
import { HydraAdmin } from '@api-platform/admin';

export default () => <HydraAdmin entrypoint="https://api.example.com"/>;

The UI is built client-side dynamically by parsing the API spec. Awesome isn’t it?

Jean-François also added some convenient helpers to help customizing the admin, and Laury Sorriaux fixed a long standing limitation: it’s now possible to use the admin even with API not served at the root of the domain (such as /api).

Read and improve the docs of API Platform Admin.

OpenAPI v3 and ReDoc

API Platform 2.4 now fully support the new version of the OpenAPI (formerly Swagger) specification format (v3). It also leverages new features introduced by this version such as links.

To retrieve the OpenAPI specification of the API in version, use the following url: /docs.json?spec_version=3.

You can also dump the specification in JSON or in YAML format:

  • bin/console api:openapi:export --spec-version=3 # JSON
  • bin/console api:openapi:export --spec-version=3 --yaml # YAML

Also, in addition to Swagger UI, we added support for ReDoc, a beautiful, human-readable, API docs generator written in React:

ReDoc in API Platform 2.4

OpenAPI v3 support has been contributed by Anthony Grassiot (API Platform Core Team). ReDoc integration has been contributed by Grégoire Hébert. A big thanks to them!

Read and improve the OpenAPI related documentation.

Improved DTO support

Handling Data Transfer Objects was known to be difficult with API Platform. Back in October, the API Platform and the Sylius teams worked together to improve the API of the popular e-commerce solution… using API Platform (stay tuned!). During this workshop Antoine Bluchet and I worked on a new way to handle DTOs with API Platform:

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Dto\BookInput;
use App\Dto\BookOutput;

/**
 * @ApiResource(
 *   input=BookInput::class,
 *   output=BookOutput::class
 * )
 */
final class Book
{
  // ...
}

The new input and output attributes allow to use specific classes respectively for the writeable and the readable representation of the resource.

As demonstrated in the example using Symfony Messenger, it’s also possible to set these new attributes to false to hint that the operation will take no inputs or no outputs.

These new attributes are automatically taken into account by all API Platform subsystems, including GraphQL, Hydra and OpenAPI.

Read and improve the DTO related documentation.

Cache HTTP headers

A convenient way has been to configure the HTTP cache per resource has been added by Daniel West:

use ApiPlatform\Core\Annotation\ApiResource;

/**
 * @ApiResource(cacheHeaders={"max_age"=60, "shared_max_age"=120})
 */
class Book
{
    // ...
}

With this config, API Platform will automatically generate the following Cache-Control HTTP header: Cache-Control: max-age=60, public, s-maxage=120. Thanks Daniel!

Read and improve the HTTP cache headers documentation.

Sunset HTTP header

The Sunset HTTP response header field indicates that a URI is likely to become unresponsive at a specified point in the future.

draft-wilde-sunset-header Internet Draft

This header plays well with the deprecation mechanism available since API Platform 2.3. Thanks to a nice contribution of Thomas Blank, it’s now easy to set this header using API Platform:

namespace App\Entity;

/**
 * @ApiResource(itemOperations={
 *     "get"={
 *         "deprecation_reason"="Retrieve a Book instead",
 *         "sunset"="01/01/2020"
 *     }
 * })
 */
class Parchment
{
    // ...
}

Read and improve the documentation related to API evolution.

Improved client generator

API Platform 2.4 is shipped with an improved version of the React and Vue.js client generators:

  • Relations are now always handled properly
  • HTML number fields as well as lists (arrays) are converted to the appropriate JSON type when sent to the API
  • API not server at the root of the domain (such /api) are now supported (thanks to Fabien Kovacic)

Download and promote API Platform

API Platform 2.4 is available for download on GitHub. While you are here, if you like the project, help us making it popular by starring it on GitHub!

[SymfonyCon slides] Progressively enhance your Symfony 4 app using Vue, API Platform, Mercure and Panther

Thanks to the new capabilities of the web platform (web components, Progressive Web Apps…) and the rise of modern JS libraries (Vue, React, Angular) almost all modern Symfony applications must leverage the frontend ecosystem.
Symfony 4 embed many gems that make it easy to integrate modern JavaScript within the framework, including the first component entirely written in JS: Webpack Encore.

In Symfony 4.2, another component that is super convenient for apps containing JS code has been released: Panther, a PHP library compatible with BrowserKit, that drives real web browsers to create end-to-end (E2E) tests with ease.
During this talk, I’ll show you how to cleanly integrate modern JavaScript code with Symfony and Twig and how to test such applications using Panther.

The examples will use VueJS, because it’s probably the easiest JS framework to get started with as a PHP developer, but all the tips and tricks will be applicable with other libraries such as React or Angular.

Finally, we’ll add some real time capabilities to our app using Mercure.rocks

HTTP/2: speed up your apps and dispatch real time updates (Symfony and API Platform’s features announcement)

HTTP/2 can improve the loading time of webpages up to 2 times. Did you know that it’s very easy to optimize your Symfony applications to leverage the advanced features of this new protocol?

This talk also contains the announcement of 3 new PHP packages:

Agenda:

  • a historically contextualized presentation of the different versions of the HTTP protocol;
  • a state of the protocol support in the PHP ecosystem;
  • a guide explaining how to serve your PHP and Symfony apps with h2, using Nginx, Apache and Docker;
  • many code samples showing how to use h2 to improve the loading time of your assets and APIs using the WebLink component and Twig
  • examples of how to take advantage of the protocol using the curl and Guzzle clients
  • the Mercure Protocol
  • Mercure x Symfony
  • Mercure x API Platform