PHPackages                             coroq/http-responder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. coroq/http-responder

ActiveLibrary[HTTP &amp; Networking](/categories/http)

coroq/http-responder
====================

Simple PSR-7 HTTP response factory with semantic method names

v1.0.0(5mo ago)06MITPHPPHP ^8.0

Since Nov 24Pushed 5mo agoCompare

[ Source](https://github.com/coroq-com/http-responder)[ Packagist](https://packagist.org/packages/coroq/http-responder)[ RSS](/packages/coroq-http-responder/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (4)Versions (2)Used By (0)

coroq/http-responder
====================

[](#coroqhttp-responder)

PSR-7 HTTP response factory with semantic method names.

Requirements
------------

[](#requirements)

- PHP ^8.0
- PSR-7 HTTP Message implementation (e.g., `nyholm/psr7`, `guzzlehttp/psr7`)
- PSR-17 HTTP Factory implementation (e.g., `nyholm/psr7`, `laminas/laminas-diactoros`)

Installation
------------

[](#installation)

```
composer require coroq/http-responder
```

Quick Start
-----------

[](#quick-start)

```
use Coroq\HttpResponder\Responder;
use Coroq\HttpResponder\JsonResponder;

// Inject PSR-17 ResponseFactoryInterface
$responder = new Responder($responseFactory);

// Returns PSR-7 ResponseInterface with status 200 and HTML body
return $responder->ok('Hello World');

// For JSON responses, use JsonResponder
$responder = new JsonResponder($responseFactory);

// Returns PSR-7 ResponseInterface with status 200, Content-Type: application/json,
// and body: {"status":"success"}
return $responder->ok(['status' => 'success']);
```

Concepts
--------

[](#concepts)

Two independent classes for different response types:

- **Responder** - HTML, text, file downloads
- **JsonResponder** - JSON responses with automatic encoding

Method names map directly to HTTP status codes. No need to remember numbers.

Both classes return PSR-7 `ResponseInterface`, allowing standard PSR-7 chaining.

Who Is This For?
----------------

[](#who-is-this-for)

For developers building PSR-7/PSR-15 applications who want readable response creation without framework coupling. Good fit for Mezzio, Slim, or custom middleware stacks mixing HTML and JSON responses.

Not for pure REST APIs needing comprehensive status code coverage, or Laravel/Symfony projects with built-in response helpers.

Usage
-----

[](#usage)

### Basic Responses

[](#basic-responses)

```
$responder = new Responder($responseFactory);

// 200 OK
return $responder->ok('Hello World');
return $responder->ok($streamInterface);
return $responder->ok(); // empty body

// 401 Unauthorized
return $responder->unauthorized('Login required');

// 403 Forbidden
return $responder->forbidden();

// 404 Not Found
return $responder->notFound('Not Found');

// 500 Internal Server Error
return $responder->internalServerError();

// 503 Service Unavailable
return $responder->serviceUnavailable('Under maintenance');

// Custom status
return $responder->response(418);
```

### File Downloads

[](#file-downloads)

```
// With filename
return $responder->okDownload(
  $fileContent,
  'application/pdf',
  'invoice.pdf'
);

// UTF-8 filenames work
return $responder->okDownload(
  $content,
  'text/plain',
  'ファイル.txt'
);

// Without filename
return $responder->okDownload($stream, 'image/png');
```

### Redirects

[](#redirects)

```
// 302 Found (temporary redirect)
return $responder->found('/login');

// With query parameters
return $responder->found('/search', ['q' => 'test', 'page' => '2']);

// With fragment
return $responder->found('/page', [], 'section-3');

// Both
return $responder->found('/article', ['id' => '123'], 'comments');

// 301 Moved Permanently
return $responder->movedPermanently('/new-url');
return $responder->movedPermanently('/new', ['ref' => 'old']);
```

### JSON Responses

[](#json-responses)

```
$responder = new JsonResponder($responseFactory);

// 200 OK
return $responder->ok(['user' => 'john', 'status' => 'active']);

// 201 Created
return $responder->created(['id' => 123, 'created_at' => '2024-01-01']);

// 400 Bad Request
return $responder->badRequest(['error' => 'Invalid email format']);

// 401 Unauthorized
return $responder->unauthorized(['error' => 'Token expired']);

// 403 Forbidden
return $responder->forbidden(['error' => 'Insufficient permissions']);

// 404 Not Found
return $responder->notFound(['error' => 'User not found']);

// 500 Internal Server Error
return $responder->internalServerError(['error' => 'Database connection failed']);

// 503 Service Unavailable
return $responder->serviceUnavailable(['error' => 'Maintenance mode']);

// Custom status
return $responder->response(418, ['message' => "I'm a teapot"]);
```

### JSON Redirects

[](#json-redirects)

```
return $responder->found('/dashboard');
return $responder->movedPermanently('/new-api', [], 'v2');
```

### JSON Encoding Options

[](#json-encoding-options)

```
// Default flags: JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
$responder = new JsonResponder($responseFactory);
return $responder->ok(['path' => '/foo/bar', 'name' => '日本語']);
// Output: {"path":"/foo/bar","name":"日本語"}

// Override flags for one response
return $responder->withEncodingOptions(JSON_PRETTY_PRINT)->ok($data);
// Returns new instance, original unchanged

// Configure at construction
$responder = new JsonResponder($responseFactory, JSON_PRETTY_PRINT);

// Custom encoder
$encoder = fn($data) => json_encode($data, JSON_THROW_ON_ERROR);
$responder = new JsonResponder($responseFactory, 0, $encoder);
```

###  Health Score

32

—

LowBetter than 72% of packages

Maintenance71

Regular maintenance activity

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity40

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

166d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/addac0ea12d91786ce888c91ef7de6525bc17252c702cd7e48fe64ab547c012e?d=identicon)[ozami](/maintainers/ozami)

---

Top Contributors

[![ozami](https://avatars.githubusercontent.com/u/170309?v=4)](https://github.com/ozami "ozami (2 commits)")

---

Tags

httpresponsepsr-7psr-17

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/coroq-http-responder/health.svg)

```
[![Health](https://phpackages.com/badges/coroq-http-responder/health.svg)](https://phpackages.com/packages/coroq-http-responder)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

8.0k1.0B3.1k](/packages/guzzlehttp-psr7)[psr/http-factory

PSR-17: Common interfaces for PSR-7 HTTP message factories

1.9k692.9M1.9k](/packages/psr-http-factory)[laminas/laminas-diactoros

PSR HTTP Message implementations

546105.8M962](/packages/laminas-laminas-diactoros)[phpro/http-tools

HTTP tools for developing more consistent HTTP implementations.

28137.8k](/packages/phpro-http-tools)[laminas/laminas-stratigility

PSR-7 middleware foundation for building and dispatching middleware pipelines

586.6M81](/packages/laminas-laminas-stratigility)[middlewares/utils

Common utils for PSR-15 middleware packages

503.4M93](/packages/middlewares-utils)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
