{"id":14965567,"url":"https://github.com/baraja-core/structured-api","last_synced_at":"2025-10-28T20:06:05.474Z","repository":{"id":37735178,"uuid":"231595804","full_name":"baraja-core/structured-api","owner":"baraja-core","description":"📝 🌐 Complex library for definition of your structured API endpoint as class with schema.","archived":false,"fork":false,"pushed_at":"2024-06-09T20:18:26.000Z","size":770,"stargazers_count":7,"open_issues_count":11,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-26T14:41:47.349Z","etag":null,"topics":["annotation","api","baraja","nette","nette-framework","panel","php","schema","typed"],"latest_commit_sha":null,"homepage":"https://php.baraja.cz","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/baraja-core.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"janbarasek","custom":["https://brj.app","https://baraja.cz","https://php.baraja.cz"]}},"created_at":"2020-01-03T13:36:07.000Z","updated_at":"2024-07-03T22:04:53.000Z","dependencies_parsed_at":"2024-06-21T13:07:53.965Z","dependency_job_id":null,"html_url":"https://github.com/baraja-core/structured-api","commit_stats":{"total_commits":263,"total_committers":5,"mean_commits":52.6,"dds":"0.041825095057034245","last_synced_commit":"bccc06848a2980537d67582180d34d946e0e43cb"},"previous_names":[],"tags_count":69,"template":false,"template_full_name":null,"purl":"pkg:github/baraja-core/structured-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baraja-core%2Fstructured-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baraja-core%2Fstructured-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baraja-core%2Fstructured-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baraja-core%2Fstructured-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/baraja-core","download_url":"https://codeload.github.com/baraja-core/structured-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/baraja-core%2Fstructured-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281504338,"owners_count":26512865,"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","status":"online","status_checked_at":"2025-10-28T02:00:06.022Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["annotation","api","baraja","nette","nette-framework","panel","php","schema","typed"],"created_at":"2024-09-24T13:34:55.656Z","updated_at":"2025-10-28T20:06:05.457Z","avatar_url":"https://github.com/baraja-core.png","language":"PHP","readme":"\u003cdiv align='center'\u003e\n  \u003cpicture\u003e\n    \u003csource media='(prefers-color-scheme: dark)' srcset='https://cdn.brj.app/images/brj-logo/logo-regular.png'\u003e\n    \u003cimg src='https://cdn.brj.app/images/brj-logo/logo-dark.png' alt='BRJ logo'\u003e\n  \u003c/picture\u003e\n  \u003cbr\u003e\n  \u003ca href=\"https://brj.app\"\u003eBRJ organisation\u003c/a\u003e\n\u003c/div\u003e\n\u003chr\u003e\n\nStructured REST API in PHP\n==========================\n\n![Integrity check](https://github.com/baraja-core/structured-api/workflows/Integrity%20check/badge.svg)\n\nFull compatible smart structured API defined by schema.\n\n- Define full type-hint input parameters,\n- Validate returned data by schema,\n- Full compatible with Nette framework,\n- Inject dependencies by `#[Inject]` attribute (or old `@inject` annotation syntax) in public property.\n\n![Baraja Structured API debug Tracy panel](doc/tracy-panel-design.png)\n\n📦 Installation \u0026 Basic Usage\n-----------------------------\n\nThis package can be installed using [PackageRegistrator](https://github.com/baraja-core/package-manager) which is also part of the Baraja [Sandbox](https://github.com/baraja-core/sandbox). If you are not using it, you have to install the package manually following this guide.\n\nA model configuration can be found in the `common.neon` file inside the root of the package.\n\nTo manually install the package call Composer and execute the following command:\n\n```shell\n$ composer require baraja-core/structured-api\n```\n\n🛠️ API endpoint\n---------------\n\nAPI endpoint is simple class with action methods and dependencies. For best comfort please use your custom BaseEndpoint with declaring all required dependencies.\n\nSimple example:\n\n```php\n\u003c?php\n\ndeclare(strict_types=1);\n\nnamespace App\\Model;\n\nfinal class MyAwesomeEndpoint extends BaseEndpoint\n{\n   /**\n    * This is test API endpoint as demonstration of inner logic.\n    *\n    * @param string $hello some user-defined parameter.\n    */\n   public function actionDefault(string $hello = 'world'): MyAwesomeResponse\n   {\n      // The endpoint response can be simply returned as an simple array or typed object.\n      // A type object is much better because it will be used as the basis for documentation.\n      // It will be automatically converted to JSON.\n\n      return new MyAwesomeResponse(\n         name: 'Test API endpoint',\n         hello: $hello,\n      );\n   }\n\n   // or use old syntax:\n\n   /**\n    * This is test API endpoint as demonstration of inner logic.\n    *\n    * @param string $hello some user-defined parameter.\n    */\n   public function actionDefault(string $hello = 'world'): void\n   {\n      $this-\u003esendJson([\n         'name' =\u003e 'Test API endpoint',\n         'hello' =\u003e $hello,\n      ]);\n   }\n\n   // or return simple array directly:\n\n   /**\n    * @param array\u003cmixed, mixed\u003e $data\n    */\n   public function postCreateUser(array $data): array\n   {\n      return [\n         'state' =\u003e 'ok',\n         'data' =\u003e $data,\n      ];\n   }\n}\n```\n\nMethod `actionDefault` is used for request in format `/api/v1/test` with query parameter `?hello=...`.\n\nMethod `postCreateUser` will be called by POST request with all data.\n\nAlways return the response from the endpoint directly as the return type of the method. This makes static analysis easier for other tools (for example, for checking code integrity or generating documentation). The `sendJson()`, `sendOk()`, and `sendError()` methods are still supported, but may be marked as deprecated in the future.\n\n📝 Endpoint registration\n------------------------\n\nIf you use the Nette Framework, all endpoints will be registered automatically. This provides an extension for DIC.\n\nTo register automatically, simply inherit `BaseEndpoint` or implement the `Baraja\\StructuredApi\\Endpoint` interface.\n\n🌐 HTTP methods\n---------------\n\nThe library supports all HTTP methods for the REST API. The selection of the HTTP method is solved by the method name.\n\nYou can specify the HTTP method at the beginning of the method name, or use an alias:\n\n```php\nfinal class MyAwesomeEndpoint extends BaseEndpoint\n{\n   public function getDefault(): void\n   {\n      // this logic will be called as GET.\n   }\n\n   public function actionDefault(): void\n   {\n      // this logic will be called as GET too,\n      // because `action` prefix is alias for GET.\n   }\n\n   public function postDetail(string $id, string $name, ?string $description = null): void\n   {\n      // this logic will be called as POST.\n   }\n}\n```\n\nList of aliases (aliases are optional):\n\n- `action` as `GET`\n- `update` as `PUT`\n- `create` as `POST`\n\n💾 Obtaining raw data\n---------------------\n\nFor processing complex data structures, it may be useful to obtain the data in its original raw form.\n\nThe library reserves the key variable `array $data`, which always contains the original input values from the user, regardless of validation.\n\nFor example:\n\n```php\nfinal class OrderEndpoint extends BaseEndpoint\n{\n   public function postProcessOrder(array $data): void\n   {\n      // variable $data contains all raw data from user.\n   }\n}\n```\n\n✅ Validation\n-------------\n\nIn the runtime, when calling methods, the passed arguments against the method definition and data types are validated. This ensures that the endpoint is never called with incorrect data.\n\nThe library guarantees that you will always get the data in the type you request. If you need to define the type more complicated, you can use a comment annotation.\n\nCombined example:\n\n```php\nfinal class ArticleEndpoint extends BaseEndpoint\n{\n   /**\n    * @param string|null $locale in format \"cs\" or \"en\"\n    * @param int $page real page number for filtering, 1 =\u003e first page ... \"n\" page\n    * @param int $limit in interval \u003c0, 500)\n    * @param string|null $status matching constant self::STATUS_* (null, all, published, trash)\n    * @param string|null $query smart search query\n    * @param string|null $filterFrom find all articles from this date\n    * @param string|null $filterTo find all articles to this date\n    * @param string|null $sort sort by supported field\n    * @param string|null $orderBy direction by `ASC` or `DESC`\n    */\n   public function actionDefault(\n      ?string $locale = null,\n      int $page = 1,\n      int $limit = 32,\n      ?string $status = null,\n      ?string $query = null,\n      ?string $filterFrom = null,\n      ?string $filterTo = null,\n      ?string $sort = null,\n      ?string $orderBy = null,\n   ): void {\n   }\n}\n```\n\nThe library takes full advantage of PHP 7 and always checks data types. If the data is passed in the wrong type (for example, a boolean cannot be passed by the GET method), it performs an automatic conversion or throws an error.\n\nIf the argument contains a default value, it is **automatically marked as optional**. If the user does not pass a value, the default is used. All mandatory arguments **must always be passed**, if not, your logic will not be called at all.\n\n🙋 Smart response\n-----------------\n\nThe library contains a number of built-in methods for elegant handling of all important return states.\n\nFor example, if we want to get the detail of an article by ID and return its detail from the database, the use is completely intuitive:\n\n```php\nfinal class ArticleEndpoint extends BaseEndpoint\n{\n   public function actionDetail(string $id): void\n   {\n      // your logic for fetch data from database\n\n      // your response\n      $this-\u003esendJson([\n         'id' =\u003e $id,\n         'title' =\u003e 'My awesome article',\n         'content' =\u003e '...',\n      ]);\n   }\n}\n```\n\nEach method can return output either via `send` methods or directly as a type object. A more modern approach is to return the entire object, as this gives us type checking and the underlying basis for automatically generated documentation.\n\n\u003e **Warning:** If you do not pass any output (by method or return statement), endpoint processing will fail.\n\nWhen processing actions, it is a good idea to return success or error information:\n\n```php\nfinal class ArticleEndpoint extends BaseEndpoint\n{\n   public function createDetail(string $title, string $content, ?string $perex = null): void\n   {\n      try {\n         // creating in database...\n         $this-\u003esendOk([\n            'id' =\u003e 123,\n         ]);\n      } catch (\\Exception $e) {\n         $this-\u003esendError('Can not create article because ...');\n      }\n   }\n}\n```\n\n🔒 Permissions\n--------------\n\n\u003e 🚩**Warning:** If you do not set the rights at all, by default all endpoints are private and you must log in to call them! 👮\n\nAll API requests are validated at runtime. If you want to allow all users access to your endpoints, please add the `#[PublicEndpoint]` attribute to class.\n\nFor example (this endpoint will be public):\n\n```php\n#[PublicEndpoint]\nfinal class ProductEndpoint extends BaseEndpoint\n{\n}\n```\n\nTo restrict rights, define an `#[Role]` attribute over a class or method.\n\nFor example (only administrators and moderators can call this endpoint):\n\n```php\n#[Role(roles: ['admin', 'moderator'])]\nfinal class ArticleEndpoint extends BaseEndpoint\n{\n}\n```\n\nRights settings can also be combined. For example, in a public endpoint, restrict rights to a specific method only:\n\n```php\n#[PublicEndpoint]\nfinal class SitemapEndpoint extends BaseEndpoint\n{\n   #[Role(roles: 'admin')]\n   public function actionClearCache(): void\n   {\n      // your secured implementation\n   }\n}\n```\n\n🔒 Check API token\n------------------\n\nIf you want to provide the API to your external partners or to provide secure communication with another application, it is a good idea to use authentication of all requests via an API token. There is an official extension [structured-api-token-authorizer](https://github.com/baraja-core/structured-api-token-authorizator) for this use.\n\n🗺️ Project endpoint documentation\n---------------------------------\n\nWhen developing a real application, you will often need to pass work between the backend and the frontend.\n\nTo describe all endpoints, the package offers an optional extension that generates documentation automatically based on real code scanning.\n\nTry the [Structured API Documentation](https://github.com/baraja-core/structured-api-doc).\n\n📄 License\n-----------\n\n`baraja-core/structured-api` is licensed under the MIT license. See the [LICENSE](https://github.com/baraja-core/structured-api/blob/master/LICENSE) file for more details.\n","funding_links":["https://github.com/sponsors/janbarasek","https://brj.app","https://baraja.cz","https://php.baraja.cz"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaraja-core%2Fstructured-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbaraja-core%2Fstructured-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbaraja-core%2Fstructured-api/lists"}