API Endpoint
Table of contents
Loading...Introduction
To allow an external client to interact with the backend application, an API access can be provided.
The API should be stateless, meaning that the server does not store any session information about the client. Each request from the client must contain all the information necessary to process the request.
Here are some best practices.
- Use RESTful principles: REST (Representational State Transfer) is a set of constraints for building web services. It is stateless and uses HTTP methods explicitly.
- Use HTTP status codes: These codes provide a quick way for clients to understand the general outcome of their request.
- Use descriptive URLs and actions: URLs should represent resources (nouns), and HTTP methods should represent actions on the resources.
- Rate limiting: Protect your API from being overwhelmed by too many requests.
- Security: Use standard authentication methods like OAuth or JWT and use HTTPS.
Allow client to make requests
Browsers have a security feature implemented to prevent unauthorized access and sharing of resources between different origins (domains, protocols, or ports). This is known as the same-origin policy, which allows scripts running on pages originating from the same site to make server requests with no specific restrictions, but prevents access to most methods and properties across pages on different sites.
This means that if a client is hosted on a different domain, it can't make requests to the backend application.
CORS is a mechanism that allows the server to tell the browser to relax the same-origin policy for its resources, and to allow specific cross-origin requests (i.e. requests from a different domain). This is done by the server sending specific HTTP headers that tell the browser which origins are allowed, which HTTP methods can be used, whether credentials can be included, and more.
The browser sends a "preflight" request to the server
with the HTTP method OPTIONS
to check if the server allows the actual request.
Enable CORS in Slim
To enable CORS in a Slim application, you can use a Middleware that adds the necessary headers to the response before sending it out.
Here is an example of a CORS Middleware that allows requests from any origin, with any HTTP method, and with credentials included.
File: src/Application/Middleware/CorsMiddleware.php
<?php
namespace App\Application\Middleware;
use App\Infrastructure\Utility\Settings;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
final readonly class CorsMiddleware implements MiddlewareInterface
{
private ?string $allowedOrigin;
public function __construct(private ResponseFactoryInterface $responseFactory, Settings $settings)
{
$this->allowedOrigin = $settings->get('api')['allowed_origin'] ?? null;
}
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
// Handle all "OPTIONS" pre-flight requests with an empty response
// https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
if ($request->getMethod() === 'OPTIONS') {
// Skips the rest of the middleware stack and returns the response
$response = $this->responseFactory->createResponse();
} else {
// Continue with the middleware stack
$response = $handler->handle($request);
}
// Add response headers in post-processing before the response is sent
// https://samuel-gfeller.ch/docs/Middleware#order-of-execution
$response = $response
->withHeader('Access-Control-Allow-Credentials', 'true')
->withHeader('Access-Control-Allow-Origin', $this->allowedOrigin ?? '*')
->withHeader('Access-Control-Allow-Headers', '*')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->withHeader('Pragma', 'no-cache');
// Handle warnings and notices, so they won't affect the CORS headers
if (ob_get_contents()) {
ob_clean();
}
return $response;
}
}
To use the Middleware, you can add it to a specific route / route group or
to the Middleware stack in the config/middleware.php
file if it should be applied
to all routes.
Add CORS middleware to a route group
Add cors headers to a specific route group only.
File: config/routes.php
// ...
$app->group('/api', function (RouteCollectorProxy $group) {
$group->get('/example', ExampleAction::class);
$group->post('/example', ExampleAction::class);
})->add(\App\Application\Middleware\CorsMiddleware::class);
// ...
Add CORS middleware to the middleware stack
Add cors headers to all routes.
File: config/middleware.php
return function (Slim\App $app) {
// ...
// Last middleware in the stack
$app->add(\App\Application\Middleware\CorsMiddleware::class);
};