Mastering Symfony: Building Enterprise-Level PHP Applications
Course Title: Mastering Symfony: Building Enterprise-Level PHP Applications
Section Title: API Platform and GraphQL
Topic: Build a fully-featured API using API Platform with pagination, filtering, and GraphQL support.(Lab topic)
Objective: By the end of this topic, you will be able to design, build, and deploy a fully-featured API using API Platform, with support for pagination, filtering, and GraphQL queries.
Prerequisites:
- Familiarity with Symfony framework and its components
- Understanding of REST principles and API development
- Experience with Symfony controllers, serializer component, and API authentication
Introduction: API Platform is a powerful tool for building robust, scalable, and maintainable APIs in Symfony. In this topic, we will explore how to use API Platform to build a fully-featured API with support for pagination, filtering, and GraphQL queries.
Step 1: Setting up API Platform
To start building our API, we need to install API Platform using Composer:
composer require api-platform/core
Next, we need to configure API Platform by creating a config/packages/api_platform.yaml
file:
api_platform:
default_platform: 'api_platform'
platforms:
api_platform:
routes:
resource_class: 'ApiPlatform\Core\Resource\ResourceClass'
route_prefix: '/api'
Step 2: Defining our API Entities
We need to define our API entities using the ApiPlatform\Core\Entity\Entity
class:
// src/Entity/User.php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Annotation\Filter;
use ApiPlatform\Core\Annotation\Search;
use Doctrine\ORM\Mapping as ORM;
/**
* @ApiResource
* @Filter("Range")
* @Search("fulltext")
*/
class User
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string")
*/
private $name;
/**
* @ORM\Column(type="string")
*/
private $email;
// getters and setters
}
Step 3: Creating our API Controller
We need to create an API controller that will handle our API requests:
// src/Controller/UserController.php
namespace App\Controller;
use App\Entity\User;
use ApiPlatform\Core\Controller\ApiPlatformController;
use ApiPlatform\Core\Serializer\SerializerInterface;
class UserController extends ApiPlatformController
{
private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
/**
* @GET("/users", name="get_users")
*/
public function getUsers(): Response
{
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
return $this->json($users, 200);
}
/**
* @GET("/users/{id}", name="get_user")
*/
public function getUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
return $this->json($user, 200);
}
/**
* @POST("/users", name="create_user")
*/
public function createUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 201);
}
/**
* @PUT("/users/{id}", name="update_user")
*/
public function updateUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 200);
}
/**
* @DELETE("/users/{id}", name="delete_user")
*/
public function deleteUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
if ($user) {
$this->getDoctrine()->getManager()->remove($user);
$this->getDoctrine()->getManager()->flush();
}
return $this->json(['message' => 'User deleted successfully'], 200);
}
}
Step 4: Adding Pagination, Filtering, and GraphQL Support
To add pagination, filtering, and GraphQL support to our API, we need to use the ApiPlatform\Core\Serializer\SerializerInterface
to serialize our data.
First, we need to add pagination support:
// src/Controller/UserController.php
use ApiPlatform\Core\Serializer\SerializerInterface;
class UserController extends ApiPlatformController
{
private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
/**
* @GET("/users", name="get_users")
*/
public function getUsers(int $page = 1, int $limit = 10): Response
{
$users = $this->getDoctrine()->getRepository(User::class)->paginate($page, $limit);
return $this->json($users, 200);
}
/**
* @GET("/users/{id}", name="get_user")
*/
public function getUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
return $this->json($user, 200);
}
/**
* @POST("/users", name="create_user")
*/
public function createUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 201);
}
/**
* @PUT("/users/{id}", name="update_user")
*/
public function updateUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 200);
}
/**
* @DELETE("/users/{id}", name="delete_user")
*/
public function deleteUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
if ($user) {
$this->getDoctrine()->getManager()->remove($user);
$this->getDoctrine()->getManager()->flush();
}
return $this->json(['message' => 'User deleted successfully'], 200);
}
}
Next, we need to add filtering support:
// src/Controller/UserController.php
use ApiPlatform\Core\Serializer\SerializerInterface;
class UserController extends ApiPlatformController
{
private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
/**
* @GET("/users", name="get_users")
*/
public function getUsers(int $page = 1, int $limit = 10, string $filter = null): Response
{
$users = $this->getDoctrine()->getRepository(User::class)->paginate($page, $limit);
if ($filter) {
$users = $users->filterBy($filter);
}
return $this->json($users, 200);
}
/**
* @GET("/users/{id}", name="get_user")
*/
public function getUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
return $this->json($user, 200);
}
/**
* @POST("/users", name="create_user")
*/
public function createUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 201);
}
/**
* @PUT("/users/{id}", name="update_user")
*/
public function updateUser(User $user): Response
{
$this->getDoctrine()->getManager()->persist($user);
$this->getDoctrine()->getManager()->flush();
return $this->json($user, 200);
}
/**
* @DELETE("/users/{id}", name="delete_user")
*/
public function deleteUser($id): Response
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
if ($user) {
$this->getDoctrine()->getManager()->remove($user);
$this->getDoctrine()->getManager()->flush();
}
return $this->json(['message' => 'User deleted successfully'], 200);
}
}
Finally, we need to add GraphQL support: ```php // src/Controller/UserController.php
use ApiPlatform\Core\Serializer\SerializerInterface; use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\Field; use GraphQL\Type\Definition\InputObjectType;
class UserController extends ApiPlatformController { private $serializer;
public function __construct(SerializerInterface $serializer)
{
$this->serializer = $serializer;
}
/**
* @GET("/graphql", name="graphql")
*/
public function getGraphQL(): Response
{
$schema = new GraphQLSchema([
'query' => new ObjectType([
'name' => 'User',
'fields' => [
new Field('id', Type::int()),
new Field('name', Type::string()),
new Field('email', Type::string()),
],
]),
'mutation' => new ObjectType([
'name' => 'User',
'fields' => [
new Field
Images

Comments