Symfony is a PHP web application framework and a set of reusable PHP components/libraries.
Symfony is a powerful PHP framework for building scalable, complex web applications. It follows the Model-View-Controller (MVC) pattern, which separates application logic from presentation, ensuring better maintainability. Symfony’s modular architecture relies on reusable components and bundles that act as plugins, enabling easy customization and extension.
Key features include platform and database engine independence, enterprise-ready architecture, and extensive customization options. Its component-based approach allows developers to use libraries independently, while its templating system supports content localization and internationalization. With robust security features and strong community support, Symfony is perfect for high-performance, scalable web applications.
Integrating Symfony with Strapi combines the strengths of both platforms, addressing their limitations while creating a powerful and flexible solution.
Here are the main advantages of using Strapi alongside Symfony:
The integration works well because it leverages the strengths of both platforms in a complementary way:
Integrating Symfony with Strapi results in more maintainable, scalable, and content-rich web applications, which are ideal for projects requiring frequent content updates or multi-channel content delivery.
Integrating Symfony with Strapi provides enhanced content management for your Symfony application. This guide walks you through three key steps: setting up your development environment, creating a basic Strapi API, and connecting Symfony to the Strapi API.
Before diving in, make sure you have these tools installed:
To set up your development environment:
composer create-project symfony/website-skeleton my-symfony-projectnpx create-strapi@latest my-strapi-projectcd my-strapi-project
npm run developWith your environment ready, let's create a simple API in Strapi:
To generate an API token for secure communication:
Let's connect your Symfony app to the Strapi API:
composer require symfony/http-client// src/Service/StrapiClient.php
namespace App\Service;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class StrapiClient
{
private $httpClient;
private $strapiUrl;
public function __construct(HttpClientInterface $httpClient, string $strapiUrl)
{
$this->httpClient = $httpClient;
$this->strapiUrl = $strapiUrl;
}
public function getArticles(): array
{
$response = $this->httpClient->request('GET', "{$this->strapiUrl}/api/articles", [
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['STRAPI_API_TOKEN'],
],
]);
return $response->toArray();
}
}.env file:STRAPI_API_URL=http://localhost:1337
STRAPI_API_TOKEN=your_api_token_here// src/Controller/ArticleController.php
namespace App\Controller;
use App\Service\StrapiClient;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ArticleController extends AbstractController
{
#[Route('/articles', name: 'article_list')]
public function list(StrapiClient $strapiClient): Response
{
$articles = $strapiClient->getArticles();
return $this->render('articles/list.html.twig', [
'articles' => $articles['data'],
]);
}
}{# templates/articles/list.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Articles</h1>
{% for article in articles %}
<h2>{{ article.title }}</h2>
<p>{{ article.content }}</p>
{% endfor %}
{% endblock %}To improve performance, you can implement caching:
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
public function getArticles(): array
{
return $this->cache->get('articles', function (ItemInterface $item) {
$item->expiresAfter(3600); // Cache for 1 hour
$response = $this->httpClient->request('GET', "{$this->strapiUrl}/api/articles", [
'headers' => [
'Authorization' => 'Bearer ' . $_ENV['STRAPI_API_TOKEN'],
],
]);
return $response->toArray();
});
}Following these steps can help you integrate Symfony with Strapi for seamless content management and application logic separation. Depending on your needs, consider using Strapi's REST or GraphQL APIs and optimizing your application with caching and security features. As your application grows, automate tasks with Strapi and consider webhook integration for real-time updates. This approach provides scalability, flexibility, and efficient content delivery.
Let's explore a practical example of integrating Symfony with Strapi in an e-commerce platform. This integration leverages Symfony’s strengths in handling complex business logic and Strapi’s robust content management capabilities.
Our e-commerce platform uses Symfony to handle complex business logic, user authentication, and order processing, while Strapi manages product information, categories, and marketing content.
Below are some of the core areas where integration typically occurs and how each platform contributes:
Bringing Symfony and Strapi together requires thoughtful setup on both sides: content modeling in Strapi and robust API integration in Symfony. This section outlines how we structured content within Strapi and shows example code for fetching and displaying that content through Symfony.
Proper content modeling in Strapi is crucial for a scalable and maintainable application.
Product
- Name (string)
- Description (rich text)
- Images (media)
- Category (relation)
- Specifications (component)
Category
- Name (string)
- Description (text)
- Image (media)
MarketingBanner
- Title (string)
- Subtitle (string)
- Image (media)
- LinkURL (string)While implementing our project, we decided to upgrade, updating to Strapi 5, to take advantage of its new features and improvements.
Here's a simplified example of a Symfony service that interacts with Strapi's API:
// src/Service/StrapiProductService.php
namespace App\Service;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\Cache\CacheInterface;
class StrapiProductService
{
private $httpClient;
private $cache;
private $strapiUrl;
public function __construct(HttpClientInterface $httpClient, CacheInterface $cache, string $strapiUrl)
{
$this->httpClient = $httpClient;
$this->cache = $cache;
$this->strapiUrl = $strapiUrl;
}
public function getProduct(int $id): array
{
return $this->cache->get('product_'.$id, function() use ($id) {
$response = $this->httpClient->request(
'GET',
$this->strapiUrl.'/api/products/'.$id.'?populate=*'
);
return $response->toArray();
});
}
public function listProducts(array $filters = []): array
{
$queryString = http_build_query($filters);
$cacheKey = 'products_list_'.md5($queryString);
return $this->cache->get($cacheKey, function() use ($queryString) {
$response = $this->httpClient->request(
'GET',
$this->strapiUrl.'/api/products?'.$queryString
);
return $response->toArray();
});
}
}// src/Controller/ProductController.php
namespace App\Controller;
use App\Service\StrapiProductService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
#[Route('/product/{id}', name: 'product_show')]
public function show(int $id, StrapiProductService $productService): Response
{
$product = $productService->getProduct($id);
if (!$product) {
throw $this->createNotFoundException('Product not found');
}
return $this->render('product/show.html.twig', [
'product' => $product,
]);
}
#[Route('/products', name: 'product_list')]
public function list(StrapiProductService $productService): Response
{
$products = $productService->listProducts([
'pagination[page]' => 1,
'pagination[pageSize]' => 20,
'sort' => 'name:asc'
]);
return $this->render('product/list.html.twig', [
'products' => $products,
]);
}
}Here are some potential positive outcomes of the project:
If you have any questions about Strapi 5 or just would like to stop by and say hi, you can join us at Strapi's Discord Open Office Hours, Monday through Friday, from 12:30 pm to 1:30 pm CST: Strapi Discord Open Office Hours.
For more details, visit the Strapi documentation and the Symfony documentation.
Symfony is a powerful PHP framework used to build scalable web applications. Integrating Symfony with Strapi allows you to manage content with Strapi’s headless CMS while using Symfony for business logic, authentication, and more complex backend operations. The integration uses Strapi’s APIs to fetch and display content within Symfony-powered applications.
Strapi and Symfony complement each other well by dividing responsibilities. Strapi handles content management with its flexible and user-friendly interface, while Symfony takes care of complex business logic and back-end operations. This separation of concerns makes it easier to scale your application, improve collaboration between teams, and manage content efficiently.
To integrate Symfony with Strapi, start by setting up Strapi and creating content types for your application. Then, use Symfony’s HTTP client to fetch data from Strapi’s API (either RESTful or GraphQL). Use environment variables to securely store Strapi API URLs and authentication tokens, and create a Symfony service to manage the API calls and cache responses for better performance.
Strapi uses JWT (JSON Web Tokens) for API authentication. You can obtain a JWT token by using Strapi's authentication endpoint (/auth/local). Once authenticated, use this token to make secure requests to protected endpoints within Strapi, ensuring that only authorized users can access the content.
Yes, Strapi supports multilingual content management through the i18n plugin. This allows you to create and manage content in multiple languages. Symfony can then consume these multilingual content types via Strapi’s API and display them in the appropriate language based on user preferences or browser settings.
Strapi’s RBAC feature allows you to define fine-grained permissions for different users or roles. When integrating with Symfony, you can use Strapi’s permission system to control access to content and API endpoints, ensuring that only authorized users or teams can access specific data or perform certain actions. Symfony’s user authentication system can be synchronized with Strapi’s roles and permissions for seamless access control.
Both Strapi and Symfony support various databases like MySQL, PostgreSQL, and SQLite. Strapi uses these databases to store content, while Symfony connects to the same database for managing user authentication, sessions, and other application-specific data. You can configure the database for Strapi and Symfony independently or choose a shared database for both systems to streamline data management.
The best deployment strategy for Strapi and Symfony depends on your needs. You can host Strapi on a separate server (e.g., DigitalOcean, AWS, Heroku) and deploy Symfony on your preferred platform. Alternatively, you can use Docker to containerize both applications, ensuring that they run independently while communicating via their APIs. For more advanced setups, consider using Kubernetes for orchestration and scaling.
You can implement caching in your Symfony application using tools like Redis or Symfony’s built-in caching mechanisms. Cache Strapi API responses to reduce database load and improve performance, especially for frequently accessed data. Additionally, Symfony services can cache the content fetched from Strapi and update it periodically or when content changes.