Jardis App-Layer - HTTP delivery for Jardis domains: FastRoute router behind own interface, PSR-15 pipeline, canonical DomainResponse-to-PSR-7 mapper, kernel bootstrap bridge

Maintainers

Package info

github.com/jardisCore/app

pkg:composer/jardiscore/app

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 1

v1.0.0 2026-07-17 05:11 UTC

This package is auto-updated.

Last update: 2026-07-17 05:26:25 UTC


README

Build Status Latest Version License: MIT PHP Version PHPStan Level PSR-12 PSR-7 PSR-15

Part of Jardis — the Domain-Driven Design platform for PHP. You model your domain; Jardis generates the production-ready hexagonal code. jardiscore/kernel is the runtime the generated code runs on; this package is the HTTP delivery layer around it.

The Request/Response-Handling offer for Jardis-generated domains. FastRoute behind an own, narrow interface, a PSR-15 middleware pipeline, one canonical DomainResponse → PSR-7 mapper, and a thin bootstrap bridge around the Koffer (BuildDomainKernelFromEnv) — nothing more.

Bleiben ist der erwartete Normalfall — Wechseln ist die garantierte Freiheit. No Jardis domain ever imports this package (a maschinell prüfbare Struktur-Eigenschaft, not a promise — see Wandfreiheit below); a fremd-framework can answer the exact same client-facing envelope contract this package implements, without depending on it at all (see examples/symfony-demo/).

Why Jardis App?

Between "an HTTP request arrives" and "$domain->…->process(…) gets called" there was no Jardis offer — building a Jardis-backed HTTP API meant pulling in Laravel or Symfony just for routing and response mapping. This package closes that gap with a deliberately small core:

  • FastRoute, but swappable. nikic/fast-route sits behind Contract\RouterInterface — an implementation detail, not a commitment.
  • PSR-15 pipeline. Global and per-route middleware, Chain-of-Responsibility ordering (global wraps route-specific), deterministic within each group. Any PSR-15-conformant ecosystem package (auth, CORS, request-id, …) runs without an adapter.
  • One canonical mapper. Every DomainResponseInterface — success or error, domain- or boundary-produced — becomes the same {status, data, errors, meta} JSON envelope (vendor/jardissupport/contract/docs/response-envelope.md). No consumer builds this translation by hand again.
  • A thin bootstrap bridge. Wraps the Koffer's own BuildDomainKernelFromEnv (ENV → DomainKernel) and the Builder-generated domain composition (App/bootstrap.php) with the one thing missing: an HTTP entry point around them.
  • A defined boundary-error contract. 404/405 (with a spec-correct Allow header)/500 all answer in the same envelope as a domain error — a client never has to guess whether "404" came from the domain or from no route matching at all.
  • A Raw-Body invariant. The request body is read from php://input exactly once, into a seekable stream; JSON parsing is lazy and never replaces it — getBody() stays byte-identical for the whole pipeline (the webhook-HMAC case).

Wandfreiheit

The "no domain depends on this package" guarantee is a structural property, not an example: tests/Acceptance/WallFreedomHarnessTest.php checks every vendored domain's composer dependencies and namespace imports for a dependency on jardiscore/app — none exists, and none may. examples/symfony-demo/ illustrates what that freedom buys a consumer: the same generated domain, answering the same envelope contract, behind Symfony instead of this package's own router — with zero jardiscore/app import anywhere in that demo's composer.json or code.

Installation

composer require jardiscore/app

Quickstart

See docs/getting-started.md for the full, runnable public/index.php recipe (install → ENV/Koffer-Bootstrap → domain registration → first route + handler → start → first request — under 15 minutes with a prepared environment, K6). It also covers API versioning (M9), the jardissupport/validation growth path, and the N1 deployment stellschrauben (body-size limits, Trusted-Proxy, display_errors).

Examples

  • examples/basic/ — the recipe above wired against a REAL Builder-generated domain (Ecommerce/Sales) over MySQL: GET/POST/PATCH /orders, the 422 rule-violation payload, 404/405/500 boundary cases, and a real PSR-15 ecosystem middleware.
  • examples/symfony-demo/ — the N3 austauschbarkeits-illustration: the same fixture domain behind a Symfony front controller, fulfilling the same envelope contract, without importing this package.

Requirements

  • PHP >=8.3
  • jardiscore/kernel ^2.0
  • jardissupport/contract ^2.1

Related Packages

Package Purpose
jardiscore/kernel The Koffer (DomainKernel) + ENV-Packer this package's bootstrap bridge builds on
jardissupport/contract DomainResponseInterface, ResponseStatus, the response-envelope contract doc
jardissupport/validation Object-graph validation — the growth path beyond the handler's own trivial type coercion (F8)

Documentation

Full documentation, guides, and API reference:

docs.jardis.io/en/core/app

License

Jardis is open source under the MIT License. Free for any purpose — commercial or non-commercial.

Jardis — Development with Passion Built by Headgent Development

AI-Assisted Development

This package ships with a skill for Claude Code, Cursor, Continue, and Aider. Install it in your consuming project:

composer require --dev jardis/dev-skills

More details: https://docs.jardis.io/en/skills