A Comprehensive Guide to Understanding and Integrating API Platform with Symfony 6

Aghar Saifeddine
4 min readJul 29, 2024

--

Introduction

A solid, resilient API is one of the basic building blocks for a project. In this guide, we’ll show you how to set up a fully functional REST API with Symfony and API Platform.

1. What is API Platform ?

Define API Platform:

  • API Platform is a framework designed for building and consuming APIs. It leverages Symfony and is built on top of it to provide a robust set of tools for creating APIs quickly and efficiently.

Key Features:

  • Automatic Documentation: API Platform automatically generates interactive API documentation using tools like Swagger or ReDoc.
  • CRUD Operations: It simplifies creating standard CRUD (Create, Read, Update, Delete) operations for your resources.
  • GraphQL Support: Out-of-the-box support for GraphQL, in addition to REST.
  • Data Serialization and Validation: Provides tools to serialize and validate data easily.

2. Setting Up API Platform

Prerequisites:

  • Ensure you have PHP, Composer, and Symfony installed.
  • Basic understanding of Symfony and PHP is beneficial.

Installation:

  1. Create a New Symfony Project:
composer create-project symfony/skeleton my_project

2. Install API Platform:

Install API Platform along with Doctrine and Maker Bundle for generating entities and other code:

composer require api maker doctrine

At this point, if you navigate to /api, you should see your API’s swagger documentation setup for you automatically.

Obviously, since we haven’t defined any API endpoints yet, it will be empty. It was set up by API-platform in the /config/routes/api_platform.yaml file and can be edited if you so desire. Here is a little snippet of the same

Configuration:

  • Briefly explain the configuration files and settings you need to adjust, such as api_platform.yaml.

3. Create the Database Configuration:

Configure your database connection in the .env file:

DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"

3. Creating Your First API

3.1 Create Entities:

Create the Book, Author, and Category entities.

Book Entity:

// src/Entity/Book.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ApiResource]
class Book
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;

#[ORM\Column(type: 'string', length: 255)]
#[Assert\NotBlank]
private string $title;

#[ORM\Column(type: 'date')]
#[Assert\NotBlank]
private \DateTimeInterface $publicationDate;

#[ORM\ManyToOne(targetEntity: Author::class, inversedBy: 'books')]
#[Assert\NotNull]
private ?Author $author = null;

#[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'books')]
private $categories;

// Getters and setters...
}

Author Entity:

// src/Entity/Author.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ApiResource]
class Author
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;

#[ORM\Column(type: 'string', length: 255)]
#[Assert\NotBlank]
private string $name;

#[ORM\OneToMany(targetEntity: Book::class, mappedBy: 'author')]
private $books;

// Getters and setters...
}

Category Entity:

// src/Entity/Category.php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
#[ApiResource]
class Category
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
private int $id;

#[ORM\Column(type: 'string', length: 255)]
#[Assert\NotBlank]
private string $name;

#[ORM\ManyToMany(targetEntity: Book::class, mappedBy: 'categories')]
private $books;

// Getters and setters...
}

3.2 Update Database Schema:

After creating the entities, update the database schema:

php bin/console doctrine:database:create
php bin/console doctrine:schema:update --force

3.3 Configure Serialization:

To control which properties are serialized, you can use serialization groups. Define them in the entity classes:

// src/Entity/Book.php

use Symfony\Component\Serializer\Annotation\Groups;

#[ORM\Entity]
#[ApiResource(
normalizationContext: ['groups' => ['book:read']],
denormalizationContext: ['groups' => ['book:write']]
)]
class Book
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column(type: 'integer')]
#[Groups(['book:read'])]
private int $id;

#[ORM\Column(type: 'string', length: 255)]
#[Assert\NotBlank]
#[Groups(['book:read', 'book:write'])]
private string $title;

#[ORM\Column(type: 'date')]
#[Assert\NotBlank]
#[Groups(['book:read', 'book:write'])]
private \DateTimeInterface $publicationDate;

#[ORM\ManyToOne(targetEntity: Author::class, inversedBy: 'books')]
#[Assert\NotNull]
#[Groups(['book:read', 'book:write'])]
private ?Author $author = null;

#[ORM\ManyToMany(targetEntity: Category::class, inversedBy: 'books')]
#[Groups(['book:read', 'book:write'])]
private $categories;

// Getters and setters...
}

3.4 Run the Server

Start the Symfony development server:

symfony server:start

You can now access the API documentation at http://localhost:8000/api .

3.5 Testing the API:

Use tools like Postman or cURL to test the endpoints. The generated Swagger UI provides an interactive interface for testing all CRUD operations on your entities.

Conclusion

This simple Bookstore API project demonstrates the power and ease of using API Platform with Symfony 6.4. You can expand this project by adding more features, such as user authentication, custom validation, and more complex relationships between entities. For detailed documentation and advanced features, visit the API Platform documentation.

References

--

--