{"id":23835179,"url":"https://github.com/mapado/rest-client-sdk","last_synced_at":"2025-09-07T12:33:47.762Z","repository":{"id":37548850,"uuid":"43553136","full_name":"mapado/rest-client-sdk","owner":"mapado","description":"Rest Client SDK for hydra API","archived":false,"fork":false,"pushed_at":"2024-11-05T12:42:05.000Z","size":995,"stargazers_count":11,"open_issues_count":14,"forks_count":3,"subscribers_count":13,"default_branch":"main","last_synced_at":"2024-12-01T22:23:03.051Z","etag":null,"topics":["client-sdk","hydra-api","php","rest-api","sdk"],"latest_commit_sha":null,"homepage":null,"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/mapado.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2015-10-02T13:04:36.000Z","updated_at":"2024-11-05T12:42:07.000Z","dependencies_parsed_at":"2023-11-13T01:36:28.386Z","dependency_job_id":"44b2a1c8-e0b6-49b9-bb67-b1b03fcd43e0","html_url":"https://github.com/mapado/rest-client-sdk","commit_stats":{"total_commits":336,"total_committers":18,"mean_commits":"18.666666666666668","dds":"0.25595238095238093","last_synced_commit":"097722eb3ce54ddcd1c0efa42624e8d91bab13e2"},"previous_names":[],"tags_count":83,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapado%2Frest-client-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapado%2Frest-client-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapado%2Frest-client-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mapado%2Frest-client-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mapado","download_url":"https://codeload.github.com/mapado/rest-client-sdk/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232137182,"owners_count":18477785,"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":["client-sdk","hydra-api","php","rest-api","sdk"],"created_at":"2025-01-02T15:27:24.639Z","updated_at":"2025-01-02T15:27:25.266Z","avatar_url":"https://github.com/mapado.png","language":"PHP","readme":"# Rest Client Sdk [![StyleCI](https://styleci.io/repos/43553136/shield)](https://styleci.io/repos/43553136) [![Scrutinizer](https://scrutinizer-ci.com/g/mapado/rest-client-sdk/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/mapado/rest-client-sdk/)\n\nPHP Rest Client SDK for JSON API.\n\nThis client tries to avoid the complexity of implementing a custom SDK for every API you have.\nYou just have to implements your model and a little configuration and it will hide the complexity for you.\n\n## installation\n\n```sh\ncomposer require mapado/rest-client-sdk\n```\n\n## Usage\n\nImagine you have those API endpoints:\n\n- /v2/carts\n- /v2/carts/{id}\n- /v2/cart_items\n- /v2/cart_items/{id}\n\nYou will need to have two entities, let's say:\n\n- Foo\\Bar\\Model\\Cart\n- Foo\\Bar\\Model\\CartItem\n\nYou will need to declare one `Mapping` containing your two `ClassMetadata`\n\n## Entity declarations\n\n### Configure an entity\n\nImagine the following entities:\n\n```php\nnamespace Acme\\Foo\\Bar;\n\nuse Mapado\\RestClientSdk\\Mapping\\Attributes as Rest;\n\n#[Rest\\Entity(key: \"carts\")]\nclass Cart\n{\n   #[Rest\\Id, Rest\\Attribute(name: \"@id\", type: \"string\")]\n  private $iri;\n\n   #[Rest\\Attribute(name: \"status\", type: \"string\")]\n  private $status;\n\n  #[Rest\\Attribute(name: \"created_at\", type: \"datetime\")]\n  private $createdAt;\n  \n  #[Rest\\OneToMany(name: \"cart_items\", targetEntity: \"CartItem\")]\n  private $cartItemList;\n\n  // getters \u0026 setters ...\n}\n\n/**\n * @Rest\\Entity(key=\"cart_items\")\n */\n#[Rest\\Entity(key: \"cart_items\")]\nclass CartItem\n{\n  #[Rest\\Id, Rest\\Attribute(name: \"@id\", type: \"string\")]\n  private $iri;\n\n  #[Rest\\Attribute(name: \"number\", type: \"integer\")]\n  private $number;\n\n  #[Rest\\ManyToOne(name: \"cart\", targetEntity: \"Cart\")]\n  private $cart;\n}\n```\n\n### Explanations\n\n`Entity` definitions:\n\n- `key` must be the key of your API endpoint\n\nAttributes definition:\n\n- `name` the name of the key in the API return format\n- `type` type of the attribute\n\nRelations definition:\n\n- `name` the name of the key in the API return format\n- `targetEntity` class name of the target entity\n\n### UnitOfWork\n\n[EntityRepository](https://github.com/mapado/rest-client-sdk/blob/master/src/EntityRepository.php) has a UnitofWork used for PUT and POST requests.\nIt sends only changed data not the full model by comparing with the entity stored on GET request.\n\n## Configuration\n\n### Using Symfony ?\n\nThere is a bundle to easily integrate this component: [mapado/rest-client-sdk-bundle](https://github.com/mapado/rest-client-sdk-bundle).\n\nOnce configured, you can get a client like this:\n\n```php\n$sdkClient = $this-\u003eget('mapado.rest_client_sdk.foo');\n// or $sdkClient = $this-\u003eget('mapado.rest_client_sdk')-\u003egetSdkClient('foo');\n```\n\n### Not using Symfony\n\nYou need to configure client this way:\n\n```php\nuse Mapado\\RestClientSdk\\Mapping;\nuse Mapado\\RestClientSdk\\RestClient;\nuse Mapado\\RestClientSdk\\SdkClient;\nuse Mapado\\RestClientSdk\\Mapping\\Driver\\AttributeDriver;\n\n$restClient = new RestClient(\n  new GuzzleHttp\\Client(),\n  'http://path-to-your-api.root'\n);\n\n// if you need to pass some headers to the client, you can do something like this:\n// $restClient = new RestClient(\n//   new GuzzleHttp\\Client(['headers' =\u003e [ 'Authorization' =\u003e 'Bearer foobar' ]]),\n//   'http://path-to-your-api.root'\n// );\n// See guzzle documentation for more informations\n\n$annotationDriver = new AttributeDriver($cachePath, ($debug = true));\n\n$mapping = new Mapping('/v2'); // /v2 is the prefix of your routes\n$mapping-\u003esetMapping($annotationDriver-\u003eloadDirectory($pathToEntityDirectory));\n\n$sdkClient = new SdkClient($restClient, $mapping);\n```\n\n#### Optionnal: create a SdkClientRegistry\n\n```php\nuse Mapado\\RestClientSdk\\SdkClientRegistry;\n\n$registry = new Registry(['my-api' =\u003e $sdkClient]);\n```\n\nIt can be easier to manager multiple clients. You can then call:\n\n```php\n$sdkClient = $registry-\u003egetSdkClient('my-api');\n\n// or\n\n$sdkClient = $registry-\u003egetSdkClientForClass('\\App\\Entity\\SomeEntity');\n```\n\n## Accessing data\n\n### Fetching an entity / a list of entities\n\n```php\n$repository = $sdkClient-\u003egetRepository('Acme\\Foo\\Bar\\Cart');\n\n// you can also access the repository by model key:\n// $repository = $sdkClient-\u003egetRepository('cart');\n\n// Find entity based on ID as defined in the entity by @Rest\\Id\n$cart = $repository-\u003efind(1);\n\n// If you need to pass extra query parameters:\n$cart = $repository-\u003efind(1, ['foo' =\u003e 'bar']); // will call /v2/carts/1?foo=bar\n\n// Find all entities in the database\n$cart = $repository-\u003efindAll();\n\n// Find one entity based on the fielddefined in the function name (in this case \u003cName\u003e)\n$cart = $repository-\u003efindOneByName('username'); // will call /v2/carts?name=username\n\n// Find one entity based on the criteria defined in the array\n$cart = $repository-\u003efindOneBy(array(\n  'name' =\u003e 'username',\n  'date' =\u003e '1-1-2016',\n)); // will call /v2/carts?name=username\u0026date=1-1-2016\n\n// To find all matches for the two examples above replace findOneByName() with findByName() and findOneBy() with findBy()\n```\n\n### Creating a new instance\n\n```php\n$cart = new \\Acme\\Foo\\Bar\\Cart();\n$cart-\u003esetStatus('awaiting_payment');\n$cart-\u003esetCreatedAt(new \\DateTime());\n$repository-\u003epersist($cart);\n```\n\nThe `persist` operation will send a `POST` request with the serialized object to the API endpoint and return the newly created object\n\n### Updating an instance\n\n```php\n$cart = $repository-\u003efind(13);\n$cart-\u003esetStatus('payed');\n$repository-\u003eupdate($cart);\n```\n\nThe `update` operation will send a `PUT` request with the serialized object to the API endpoint (using the object `Id`) and return the updated object.\n\n### Deleting an instance\n\n```php\n$cart = $repository-\u003efind(13);\n$repository-\u003eremove($cart);\n```\n\nThe `remove` operation will send a `DELETE` request to the API endpoint using the object Id.\n\n### Custom serialization\n\nBy default, when serializing, the SDK return only the Id to existing relations (like one-to-many).\n\nYou may want to serialize OneToMany relations though (imagine you have a `Cart` and you want to update linked `cartItems`)\n\nto do so, you can specify a `$serializationContext` in the `persist` and `update` method:\n\n```php\n$repostory-\u003eupdate($cart, ['serializeRelations' =\u003e ['cartItems']]);\n```\n\n### Extending the repository\n\nIf you need to extend the [EntityRepository](https://github.com/mapado/rest-client-sdk/blob/master/src/EntityRepository.php), you can just do something like that:\n\n```php\nnamespace Acme\\Foo\\Bar\\Repository;\n\nuse Mapado\\RestClientSdk\\EntityRepository;\n\nclass CartRepository extends EntityRepository\n{\n  public function findOneByFoo($bar)\n  {\n    // generate the path to call\n    $path = $data = $this-\u003erestClient-\u003eget($path); // ...\n    return $this-\u003esdk-\u003egetModelHydrator()-\u003ehydrate($data, $this-\u003eentityName); // hydrate for an entity, hydrateList for a list\n  }\n}\n```\n\nUpdate your entity `Rest` attribute to let the entity be aware of it's repository:\n\n```php\nnamespace Acme\\Foo\\Bar;\n\nuse Mapado\\RestClientSdk\\Mapping\\Attributes as Rest;\n\n#[Rest\\Entity(key: \"carts\", repository: Acme\\Foo\\Bar\\Repository\\CartRepository::class)]\nclass Cart {\n```\n\n## Handling exceptions\n\nThe SDK will throw an Exception if your API return something different than a 2xx or a 404 status code.\n\nYou can see all the exceptions in [this folder](https://github.com/mapado/rest-client-sdk/tree/master/src/Exception).\n\nIf you need to access the body of the response from your API you can do something like this:\n\n```php\nuse Mapado\\RestClientSdk\\Exception\\RestClientException;\n\ntry {\n  // do something that will fail\n} catch (\\RestClientException $e) {\n  $response = $e-\u003egetResponse(); // $response should be a Psr\\Http\\Message\\ResponseInterface\n  $body = $response-\u003egetBody();\n  var_dump($body); // will dump your response body\n}\n```\n\n## PHPStan\n\nrest-client-sdk does work well with PHPStan. See [the related documentation](phpstan-extension/README.md).\n\n## Hacking\n\nThis library is tested on multiple Symfony and PHP version thanks to [composer-test-scenarios](https://github.com/g1a/composer-test-scenarios).\n\nBut there is a conflict between ocramius/proxy-manager, composer 1\u00262, and php version.\n\nIn order to sort this issue, it may be usefull to update scenarios with this command for scenario with php 7.4:\n\n```sh\ndocker run --rm --interactive --tty --volume $PWD:/app -w \"/app\" roadiz/php74-runner composer scenario:update\n```\n\nThis should be resolved with [ocramius/proxy-manager#2.9.0](https://packagist.org/packages/ocramius/proxy-manager#2.9.0) but it requires composer 2 absolutely, and we (Mapado) are not ready for this.\n\nThe path to fix this is to bump a major version with `\"ocramius/proxy-manager\": \"^2.9.0\"` that requires composer^2\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapado%2Frest-client-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmapado%2Frest-client-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmapado%2Frest-client-sdk/lists"}