[slides] APIDays: Creating hypermedia APIs in a few minutes using the API Platform framework

My talk at APIDays:

API Platform is new open source PHP framework dedicated to the creation of modern web APIs.

It allows to bootstrap a fully featured API (pagination, validation, filtering, sorting, automatically generated documentation, HTTP cache, OAuth and JWT auth…) in just a few minutes.

It exposes out of the box popular API formats including Swagger, JSON-LD, Hydra, HAL, JSONAPI and Schema.org.
It is extensible and can be specialized with ease. Because it is built on top of the industry-leading Symfony framework, it already counts hundreds of available extensions (bundles).

In this talk, I’ll show how to create a hypermedia API in just a few lines of codes, then take a look to the main features of the framework.

Download the PPT (“download” button) to see screencasts!

API Platform 2.0 released: creating powerful web APIs has never been so easy

api-platform-demo

After 1 year of development and more than 700 commits authored by a hundred contributors across the world, the new major release of API Platform is immediately available for download.

API Platform is a PHP 7 framework dedicated to the creation of modern and powerful web APIs. It is especially adapted to build API-centric information systems relying on hypermediaLinked Data; and consumed by Single-Page Applications (using Javascript libraries such as React or Angular) and mobile apps.

API Platform 2 has been built with 3 strong opinions in mind:

  • Creating an API must be an easy and quick process: any web developper should be able to create a REST API in just a few minutes including CRUD support, data validation, filtering and sorting, autogenerated documentation, OAuth and JWT authentication, CORS and other security HTTP headers, caching
  • Modern open formats must be supported out of the box, without requiring any extra work for the developper: Swagger/OpenAPI, JSON-LD, Hydra, HAL, API Problem (RFC 7807) and Schema.org are supported out of the box, the powerful abstraction layer of the framework easily allows adding support for other emerging API formats (JSONAPI and GraphQL support is in progress)
  • Every feature of the framework must be extensible, overridable and modular

API Platform v2 is a massive rewrite of the framework, with tons of new features and bug fixes. The whole design has been rethinked, but let’s take a tour of the major new features and changes:

Revamped Config and Metadata: Exposing an API is a Matter of Seconds

Thanks to the new configuration system and the new metadata component, to create a high grade hypermedia API you just have to modelize your data model as a set of PHP classes then to add some annotations. Example:

This single class is enough to get a working API with the following features:

  • basic CRUD operations
  • data validation and error serialization
  • JSON-LD, Swagger, Hydra support (a lot of other formats can easily be added, see below)
  • pagination
  • an awesome UI and an extensive human-readable documentation reusing PHPDoc’s data and PHP metadata like types (see below)

Checkout our demo to play with a more advanced example (source code, only 2 classes)!

Hypermedia relations are handled out of the box. Leveraging any other feature of API Platform is just a matter of adding a few lines of configuration. Learn more in our getting started guide.

If you don’t like annotations, you can use XML or YAML configuration files instead. If you don’t like the Doctrine ORM (or doesn’t want to tight the exposed data model to the internal model of the database); or if you don’t want to use the Symfony validator, you can create adapters to hook your custom code and use your preferred libraries. API Platform is designed to be fully extensible.

Docker Integration

API Platform’s official distribution is shipped with a Docker setup adapted to API devlopment. It includes a Apache + PHP 7 and a MySQL image. To get an API Platform app up and running on your computer, type the following commands in the main directory:

The app is up and running, browse http://localhost to get started.

API Platform’s images can be deployed easily in production using Docker Swarm (Amazon Web Services, Azure…) or Google Container Engine (with Kubernetes).

A Data Model Generator on Steroid

Instead of crafting your own data model, why not reusing an open vocabulary like the very popular Schema.org and feel the power of Linked Data and Semantic Web? Yes, just like Google but for free.

Since its first release, API Platform comes with a handy code generator allowing to bootstrap a whole PHP data model including classes, properties, getters and setters, full PHPDoc, Doctrine mappings, API Platform’s external vocabulary mappings and validation annotations.

This generator has been updated to match the new configuration format of API Platform 2 and to allow generating custom classes and properties.

The following config file contains a selection of Schema.org’s types and properties. When using the generator to create the corresponding data model, a working API is created without writing a single line of PHP:

Learn more about the generator in the docs and the demo application.

Content Negotiation and Built-in Support for JSON-LD, Hydra, HAL, YAML, CSV and XML

API Platform now natively supports content negotiation (only JSON-LD and Hydra was previously supported) as well as most popular API formats. To be able to retrieve or send resources in a specifc format, you enable them in the configuration file:

This config enable all built-in formats (Symfony 3.2, actually in RC stage, is required for YAML and CSV support). Then, you can request the format you want through the UI using the proper Accept HTTP header, or by adding the format name as extension of any URL of the API (example: https://demo.api-platform.com/books.jsonld).

Support for formats not supported by default can be added by writing custom adapters.

Learn more about content negotiation in API Platform.

A Powerful UI and Automatic Swagger 2 Docs

API Platform 2 generates an extensive Swagger 2/OpenAPI documentation. All URLs and types are automatically described thanks to our powerful metadata extraction system.

A web interface built on top of Swagger UI is also automatically available. Request any API’s URL using a web browser and (thanks to the Accept header sent by the browser), API Platform will display the request sent to the API and the received response in a nice web interface. It will also display a human-readable documentation of the current operation.

api-platform-ui

Browse the homepage to see the documentation of all available operations, including the description of resources and properties extracted from PHP metadata. Use the sandbox to play with your API.

New Filters and Extension Mechanism

Several new built-in filters have been added. In addition to the existing search, date and range filters, the following are now available:

  • boolean: filter by a boolean property
  • numeric: search numeric fields

The filters are now available directly from the UI and documented in both Swagger and Hydra formats.

Learn how to add filters to your API collections.

Filters are now implemented using the brand new extension system. This system allows to hook to the database query generation process and to customize them. It’s particularly useful to implement security features.

Learn how to leverage the extension mechanism to filter the result of an entrypoint depending of the role of the connected user in the documentation.

Secure by default, tested against OWASP’s recommendations for REST APIs

API Platform 2 follows OWASP’s security recommendations for all its built-in features. We created a test suite to ensure that all recommendations applying to API Platform are followed and documented.

Checkout what API Platform 2 do to secure your API.

Improved performance

We are continuously improving the performance of API Platform and Symfony components it uses (like the Serializer or the PropertyAccess component). This new version is faster than v1 and automatically optimizes SQL queries regarding current serialization groups.

API Platform 2 is also compatible with PHP PM. When using it, API response times are divided by 10.

Availability as Standalone Components, Decoupled from Symfony and Doctrine

API Platform is designed as a set of standalone PHP components: the metadata system; JSON-LD, Hydra, Swagger, HAL serializers, Doctrine and Symfony components bridges…

All those components can be used separately to create your own APIs. For now, the Core library must be downloaded, but a subtree split to allow specific component installation will be available for the 2.1 version. Specific classes can already be used separately of the standard distribution, and without Symfony.

We also moved the code generic enough directly to Symfony. For instance the new Symfony’s PropertyInfo component has been extracted from API Platform.  Some new bug fixes and new features and like the MaxDepth as well as YAML and CSV support for the Symfony Serializer has been done while working on API Platform.

Doctrine has never been mandatory to use API Platform, but the set of interfaces to implement to use another persistence system has been rethought and is now documented.

Quality and QA improvements

We dramatically improved the quality of the API Platform code base for this v2. API Platform v1 was already well tested through Behat. In v2 we added a lot of unit tests to prevent bugs and prove that every class respect SOLID principles. The code coverage is now of 96%. Our test suite is automatically run both on Linux (using Travis) and Windows (using AppVeyor).

We also used Scrutinizr and SensioLabs Insight to detect bad practices and improve the overall quality of our code base. API Platform is rated 8.7/10 on Scrutinizr and has the Platinum medal (best rating) on Insight.

Documentation Rewrite and New Website

The documentation has been improved, almost all new features documented and the Getting Started guide fully rewrote. A new website built with React and Redux has also been created. It supports universal rendering and provides a powerful search engine thanks to Algolia’s DocSearch.

A Growing Community

API Platform it’s more than 100 contributors, an awesome core team (Amrouche HamzaAntoine BluchetSamuel ROZETeoh Han HuiThéo FIDRYVincent CHALAMON and myself), workshops and conferences talks across the world (don’t miss the workshop at the Berlin’s Symfony Con next week).

API Platform has been in the top GitHub trending PHP repositories several times during past months (and 1st one time) beside great projects like Laravel, Symfony and WordPress and has now more than 1k stars.

It’s amazing! Thanks to everybody having worked on the code base, contributed to the documentation or evangelized about the solution, you rock!

Training, development, professional services and workshops are also provided worldwide by Les-Tilleuls.coop, API Platform’s creators.

What’s next

The release of API Platform v2 is just the first step! We’re already working on new features and some of them are already ready to be merged in the 2.1 branch including:

More to come! Stay tuned!

If you haven’t already done it, it’s time to give a try to API Platform!

[Slides] Forum PHP: Create Symfony apps as quickly as with Laravel and keep your code framework-agnostic

Slides of my talk at AFUP’s Forum PHP 2016.

You’ll learn about RAD and autowiring, the ADR pattern, framework agnostic controllers, PSR-7, PSR-15 and PSR-17.

[Slides] Take Off Conf 2016: Creating a hypermedia API in 5 minutes with API Platform

This morning I was speaking about the API Platform framework at the Take Off Conf in my hometown of Lille. Take a look at my slides, and learn how to create a fully featured hypermedia API in a few minutes!

ADR pattern, autowiring, DunglasActionBundle: Symfony controllers redesigned

Here are the slides of the talk I gave yesterday at the Symfony meetup (sfPot) of Lille. I was presenting DunglasActionBundle, a refinement of the the Symfony controller system and talking about services autowiring and the ADR pattern.

The first alpha of API Platform 2.0 is available!

The first alpha of API Platform 2.0 has been released!

Take a look to this presentation to discover changes and new features of this version:

These slides have been presented first in the sfPot conference of Paris (May 17, 2016).

DunglasActionBundle 0.3.0 released!

DunglasActionBundle is an alternative controller system for the Symfony framework relying on autowiring and inspirited by the ADR pattern. Thanks to this bundle, controllers, commands and event listeners are automatically detected and registered as services. All their dependencies are also automatically registered. See the GitHub repository for an extensive documentation.

A lot of work have been done in  during the last months to improve the reliability and the usability of the bundle. Today I’m proud to announce a new release of this bundle (0.3.0). It is available on GitHub and includes the following changes:

  • Actions and controllers (src/*Bundle/Action and src/*Bundle/Controller directories), commands ( src/*Bundle/Command) and event listeners ( src/*Bundle/EventListener) are auto-registered by default
  • The name of auto-registered services are now the Fully Qualified Name of the registred class
  • Directories containing classes to auto-register as services are now configurable
  • Directories of third-party bundles (vendor/) are not tracked by default anymore
  • It’s not necessary anymore to clear the cache manually when a new class is added or removed from a tracked directory
  • If the class of an automatically registred service implements the ContainerAwareInterface, the container is automatically injected into it
  • It’s now possible to automatically add custom tags to auto-registered services
  • The custom routing annotation loader has been removed thanks to a bug fix in Symfony core (this feature still works out of the box)
  • The “autodiscover” feature has been removed, paths must be configured explicitly (regex supported)
  • The bundle can now be configured using the XML format
  • PHP 5.5 support has been added
  • Lot of a bug fixes

Thanks to @Ener-Getick, @stof and @weaverryan for their contributions and good design advices.

If you like this bundle, please give it a star on GitHub!

 

Making the Symfony PropertyAccess Component 84% faster in 2.8… and counting

Update 12/06/15: I’ve opened a PR making the PropertyAccess Component 84% faster than before. It implements strategies explained at the end of this post.

This PropertyAccess component allows to access to a property of an object (or a to a key of an array) regardless of the access strategy that must be used. It is smart enough to access directly to  public  properties and to use getters, setters, issers, adders, removers, magic methods and so on for private  and protected ones. It is also allows to access a property trough an object graph using a straightforward notation:  $propertyAccessor->getValue($rootObject, 'foo.bar.baz'); .

As you may know, some components of the Symfony framework including Form and the Serializer (see the ObjectNormalizer) rely heavily on it. The JSON-LD normalizer of the API Platform framework also use it intensively. In fact, more than 250+ open source projects rely on the PropertyAccess component (and it has been installed more than 1M times).

It’s a convenient and popular piece of software. But this convenience has a cost: the PropertyAccess component is slow: internally, it uses the PHP Reflection API to guesses what’s the strategy needed to read or write a property.

When using this component in a loop (ex: to normalize a collection of objects to an associative array using the ObjectNormalizer), its slowness become a significant problem.

Here is a benchmark for the PropertyAccess component:

And here is the profile generated by the awesome Blackfire.io: with Symfony 2.7.6:

As you can see the logic to guess the access strategy is executed at each loop iteration. As the structure of a PHP class generally never changes at runtime, a possible optimisation path is to guess the strategy to use for the property of a given class during the first iteration then cache it in an array. This way, the cached access strategy can be reused without extra computations every other time during the current execution thread.

Let’s try that:

Symfony PropertyAccess performance improvement

(Click on the image to read the full Pull Request description and the related code).

Thanks to this new caching strategy, the PropertyAccessor Component included in Symfony 2.7.7 (and more recent versions) is now 54% faster according to the same benchmark:

But the component can be even more optimized.

For instance, the constructor of the Symfony\Component\PropertyAccess\PropertyPath  class uses a slow regular expression. This constructor is still called at each iteration in a loop. The result of the regular expression isn’t cached:

A similar cache mechanism should be used to avoid executing the same regular expression at each iteration. I’ve started to work on a patch doing that, but it still needs some work before being ready to be merged in Symfony. This patch improves the performance of the PropertyAccess of 20% more. Using both patches, the component is 70% faster than in 2.7.6.

There is another promising way to improve the performance of this component: for now the access strategy is always guessed the first time a property is accessed during an execution thread (e.g. when handling an HTTP request). Using a permanent cache system (such as APC or Redis trough the Doctrine Cache library) in complement of the in-memory array would allow to guess the strategy only one time, (e.g. during the first HTTP request), then reuse it for each next executions. Symfony 3.1 will have this feature.

By the way, a similar optimization has been done on the ObjectNormalizer. It needs to know the list of properties of an object to normalize it. This list wasn’t cached either. In Symfony 2.8, it’s done:

Capture d’écran 2015-12-01 à 22.55.40

Thanks to this patch and to the optimization of the PropertyAccess component, the ObjectNormalizer is 40% faster in Symfony 2.8/3.0 than in Symfony 2.7.6!

My slides about API Platform from AFUP’s Forum PHP 2015

My slides from this morning at Forum PHP Paris about API Platform:

Open the slides in full screen

Introducing the phpdoc-to-typehint Converter: add scalar type hints and return type declarations to your projects

tl;dr Download phpdoc-to-typehint, it will automatically add scalar type hints and return type declarations to your PHP project using existing PHPDoc annotations.

PHP 7 will be released soon. Scalar type hints and return type declarations introduced in this new release are very interesting because they enforce the use of stricter types in PHP code. They are less error-prone and ease the maintenance. To quote the RFC: “These type declarations allow the PHP runtime to ensure that correctly-typed arguments are passed to functions, and make function signatures more informative.

At Les-Tilleuls.coop, we are always looking how we can improve the quality of some of our long running sensitive projects. On the other hand we are a gang of lazy leftists drinking beers late at night. Updating all our code bases to add scalar type hints and return type declarations will be a pain.

Hopefully, we’ve already done a similar work by writing an exhaustive PHPDoc including @param  and @return  tags describing PHP functions. It allows IDEs and static analysis tools such as Scrutinizr to detect potential bugs early in the development process. Here was born my idea: a tool using existing PHPDoc tags to automatically add scalar type hint and return types.

This command line tool is called phpdoc-to-typehint. You can download it as PHAR file on GitHub.

To use it, just run the following command:

php phpdoc-to-typehint.phar <my-project-directory>

Before:

After:

This tool is very experimental and can break your code. Be sure to have a backup of it (but you’re using Git right?) and run your test suite after the conversion. Bug reports are very welcomed.

It supports:

  • functions
  • methods of classes and traits
  • method definitions in interfaces
  • PHPDoc inheritance

The tool tries to preserve the existing indentation of source code files but it can create some strange indentations, especially when it adds return types. Run PHP CS Fixer to make your code following PSR-1 and PSR-2 conventions.

We can go back to the pub.