{"id":13700018,"url":"https://github.com/leocavalcante/request-callback","last_synced_at":"2025-04-23T07:30:07.018Z","repository":{"id":39711310,"uuid":"326076466","full_name":"leocavalcante/request-callback","owner":"leocavalcante","description":"➰ Swoole request callback for PSR compliant handlers.","archived":false,"fork":false,"pushed_at":"2022-11-08T11:21:09.000Z","size":396,"stargazers_count":26,"open_issues_count":8,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-16T07:46:20.738Z","etag":null,"topics":["middleware","psr-15","psr-7","request-handler","swoole"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leocavalcante.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-01T23:54:04.000Z","updated_at":"2025-03-07T11:43:41.000Z","dependencies_parsed_at":"2022-09-07T10:52:38.915Z","dependency_job_id":null,"html_url":"https://github.com/leocavalcante/request-callback","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Frequest-callback","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Frequest-callback/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Frequest-callback/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leocavalcante%2Frequest-callback/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leocavalcante","download_url":"https://codeload.github.com/leocavalcante/request-callback/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250390721,"owners_count":21422762,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["middleware","psr-15","psr-7","request-handler","swoole"],"created_at":"2024-08-02T20:00:47.257Z","updated_at":"2025-04-23T07:30:06.970Z","avatar_url":"https://github.com/leocavalcante.png","language":"PHP","funding_links":[],"categories":["HTTP and WebSocket"],"sub_categories":[],"readme":"# ➰ Request Callback\n\n![CI](https://github.com/leocavalcante/request-callback/workflows/CI/badge.svg)\n[![codecov](https://codecov.io/gh/leocavalcante/request-callback/branch/main/graph/badge.svg?token=TE1YQYNKHJ)](https://codecov.io/gh/leocavalcante/request-callback)\n[![psalm](https://shepherd.dev/github/leocavalcante/request-callback/coverage.svg)](https://shepherd.dev/github/leocavalcante/request-callback)\n\n[Swoole](https://www.swoole.co.uk/) request callback for [PSR](https://www.php-fig.org/psr/) compliant handlers.\n\n## Install\n\n```bash\ncomposer require leocavalcante/request-callback\n```\n\n## Usage\n\nSimply create a callback that decorates a [`RequestHandlerInterface`](https://www.php-fig.org/psr/psr-15/#11-request-handlers) and pass as a listener to the [`onRequest`](https://www.swoole.co.uk/docs/modules/swoole-http-server-on-request) event of the [`Swoole\\Http\\Server`](https://www.swoole.co.uk/docs/modules/swoole-http-server-doc).\n\n```php\nuse Swoole\\Http\\RequestCallback;\n\n$callback = new RequestCallback(\\Psr\\Http\\Server\\RequestHandlerInterface);\n```\n\n### Example\n\n#### Hello, World!\n\n```php\nuse Laminas\\Diactoros\\Response\\TextResponse;\nuse Psr\\Http\\Message\\{ResponseInterface, ServerRequestInterface};\nuse Psr\\Http\\Server\\RequestHandlerInterface;\nuse Swoole\\Http\\{RequestCallback, Server};\n\n$server = new Server('localhost', 9501);\n\n$server-\u003eon('request', new RequestCallback(new class implements RequestHandlerInterface {\n    public function handle(ServerRequestInterface $request): ResponseInterface\n    {\n        return new TextResponse(sprintf('Hello, %s!', $request-\u003egetQueryParams()['name'] ?? 'World'));\n    }\n}));\n\n$server-\u003estart();\n```\n\nTo help you with the boilerplate, you can use the `RequestCallback::fromCallable(callable)` factory method:\n\n```php\n$server-\u003eon('request', RequestCallback::fromCallable(static function (ServerRequestInterface $request): ResponseInterface {\n    return new TextResponse(sprintf('Hello, %s!', $request-\u003egetQueryParams()['name'] ?? 'World'));\n}));\n```\n\nIf you are like me and want even more sugar, use the `request_callback(RequestHandlerInterface|callable)` function:\n\n```php\n$server-\u003eon('request', request_callback(\n    static fn(ServerRequestInterface $request): ResponseInterface =\u003e\n        new TextResponse(sprintf('Hello, %s!', $request-\u003egetQueryParams()['name'] ?? 'World')))\n);\n\n```\n\nYou can pass either a `RequestHandlerInterface` or a `callable`, it will figure out.\n\n#### Middleware\n\n```php\nuse Laminas\\Diactoros\\Response\\JsonResponse;\nuse Laminas\\Stratigility\\MiddlewarePipe;\nuse Psr\\Http\\Message\\{ResponseInterface, ServerRequestInterface};\nuse Psr\\Http\\Server\\RequestHandlerInterface;\nuse Swoole\\Http\\{RequestCallback, Server};\nuse function Laminas\\Stratigility\\middleware;\n\n$app = new MiddlewarePipe();\n\n$app-\u003epipe(middleware(static function (ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface {\n    $user = $request-\u003egetQueryParams()['user'] ?? null;\n\n    if ($user === null) {\n        return new JsonResponse(['error' =\u003e true, 'message' =\u003e 'Unauthorized'], 401);\n    }\n\n    return $next\n        -\u003ehandle($request-\u003ewithAttribute('user', $user))\n        -\u003ewithAddedHeader('X-Foo', 'Bar');\n}));\n\n$app-\u003epipe(middleware(static function (ServerRequestInterface $request, RequestHandlerInterface $next): ResponseInterface {\n    return new JsonResponse(['message' =\u003e sprintf('Hello, %s!', $request-\u003egetAttribute('user'))]);\n}));\n\n$server = new Server('0.0.0.0', 9501);\n$server-\u003eon('request', new RequestCallback($app));\n$server-\u003estart();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleocavalcante%2Frequest-callback","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleocavalcante%2Frequest-callback","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleocavalcante%2Frequest-callback/lists"}