{"id":23380713,"url":"https://github.com/softonic/rest-api-nested-resources","last_synced_at":"2026-02-13T23:33:02.730Z","repository":{"id":39587958,"uuid":"487816644","full_name":"softonic/rest-api-nested-resources","owner":"softonic","description":"Utilities to work with REST APIs with nested resources","archived":false,"fork":false,"pushed_at":"2025-02-21T09:39:19.000Z","size":23,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-23T18:58:41.109Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/softonic.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":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-05-02T11:19:54.000Z","updated_at":"2025-02-21T09:38:27.000Z","dependencies_parsed_at":"2022-09-20T06:01:18.806Z","dependency_job_id":null,"html_url":"https://github.com/softonic/rest-api-nested-resources","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/softonic/rest-api-nested-resources","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softonic%2Frest-api-nested-resources","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softonic%2Frest-api-nested-resources/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softonic%2Frest-api-nested-resources/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softonic%2Frest-api-nested-resources/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/softonic","download_url":"https://codeload.github.com/softonic/rest-api-nested-resources/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/softonic%2Frest-api-nested-resources/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29423534,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T22:20:51.549Z","status":"ssl_error","status_checked_at":"2026-02-13T22:20:49.838Z","response_time":78,"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":[],"created_at":"2024-12-21T20:18:06.504Z","updated_at":"2026-02-13T23:33:02.702Z","avatar_url":"https://github.com/softonic.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"REST API nested resources\n====================\n\n[![Latest Version](https://img.shields.io/github/release/softonic/rest-api-nested-resources.svg?style=flat-square)](https://github.com/softonic/rest-api-nested-resources/releases)\n[![Software License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](LICENSE.md)\n[![Build Status](https://github.com/softonic/rest-api-nested-resources/actions/workflows/build.yml/badge.svg)](https://github.com/softonic/rest-api-nested-resources/actions/workflows/build.yml)\n[![Total Downloads](https://img.shields.io/packagist/dt/softonic/rest-api-nested-resources.svg?style=flat-square)](https://packagist.org/packages/softonic/rest-api-nested-resources)\n[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/softonic/rest-api-nested-resources.svg?style=flat-square)](http://isitmaintained.com/project/softonic/rest-api-nested-resources \"Average time to resolve an issue\")\n[![Percentage of issues still open](http://isitmaintained.com/badge/open/softonic/rest-api-nested-resources.svg?style=flat-square)](http://isitmaintained.com/project/softonic/rest-api-nested-resources \"Percentage of issues still open\")\n\nUtilities to work with REST APIs with nested resources\n\nMain features\n-------------\n\n* MultiKeyModel: allows to have nested resources with composite primary keys\n* EnsureModelExists: middleware to validate that a resource exists (used to ensure that a parent resource exists)\n* EnsureModelDoesNotExist: middleware to validate that the resource we want to create doesn't already exist\n* SubstituteBindings: a personalization of the Laravel's SubstituteBindings middleware to work with nested resources\n* SplitPutPatchVerbs: trait that allows the controller to split the \"update\" method into \"modify\" (PATCH) and \"replace\" (PUT) CRUDL methods\n\nInstallation\n-------------\n\nYou can require the last version of the package using composer\n```bash\ncomposer require softonic/rest-api-nested-resources\n```\n\n### Configuration\n\n* MultiKeyModel\n```php\nclass UserCommentModel extends MultiKeyModel\n{\n    /**\n     * Identifiers to be hashed and used in the real primary and foreign keys.\n     */\n    protected static array $generatedIds = [\n        'id_user_comment' =\u003e [\n            'id_user',\n            'id_comment',\n        ],\n    ];\n}\n```\n\n* EnsureModelExists and EnsureModelDoesNotExist\n```php\nclass UserCommentController extends Controller\n{\n    protected function setMiddlewares(Request $request)\n    {\n        $this-\u003emiddleware(\n            'App\\Http\\Middleware\\EnsureModelExists:App\\Models\\User,id_user',\n            ['only' =\u003e ['store', 'update']]\n        );\n\n        $this-\u003emiddleware(\n            'App\\Http\\Middleware\\EnsureModelDoesNotExist:App\\Models\\UserComment,id_user,id_comment',\n            ['only' =\u003e 'store']\n        );\n    }\n}\n```\n\n* SubstituteBindings\n```php\nuse App\\Models\\UserComment;\n\nclass UserCommentController extends Controller\n{\n    public function show(UserComment $userComment)\n    {\n        ...\n    }\n}\n```\n\n* SplitPutPatchVerbs\n```php\nuse App\\Models\\UserComment;\n\nclass UserCommentController extends Controller\n{\n    use SplitPutPatchVerbs;\n\n    public function modify(UserComment $userComment, Request $request)\n    {\n        ...\n    }\n\n    public function replace(Request $request, string $id_user, string $id_comment)\n    {\n        ...\n    }\n}\n```\n\nTesting\n-------\n\n`softonic/rest-api-nested-resources` has a [PHPUnit](https://phpunit.de) test suite, and a coding style compliance test suite using [PHP CS Fixer](http://cs.sensiolabs.org/).\n\nTo run the tests, run the following command from the project folder.\n``` bash\n$ docker compose run test\n```\n\nTo open a terminal in the dev environment:\n``` bash\n$ docker compose run --entrypoint=bash php\n```\n\nLicense\n-------\n\nThe Apache 2.0 license. Please see [LICENSE](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftonic%2Frest-api-nested-resources","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoftonic%2Frest-api-nested-resources","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoftonic%2Frest-api-nested-resources/lists"}