qeezer/api-responder

The api responder.

Maintainers

Package info

github.com/QeeZer/api-responder

pkg:composer/qeezer/api-responder

Transparency log

Statistics

Installs: 63

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

v2.0.0 2026-07-21 06:59 UTC

This package is auto-updated.

Last update: 2026-07-21 07:00:03 UTC


README

Fast build php web api response. Support laravel/lumen framework. Not support hyperf.

中文

install

composer require qeezer/api-responder ^1.0

usage

use QeeZer\ApiResponder\ResponderFactory

<?php

namespace App\Controllers;

use QeeZer\ApiResponder\ResponderFactory;
use Request;
use App\Models\User;

class IndexController
{
    public function index(Request $request)
    {
        return ResponderFactory::responseSuccess();
    }
    
    public function item(Request $request)
    {
        return ResponderFactory::responseItem(User::find(1));
    }
    
    public function collection(Request $request)
    {
        return ResponderFactory::responseCollection(User::all());
    }
    
    public function paginate(Request $request)
    {
        return ResponderFactory::responsePaginate(User::simplePaginate(10));
    }
    
    public function data(Request $request)
    {
        return ResponderFactory::responseData([
            'is_can' => true,
            'name' => 'Tom',
        ]);
    }
    
    public function user(Request $request)
    {
        if (!$request->user()) {
            return ResponderFactory::responseUnauthorized();
        }
        
        return ResponderFactory::responseItem($request->user());
    }
}

use QeeZer\ApiResponder\Responder

app/Controllers/BaseController.php

<?php

namespace App\Controllers;

use QeeZer\ApiResponder\Responder;
use Request;

class BaseController
{
    use Responder;
}

app/Controllers/IndexController.php

<?php

namespace App\Controllers;

use QeeZer\ApiResponder\Responder;
use Request;

class IndexController extends BaseController
{
    public function index(Request $request)
    {
        return $this->responseSuccess();
    }
}

use response resource

app/Resources/UserResource.php

<?php

namespace App\Resources;

use QeeZer\ApiResponder\DefaultResource;

class UserResource extends DefaultResource
{
    public function toArray(): array
    {
        return [
            'id' => $this->data['id'],
            'name' => $this->data['name'],
            'phone' => $this->data['mobile'],
        ];
    }
}

app/Controllers/UserController.php

<?php

namespace App\Controllers;

use App\Models\User;
use App\Resources\UserResource;
use QeeZer\ApiResponder\Responder;
use Request;

class IndexController extends BaseController
{
    public function detail(Request $request)
    {
        $data = $this->validata([
            'uid' => 'required|int'
        ], $request->all());
        
        return $this->responseItem(User::find($data['uid']), UserResource::class);
    }
}

response list

ResponderFactory::responseItem();
ResponderFactory::responseCollection();
ResponderFactory::responsePaginate();
ResponderFactory::responseData();
ResponderFactory::responseSuccess();
ResponderFactory::responseFail();
ResponderFactory::responseError();
ResponderFactory::responseUnauthorized();
ResponderFactory::responseCreated();

in laravel or lumen

app/Exceptions/Handler.php

public function render($request, $exception)
{
    // other

    return \QeeZer\ApiResponder\Helpers::laravelExceptionRender($request, $exception);
}

response shape

{
  "code": 0,
  "message": "ok",
  "data": {
    "meta": null,
    "data": null
  }
}

code vs HTTP status convention

  • responseSuccess / responseData / responseItem / responseCollection / responsePaginate: HTTP 200, business code = 0.
  • responseCreated: HTTP 201, business code = 0.
  • responseFail: HTTP 200 by default, business code = 1 (or a caller-supplied errCode). Use this for expected business failures that the client should handle by business code, not HTTP status.
  • responseUnauthorized: HTTP 401, business code = 401.
  • responseHttp: HTTP status = business code (a thin pass-through).
  • responseError(Throwable):
    • BusinessException implementations keep the caller's message/code and stay at HTTP 200 (it's a business error, not a server fault).
    • Any other Throwable is treated as a server error: HTTP 500. Its code defaulting to 0 is collapsed onto the fail code 1 (so it never collides with the success code 0); string codes are preserved verbatim and also prefixed onto the message as [code]message.

exception detail exposure

Exception internals (message/file/line/trace) are only attached to the response for non-BusinessException throwables, and only when debug exposure is on. Control it explicitly:

\QeeZer\ApiResponder\Helpers::exposeExceptionInfo(true);   // force on
\QeeZer\ApiResponder\Helpers::exposeExceptionInfo(false);  // force off

With no explicit override, it falls back to Laravel/Lumen's config('app.debug') when available, and otherwise defaults to off.

paginate with non-Laravel paginators

responsePaginate accepts any QeeZer\ApiResponder\Contracts\PaginatorAdapter, or auto-wraps a native Laravel paginator via LaravelPaginatorAdapter. For Hyperf or a custom backend, implement PaginatorAdapter:

class MyPaginatorAdapter implements \QeeZer\ApiResponder\Contracts\PaginatorAdapter
{
    public function getItems(): array { /* ... */ }
    public function getPagination(): array { /* ... */ }
    public function getLinks(): array { /* ... */ }
}

return ResponderFactory::responsePaginate(new MyPaginatorAdapter());

responseCollection follows the same shape: a CollectionAdapter, a plain array, or a Laravel-style collection (auto-wrapped via LaravelCollectionAdapter).

run tests

  • composer test — PHPUnit suite
  • composer analyze — PHPStan static analysis (level 5)
  • CI runs both on PHP 7.4 → 8.3 (.github/workflows/tests.yml)