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

Http Status Code Laravel Package

juststeveking/http-status-code

PHP package that turns HTTP status codes into a typed enum, with helpers for messages, code categories and Laravel validation. Replace magic numbers with descriptive cases for clearer, safer API and controller responses—no more guessing what 418 means.

View on GitHub
Deep Wiki
Context7

Getting Started

Install

composer require juststeveking/http-status-code

Constrain it to ^3.0 in composer.json — that is the backed-enum line and requires PHP 8.1+. Older tags (1.x, 2.x) predate the enum and are covered by stale blog posts; match the tag to your runtime, not the other way round.

There is no service provider, no facade, no config file and no publish step. Laravel will autoload the single enum via Composer and nothing else happens at boot. If you find yourself running php artisan vendor:publish, you've misread the package.

Where to look first

  1. README.md — the entire public surface fits on a screen.
  2. src/Enums/HttpStatusCode.php — this file is the package. Skim the case names before coding, because they follow IANA reason phrasing: UNPROCESSABLE_ENTITY, METHOD_NOT_ALLOWED, IM_A_TEAPOT. They will not match the short aliases you may have memorised from other libraries.
  3. composer.json — confirm the PHP constraint before you assume it installs on a legacy branch.

Your first day-one use case

Strip magic numbers out of a controller action:

use JustSteveKing\HttpStatusCode\Enums\HttpStatusCode;

return response()->json($user, HttpStatusCode::CREATED->value);

return response()->json(['message' => 'Not found'], HttpStatusCode::NOT_FOUND->value);

That's the value: an autocompletable, greppable vocabulary so the next reviewer doesn't have to remember what 422 means. Note the ->value — it is mandatory on response()->json()'s int $status parameter and forgetting it is the standard first-hour mistake.

Implementation Patterns

Translate domain results in the controller, not in the domain. Let your action return a domain status, then match it onto HTTP semantics at the boundary:

$result = $this->registerUser->execute($request->validated());

return match ($result->status) {
    RegistrationStatus::Created   => response()->json($result->user, HttpStatusCode::CREATED->value),
    RegistrationStatus::Duplicate => response()->json(['message' => 'Exists'], HttpStatusCode::CONFLICT->value),
    default                       => response()->json(null, HttpStatusCode::NO_CONTENT->value),
};

This ages well because the mapping is exhaustively visible in one place, and PHPStan will nag you when a new domain case appears.

Central exception handler with a status map. Instead of chained ifs, keep a lookup array. Laravel 10: app/Exceptions/Handler.php. Laravel 11: bootstrap/app.php via withExceptions. Either way:

protected array $statusMap = [
    UserNotFoundException::class      => HttpStatusCode::NOT_FOUND,
    ValidationException::class        => HttpStatusCode::UNPROCESSABLE_ENTITY,
    InsufficientFundsException::class => HttpStatusCode::PAYMENT_REQUIRED,
];

Self-describing exceptions — the highest-leverage integration. Give each domain exception a status(): HttpStatusCode method. The enum becomes the contract, the handler becomes generic (one match for the whole app), and you can unit-test the mapping without booting the framework:

final class UserNotFoundException extends RuntimeException
{
    public function status(): HttpStatusCode
    {
        return HttpStatusCode::NOT_FOUND;
    }
}

A single response helper per layer. If your API uses an envelope, wrap the enum once so it appears in exactly one file and is trivial to audit:

final class ApiResponse
{
    public static function ok(mixed $data = null): JsonResponse
    {
        return response()->json(['data' => $data], HttpStatusCode::OK->value);
    }
}

Dynamic codes from config, DB columns or webhooks. Use HttpStatusCode::tryFrom($code) and branch on null. Never from() — it throws ValueError and converts a bad input into a 500:

$status = HttpStatusCode::tryFrom((int) $payload['status'])
    ?? HttpStatusCode::INTERNAL_SERVER_ERROR;

Testing. Put the enum on the expected side so failures read like English:

$response->assertStatus(HttpStatusCode::CREATED->value);

For large suites, register a TestResponse macro (assertHttpStatus(HttpStatusCode $code)) in a service provider and keep call sites uniform.

Do not replace framework machinery. abort(404), ValidationException, and Response::HTTP_* already emit correct codes. Use this package for responses you construct; pick either this enum or Response::HTTP_* and enforce it project-wide.

Gotchas and Tips

  • It's an enum, not an int. response()->json($data, HttpStatusCode::OK) type-errors on the int $status parameter. Always ->value. Run Larastan/PHPStan at a level that catches HttpStatusCode passed where int is declared.
  • === comparisons fail silently. HttpStatusCode::OK === 200 is always false. Compare ->value to ->value, or better, compare case to case.
  • tryFrom() returns ?self. A webhook forwarding "status": 999 or "abc" yields null. Decide explicitly — reject the payload or fall back — rather than letting it fall through.
  • Backed enums JSON-encode to their value. json_encode(HttpStatusCode::OK) yields 200 in PHP 8.1+. Usually convenient; occasionally a surprise when an enum leaks into a log context or a test fixture.
  • Backed enums cannot be extended. For vendor-specific codes (499, 599) or a companion Retry-After concept, wrap the package enum in your own class. Don't fork the package for it.
  • Reason phrases are English and not localised. If users see them, keep copy in lang/ files and use the enum only for the numeric code. Treat ->name as a developer-facing identifier.
  • Name drift across ecosystems. This package uses IANA wording; Symfony ships Response::HTTP_* and Guzzle has its own constants. UNPROCESSABLE_ENTITY vs HTTP_UNPROCESSABLE_ENTITY — let autocompletion pick it, don't type from memory.
  • There is nothing to configure. No config/http-status-code.php, no container binding, no way to change messages. Don't hunt for one.
  • Version and maintenance signal. The 3.x line is current; 3.0.2 is a patch from a first-time contributor described only as "minor improvements", with no public API change — bumping 3.0.1 → 3.0.2 needs no code edits or test changes. Constrain to ^3.0 and treat major bumps as the only reviewable upgrade events. The surface area is ~10 lines of frozen spec, so risk is genuinely low; if it ever becomes inconvenient, inline the enum under MIT. Bus-factor is a fair concern for a constants list, and Response::HTTP_* is a defensible substitute that you could migrate to in an afternoon.
  • Debugging tip. When a status looks wrong in a test, dump() the enum case rather than the raw int — the case name instantly tells you whether you picked the wrong constant or whether middleware overwrote the response downstream.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource