Skip to content

v3.18.0

Latest

Choose a tag to compare

@spiralbot spiralbot released this 27 Oct 11:21
83cd3e4

New features

1. QUERY HTTP verb

The router supports the QUERY method from RFC 10008: a safe, idempotent request that carries its query in the body. Routes without explicit verbs accept it too, and route:list shows it in its own color.

use Spiral\Router\Annotation\Route;

#[Route(route: '/products/search', methods: ['QUERY'])]
public function search(ServerRequestInterface $request): array
{
    // the search criteria come in the request body
}

QUERY is not in CsrfFirewall::ALLOW_METHODS, so such requests still require a CSRF token.

by @gam6itko in #1314

2. HTTP spans follow the stable OpenTelemetry semantic conventions

The server span written by spiral/http now uses the stable HTTP semantic conventions, so tracing backends (Jaeger, Tempo, Grafana, Datadog, Honeycomb, …) recognise it in their HTTP views and RED metrics.

  • The span is named after the request method (GET) instead of the full URL, which removes unbounded span-name cardinality.
  • Request headers (http.headers) are no longer exported, so Authorization and Cookie values do not reach the tracing backend.
  • The status stays unset below 500 instead of OK; a 5xx sets ERROR and error.type.
Before Now
http.method http.request.method
http.url url.scheme, url.path, url.query, server.address, server.port
http.status_code http.response.status_code
http.response_content_length http.response.body.size
http.headers removed
— client.address, user_agent.original, network.protocol.version

The middleware spans of the deprecated Pipeline get the same status and response attribute changes.

by @roxblnfk in #1312

3. MailerInterface can be overridden or decorated

MailerBootloader used to bind MailerInterface from its boot() method, which runs after every bootloader has registered its bindings, so an application binding of the mailer was always overwritten. The binding now lives in the singleton map next to an explicit MailQueue binding, and the usual last-registration-wins order applies:

final class AppMailerBootloader extends Bootloader
{
    protected const SINGLETONS = [
        MailerInterface::class => [self::class, 'mailer'],
    ];

    private function mailer(MailQueue $queue, LoggerInterface $logger): MailerInterface
    {
        return new LoggingMailer($queue, $logger);
    }
}

by @gam6itko in #1302

Upgrade notes

  • Telemetry: dashboards, alerts and queries that filter on the old attributes, the old span name or status OK need to switch to the new keys. There is no dual-emission mode; if you need a transition period, rename the attributes in your OpenTelemetry Collector (transform processor).
  • Mailer: MailerBootloader::boot() no longer takes BinderInterface; a subclass overriding boot() must drop that parameter. An application binding of MailerInterface now takes effect instead of being silently replaced by MailQueue.
  • SendIt: HTML comments are now stripped from the HTML part of emails built on sendit:builder. Outlook conditional comments and the content of <style>, <script>, <textarea> and <title> are kept.
  • Development branch: master is renamed to 3.x in spiral/framework and in every split package, and the dev-master branch aliases are gone. If you require a development version, replace dev-master with 3.x-dev.

Other

  • [spiral/sendit] Strip HTML comments from the rendered HTML part by @gam6itko in #1315
  • [spiral/http] Pass EventDispatcher into the HTTP core by @roxblnfk in #1292
  • Releases are now prepared by release-please from conventional-commit PR titles by @roxblnfk in #1317

Full Changelog: 3.17.2...3.18.0