Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Components Laravel Package

hypervel/components

Hypervel Components packages a suite of Laravel-style building blocks—routing, validation, collections, and more—for the Hyperf coroutine framework, letting developers reuse familiar PHP patterns in high-performance, Swoole-powered applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Hypervel is Laravel-shaped, not Laravel. You keep Route::, DB::, Event::, Eloquent, and the container, but the runtime beneath them is a long-lived Swoole worker with coroutines. Budget your first hour for that shift in mental model, not for learning new syntax.

1. Confirm what you actually have. In a full Hypervel app the package is already a transitive dependency. Check before requiring it directly:

composer show hypervel/components
composer show hypervel/* | head -50

If you are adding it to a bare skeleton, pin the 0.3.x line exactly rather than floating:

composer require hypervel/components:~0.3.26

The 0.3.x line is pre-1.0. Patch releases have changed observable HTTP behaviour (v0.3.26 changed exception handling inside the middleware pipeline), so treat upgrades as reviewable changes, not background noise.

2. Find the bootstrap, not the Laravel bootstrap. There is no app/Http/Kernel.php equivalent to lean on. Look under config/autoload/ — typically middlewares.php for global middleware, plus dependencies.php, listeners.php, and annotations.php if you are using annotation-based routing. If the app uses a custom ConfigProvider, read that first; it is the real map of which components are wired in and in what order.

3. Read the source, not the Laravel docs. With 32 stars and a pre-1.0 API, blog posts and Stack Overflow answers will be about Laravel and will be wrong in the places that matter. The useful reading order:

  • vendor/hypervel/components/src/ — start with the HTTP kernel, Pipeline, and the exception handler.
  • src/docs/ in the repository — this is the source for the hypervel/docs package and is the closest thing to authoritative documentation.
  • The package test suite — the middleware and exception tests are the spec for the behaviour you are about to depend on.

4. First use case: prove the lifecycle to yourself. Write one middleware, throw from it, and observe where the exception surfaces.

namespace App\Http\Middleware;

use App\Exceptions\InvalidTokenException;
use Closure;

class EnsureTokenIsValid
{
    public function handle($request, Closure $next)
    {
        if ($request->getHeaderLine('X-Token') === '') {
            throw new InvalidTokenException();
        }

        return $next($request);
    }
}

Register it, hit the route without the header, and assert on the rendered status and body. That single test validates three things at once: middleware registration, the pipeline, and the exception handler's rendering path for pre-controller exceptions. It is also the regression test you will rerun on every package bump.

5. Then prove the coroutine part. The second test should be concurrency, not features. Hit the same endpoint from many coroutines with different request-scoped values and assert none bleed into each other. If that passes, you understand the framework well enough to build on it.

Implementation Patterns

Write middleware the boring way

Cross-cutting transport concerns belong in middleware: auth, request/correlation IDs, CORS, rate limiting, tenant resolution, response decoration. Business rules belong in services. This is unchanged from Laravel and it is the pattern the pipeline is built to support.

Route::middleware(['auth', EnsureTokenIsValid::class])->group(function () {
    Route::get('/orders', [OrderController::class, 'index']);
});

Throw; do not hand-roll error responses

Since v0.3.26, exceptions raised inside the pipeline are handled as part of the pipeline rather than escaping unpredictably. Lean on that: throw a domain or HTTP exception and let the handler render it, so error shape stays consistent between middleware and controllers.

public function handle($request, Closure $next)
{
    $tenant = $this->resolveTenant($request);

    if (! $tenant) {
        throw new TenantNotFoundException();
    }

    $request = $request->withAttribute('tenant', $tenant);

    return $next($request);
}

Pass request-scoped data downstream via request attributes or coroutine context — never by assigning to a property on the middleware instance.

Convert exceptions, do not swallow them

The one legitimate reason to catch in middleware is to translate a low-level failure into something the framework's handler can render meaningfully:

try {
    return $next($request);
} catch (TenantResolutionException $e) {
    throw new HttpException(400, $e->getMessage(), $e);
}

A blanket catch (Throwable $e) here does two bad things: it bypasses the new pipeline handling, and it hides errors from your monitoring while returning plausible-looking 200s.

Order the global stack deliberately

A workable default:

  1. Request / correlation ID
  2. Trusted proxies and host checks
  3. CORS
  4. Authentication
  5. Tenant resolution
  6. Authorization
  7. Route-specific middleware
  8. Response decoration and timing

Global middleware runs on health checks, metrics endpoints, and error routes too. Keep each entry cheap and safe to fail.

Resolve per-request state from the container correctly

This is the biggest day-to-day difference from Laravel. A singleton resolved at boot survives every request in that worker. Anything request-scoped — the current user, tenant, correlation ID, an authenticated guard instance — must live in coroutine-scoped storage (Hypervel's CoroutineContext) or in request attributes, and must be scoped bindings rather than plain singletons.

// Wrong: persists across requests in the same worker.
$this->app->singleton(CurrentTenant::class, fn () => new CurrentTenant());

// Right: one instance per coroutine/request.
$this->app->scoped(CurrentTenant::class, fn () => new CurrentTenant());

Audit third-party packages for singleton() registrations holding request state. It is the single most common source of cross-request contamination when porting Laravel code.

Test middleware as HTTP behaviour

Feature-test the route, not the middleware class in isolation. Asserting status codes, headers, and JSON shape is what catches pipeline-ordering and exception-rendering regressions — the exact class of bug that patch releases in this package have fixed.

public function test_missing_token_returns_json_error(): void
{
    $this->getJson('/orders')
        ->assertStatus(401)
        ->assertJsonStructure(['message']);
}

Use terminable middleware for side effects only

Logging and metrics after the response is sent are a good fit. Response mutation is not — by termination time the response already exists.

Gotchas and Tips

  • Long-lived workers are the whole ballgame. Static properties, singleton registries, manager caches, config, and resolved callbacks persist for the worker's life. Any state you assumed would be garbage-collected at end-of-request now is not. When something behaves correctly on the first request and wrongly on the second, this is almost always why.

  • Never store request data on a middleware instance. Middleware is typically resolved once and reused. Use $request->withAttribute(...) or coroutine context.

  • The v0.3.26 exception fix changes observable behaviour. There are no advertised breaking changes, but exceptions that previously escaped to the global handler may now be handled in the pipeline. After upgrading, rerun every middleware feature test — especially ones that asserted on generic 500s or on exceptions propagating out — and diff status codes, response bodies, and log volume against the previous version.

  • Watch for silently swallowed errors. If exception rates drop after an upgrade rather than staying flat, that is a red flag, not an improvement. Alert on exception-rate drops as well as spikes during the rollout window.

  • Do not catch (Throwable). Broad catches in middleware bypass the pipeline's handling and defeat the framework's error rendering. Catch narrow types and rethrow.

  • Always return. Middleware must return $next($request) or a real response object. A missing return produces a null downstream and confusing failures well away from the actual bug.

  • Call $next($request) exactly once. Conditional short-circuiting is fine; invoking the next handler twice duplicates side effects and can corrupt the response.

  • Global middleware has a wide blast radius. A failing global middleware takes out health checks, metrics, and error routes simultaneously — the worst time to lose observability. Register narrowly and explicitly test failure paths.

  • Custom exception renderers need to cover pre-controller exceptions. If you have your own rendering logic, verify it handles exceptions thrown before the controller is reached, not just ones thrown inside it.

  • Clear cached config after middleware changes. If the app caches configuration, registration and alias changes will not take effect until the cache is rebuilt. This burns people repeatedly on first setup.

  • Pin and read the changelog. Pre-1.0 means no semver guarantee across minor versions. Pin to ~0.3.26, and treat each upstream patch as something to review and test rather than something to absorb passively. The maintainer ships small, frequent patches — plan for a steady drip.

  • The release notes are thin; the tests are the spec. With a single-line changelog entry, the diff and the accompanying test are your only real documentation of a behaviour change. Read both before upgrading.

  • Your middleware test suite is the artifact that protects you. Not the version pin. Invest in it early; it is what makes upgrades cheap.

  • Escape hatch. Single-maintainer project at 32 stars. Establish an internal owner for the dependency and keep a documented fork-or-patch path for the day upstream goes quiet or a fix is needed faster than a release.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core