{"id":23725960,"url":"https://github.com/apioo/psx-api-bundle","last_synced_at":"2026-03-07T07:32:11.713Z","repository":{"id":270263567,"uuid":"909795573","full_name":"apioo/psx-api-bundle","owner":"apioo","description":"PSX API Symfony Bundle","archived":false,"fork":false,"pushed_at":"2025-09-21T07:26:02.000Z","size":60,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-26T10:43:03.728Z","etag":null,"topics":["api","code-generator","dto","openapi","rest","specification","symfony","symfony-bundle"],"latest_commit_sha":null,"homepage":"https://phpsx.org/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/apioo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"chriskapp","patreon":"fusio","custom":"https://www.paypal.me/fusioapi"}},"created_at":"2024-12-29T19:49:30.000Z","updated_at":"2025-09-21T07:26:06.000Z","dependencies_parsed_at":"2024-12-29T21:17:18.459Z","dependency_job_id":"d74753a7-f777-46d1-a6c5-ee88b719f07d","html_url":"https://github.com/apioo/psx-api-bundle","commit_stats":null,"previous_names":["apioo/psx-api-bundle"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/apioo/psx-api-bundle","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apioo%2Fpsx-api-bundle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apioo%2Fpsx-api-bundle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apioo%2Fpsx-api-bundle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apioo%2Fpsx-api-bundle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/apioo","download_url":"https://codeload.github.com/apioo/psx-api-bundle/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/apioo%2Fpsx-api-bundle/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30209727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T05:23:27.321Z","status":"ssl_error","status_checked_at":"2026-03-07T05:00:17.256Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["api","code-generator","dto","openapi","rest","specification","symfony","symfony-bundle"],"created_at":"2024-12-31T00:16:59.837Z","updated_at":"2026-03-07T07:32:11.708Z","avatar_url":"https://github.com/apioo.png","language":"PHP","funding_links":["https://github.com/sponsors/chriskapp","https://patreon.com/fusio","https://www.paypal.me/fusioapi"],"categories":[],"sub_categories":[],"readme":"\n# PSX API Bundle\n\nThe PSX API bundle integrates the [PSX API components](https://phpsx.org/) into Symfony which help\nto build fully type-safe REST APIs. Basically the bundle provides additional attributes which you\ncan use at your [controller](#controller) to map HTTP parameters to arguments of your controller\nand commands to generate based on those attributes and type-hints different artifacts:\n\n* Generate Client SDKs for different languages i.e. TypeScript and PHP\n  * `php bin/console generate:sdk client-typescript`\n* Generate OpenAPI specification without additional attributes\n  * `php bin/console generate:sdk spec-openapi`\n* Generate DTO classes using [TypeSchema](https://typeschema.org/)\n  * `php bin/console generate:model`\n\nAs you note this bundle is about REST APIs and not related to any PlayStation content, the name PSX\nwas invented way back and is simply an acronym which stands for \"**P**HP, **S**QL, **X**ML\"\n\n## Installation\n\nTo install the bundle simply require the composer package at your Symfony project.\n\n```\ncomposer require psx/api-bundle\n```\n\nMake sure, that the bundle is registered at the `config/bundles.php` file:\n\n```php\nreturn [\n    PSX\\ApiBundle\\PSXApiBundle::class =\u003e ['all' =\u003e true],\n];\n```\n\n## Controller\n\nThe following is a simple controller which shows how to use the PSX specific attributes to describe\ndifferent HTTP parameters:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Controller;\n\nuse App\\Model\\PostCollection;\nuse App\\Model\\Post;\nuse App\\Model\\Message;\nuse PSX\\Api\\Attribute\\Body;\nuse PSX\\Api\\Attribute\\Param;\nuse PSX\\Api\\Attribute\\Query;\nuse Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController;\nuse Symfony\\Component\\Routing\\Attribute\\Route;\n\nfinal class PostController extends AbstractController\n{\n    public function __construct(private PostService $service, private PostRepository $repository)\n    {\n    }\n\n    #[Route('/post', methods: ['GET'])]\n    public function getAll(#[Query] ?string $filter): PostCollection\n    {\n        return $this-\u003erepository-\u003efindAll($filter);\n    }\n\n    #[Route('/post/{id}', methods: ['GET'])]\n    public function get(#[Param] int $id): Post\n    {\n        return $this-\u003erepository-\u003efind($id);\n    }\n\n    #[Route('/post', methods: ['POST'])]\n    public function create(#[Body] Post $payload): Message\n    {\n        return $this-\u003eservice-\u003ecreate($payload);\n    }\n\n    #[Route('/post/{id}', methods: ['PUT'])]\n    public function update(#[Param] int $id, #[Body] Post $payload): Message\n    {\n        return $this-\u003eservice-\u003eupdate($id, $payload);\n    }\n\n    #[Route('/post/{id}', methods: ['DELETE'])]\n    public function delete(#[Param] int $id): Message\n    {\n        return $this-\u003eservice-\u003edelete($id);\n    }\n}\n```\n\nIn the example we use the `#[Query]`, `#[Param]` and `#[Body]` attribute to map different parts of\nthe incoming HTTP request. In the controller we use a fictional `PostService` and `PostRepository`\nbut you are complete free to design the controller how you like, for PSX it is only important to map\nthe incoming HTTP request parameters to arguments and to provide a return type.\n\n### Raw payload\n\nWe always recommend to generate concrete DTOs to describe the request and response payloads.\nIf you need a raw payload we provide the following type-hints to receive a raw value.\n\n* `Psr\\Http\\Message\\StreamInterface`\n  * Receive the raw request as stream `application/octet-stream`\n* `PSX\\Data\\Body\\Json`\n  * Receive the raw request as JSON `application/json`\n* `PSX\\Data\\Body\\Form`\n  * Receive the raw request as form `application/x-www-form-urlencoded`\n* `string`\n  * Receive the raw request as string `text/plain`\n\nFor example to write a simple proxy method which returns the provided JSON payload s.\n\n```php\n#[Route('/post', methods: ['POST'])]\npublic function create(#[Body] Json $body): Json\n{\n    return $body;\n}\n```\n\n### Multiple response types\n\nIn case your method can return different response types you can use the `#[Outgoing]` attribute to\ndefine a response schema independent of the return type.\n\n```php\n#[Route('/post', methods: ['POST'])]\n#[Outgoing(201, Message::class)]\n#[Outgoing(400, Error::class)]\npublic function create(#[Body] Post $body): JsonResponse\n{\n    if (empty($body-\u003egetTitle())) {\n        return new JsonResponse(new Error('An error occurred'), 400);\n    }\n\n    return new JsonResponse(new Message('Post successfully created'), 201);\n}\n```\n\n## Generator\n\n### SDK\n\nTo generate an SDK you can simply run the following command:\n\n```\nphp bin/console generate:sdk\n```\n\nThis reads alls the attributes from your controller and writes the SDK to the `output` folder.\nAt first argument you can also provide a type, by default this is `client-typescript` but you can also\nselect a different type.\n\n* `client-php`\n* `client-typescript`\n* `spec-openapi`\n\n#### SDKgen\n\nThrough the SDKgen project you have the option to generate also client SDKs for\ndifferent programming languages, therefor you only need to register at the [SDKgen](https://sdkgen.app/)\nwebsite to obtain a client id and secret which you need to set as `psx_api.sdkgen_client_id` and `psx_api.sdkgen_client_secret`\nat your config. After this you can use one of the following types:\n\n* `client-csharp`\n* `client-go`\n* `client-java`\n* `client-python`\n\n#### TypeHub\n\nIf you want to share your API specification it is possible to push your specification to the [TypeHub](https://typehub.cloud/)\nplatform with the following command:\n\n```\nphp bin/console api:push my_document_name\n```\n\nThen you also need to provide a client id and secret for your account. The TypeHub platform basically tracks all changes of\nthe API specification and it is possible to download different SDKs. \n\n### Model\n\nThis bundle also provides a model generator which helps to generate DTOs to describe the\nincoming and outgoing payload s.\n\n```\nphp bin/console generate:model\n```\n\nThis commands reads the [TypeSchema](https://typeschema.org/) specification located at `config/typeschema.json`\nand writes all model classes to `src/Model`. In general TypeSchema is a JSON specification to describe data models.\nThe following is an example specification to generate a simple Student model.\n\n```json\n{\n  \"definitions\": {\n    \"Student\": {\n      \"description\": \"A simple student struct\",\n      \"type\": \"struct\",\n      \"properties\": {\n        \"firstName\": {\n          \"type\": \"string\"\n        },\n        \"lastName\": {\n          \"type\": \"string\"\n        },\n        \"age\": {\n          \"type\": \"integer\"\n        }\n      }\n    }\n  }\n}\n```\n\n## Configuration\n\nThe bundle needs the following `psx_api.yaml` configuration:\n\n```yaml\npsx_api:\n  base_url: 'https://api.acme.com'\n  sdkgen_client_id: ''\n  sdkgen_client_secret: ''\n```\n\nThe `base_url` is the absolute url to your API so that you don't need to provide the\nbase url at your client SDK.\n\nThe `sdkgen_client_id` and `sdkgen_client_secret` are credentials to the [SDKgen](https://sdkgen.app/) app.\n\n## Technical\n\nThis bundle tries to not change any Symfony behaviour, for example we use the existing `#[Route]` attribute instead\nof the `#[Path]` attribute. This has some small tradeoffs, at first you are required to use the\n`#[Route]` attribute, `YAML`, `XML` or `PHP` routing is not supported, since otherwise the generate command will not\nbe able to parse the routes, and second your route has to specify a concrete HTTP method filter, since the SDK generator\nneeds a concrete HTTP method for every endpoint.\n\nBasically the bundle only registers the following classes:\n\n* `PSX\\ApiBundle\\ArgumentResolver\\ValueResolver`\n  * To parse the attributes of each argument and transform the incoming value\n* `PSX\\ApiBundle\\EventListener\\SerializeResponseListener`\n  * To transform the response of the controller\n* `PSX\\ApiBundle\\EventListener\\ExceptionResponseListener`\n  * To transform the exception response\n\n## Community\n\nFeel free to create an issue or PR in case you want to improve this bundle. We also like to give a\nshout-out to [praswicaksono](https://github.com/praswicaksono/typeapi-bundle) for implementing a\nfirst version of this bundle.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapioo%2Fpsx-api-bundle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapioo%2Fpsx-api-bundle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapioo%2Fpsx-api-bundle/lists"}