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.—
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)
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:
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 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:
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.
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:
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:
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.
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).
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.
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
Today, an introduction blog post to Panther was published on the Symfony blog! Panther is a new browser testing and web scraping library I contributed to the Symfony project,
In the blog post, I showcase how to use Symfony, API Platform and VueJS together to create a small but modern app, and how to test it on Panther:
Today, the API Platform framework has reached 3k stars on GitHub, and it makes us very proud! To celebrate, I’ve just tagged the 2.3 version, that comes with a lot of amazing new features. Let’s discover them!
We’re committed to continuously improving the performance of API Platform. In version 2.1, we’ve added an amazing invalidation-based cache mechanism. When enabled, HTTP responses are generated only one time then stored and served by a reverse caching proxy. When a resource is modified, all responses including or referencing it are automatically removed from the cache.
A big thanks to Ben and to Nicolas Grekas from Blackfire.io for making it happen!
Support for API evolution (aka deprecating fields and resources)
A growing best practice is to use the evolution strategy for web APIs. Creating new versions of the API, of or its endpoints requires modifying all clients to upgrade, even the ones not impacted by the changes. On the other hand, this strategy (also known as versionless APIs) consists of deprecating the fields, resources types or operations that will be removed at some point. Most modern API formats including GraphQL, OpenAPI and Hydra are able to support this strategy.
In API Platform 2.3, we’ve introduced a new attribute to mark deprecated resource classes, operations and properties. All documentation formats generated by API Platform and having support for this feature will then automatically take it into account.
Here is how to deprecate an entire resource:
* @ApiResource(deprecationReason="Create a Book instead")
As you can see, to deprecate a resource, we just have to explain what the client should do to upgrade in a dedicated attribute. You can also use this new deprecationReason attribute on any operation.
The deprecation will automatically be taken into account by clients supporting the previously mentioned format. Here is how it renders for OpenAPI in the built-in Swagger UI shipped with the framework:
And now in the built-in version of GraphiQL (for GraphQL APIs):
It’s also possible to deprecate a single field:
* @ApiProperty(deprecationReason="Use the rating property instead")
All our client-side tools have been updated to ignore deprecated fields, operations and resources by default. The api-doc-parser library (which supports Hydra, and OpenAPI in the latest version) also support this new feature.
Dedicated Profiler Panel and Web Debug Toolbar Integration
Symfony comes with a nice set of development tools, including the Profiler, and it is compatible with API Platform! To install it, execute composer req profiler. Thanks to the contributions of Julien Deniau and Anthony Grassiot, the Web Debug Toolbar now displays an icon featuring our nice spider Webby that is linked to a new profiler panel dedicated to API Platform:
Shorter Attributes Syntax
Defining attributes using annotations can become verbose pretty quickly. As alternatives to annotations, for complex configurations API Platform also supports the XML and YAML formats. However, in version 2.3, Baptiste Meyer added a nicer and shorter syntax to define attributes on the @ApiResource and @ApiProperty annotations:
Of course the “old” syntax is still valid, but the new shortcuts allow a better discoverability and enable autocompletion in IDEs (if you are a PHPStorm user, install the PHP Annotations plugin to benefit from this new feature).
It uses React, and was built on top of the Admin On Rest library. But as you may know, Admin On Rest has been deprecated and Marmelab, the company behind the tool, has released a replacement called React Admin. React Admin comes with an updated fancy interface and it also fixes some design issues.
So we’ve patched API Platform Admin to use the new kid on the block, and we’ve taken this opportunity to also fix a well known annoying issue on our side: the Admin component wasn’t able to deal with embedded relations. This isn’t the case anymore. What’s even better, the Admin is now smart enough to reuse the data already downloaded as embedded relation instead of triggering a new HTTP request. It allows to dramatically improve the performance of the admin!
As usual, thank you very much to all the developers who’ve contributed these new features, bug fixes, and the related documentation entries. You’re the most important part of the project: the community.
The Symfony Serializer Component exists since the very beginning of Symfony 2. Years after years, it gained a lot of new features useful to transform various data formats to PHP structures and the opposite. It is also a foundation block of API Platform and a first-class citizen in FOSRest.
Let’s dive into this component. We will cover the basic concepts behind the serialization process: normalization, denormalization, encoding and decoding.
Then we will discover all the little known features of the component: JSON, XML and CSV support, file handling with “data:” URIs, serialization groups, attributes names conversion, trees support, updating existing objects, dealing with circular references.
Finally we will learn how to create custom normalizers and encoders; and how to modify the behavior of the builtin ones using composition.
GraphQL is an increasingly popular alternative to REST architectures for building web APIs.
The query language promoted by Facebook has undeniable advantages: retrieve exactly what the client need, limitation of the number of queries, strong typing, powerful and extremely well thought out syntax…
However, it also suffers from often underestimated problems including HTTP cache, logs, security or authentication, features that are the basis of the today’s web stack. GraphQL is also a non-standard format that requires a specific parser.
In addition, modern REST-based hypermedia formats such as JSON-LD or JSON API have features very similar to those of GraphQL (and more advanced ones) while remaining compatible with the fundamentals of the web.
The API Platform framework, based on Symfony, makes it easy to create REST APIs (JSON-LD, JSON API, HAL …) just like GraphQL.
After listing the advantages and disadvantages of different formats, we will study through different cases of frequent use when it is better to use GraphQL, REST or both in addition.