diff --git a/README.MD b/README.MD index 5790e49..12ee060 100644 --- a/README.MD +++ b/README.MD @@ -86,23 +86,20 @@ php artisan vendor:publish --provider="Swis\JsonApi\Client\Providers\ServiceProv ## Getting started -You can simply require the [DocumentClient](#documentclient) as a dependency and use it in your class. -Alternatively, you can create a repository based on `\Swis\JsonApi\Client\Repository` and use that as a dependency: +You can simply create an instance of [DocumentClient](#documentclient) and use it in your class. +Alternatively, you can create a [repository](#repository). ``` php -use Swis\JsonApi\Client\Repository +use Swis\JsonApi\Client\DocumentClient; -class BlogRepository extends Repository -{ - protected $endpoint = 'blogs'; -} +$client = DocumentClient::create(); +$document = $client->get('https://cms.contentacms.io/api/recipes'); -$repository = app(BlogRepository::class); -$document = $repository->all(); -if ($document->hasErrors()) { - // do something with errors -} else { - $blogs = $document->getData(); +/** @var \Swis\JsonApi\Client\Collection&\Swis\JsonApi\Client\Item[] $collection */ +$collection = $document->getData(); + +foreach ($collection as $item) { + // Do stuff with the items } ``` diff --git a/src/DocumentClient.php b/src/DocumentClient.php index 9e16f4c..a242b70 100644 --- a/src/DocumentClient.php +++ b/src/DocumentClient.php @@ -2,12 +2,15 @@ namespace Swis\JsonApi\Client; +use Psr\Http\Client\ClientInterface as HttpClientInterface; use Psr\Http\Message\ResponseInterface; use Swis\JsonApi\Client\Interfaces\ClientInterface; use Swis\JsonApi\Client\Interfaces\DocumentClientInterface; use Swis\JsonApi\Client\Interfaces\DocumentInterface; use Swis\JsonApi\Client\Interfaces\ItemDocumentInterface; use Swis\JsonApi\Client\Interfaces\ResponseParserInterface; +use Swis\JsonApi\Client\Interfaces\TypeMapperInterface; +use Swis\JsonApi\Client\Parsers\ResponseParser; class DocumentClient implements DocumentClientInterface { @@ -31,6 +34,17 @@ public function __construct(ClientInterface $client, ResponseParserInterface $pa $this->parser = $parser; } + /** + * @param \Swis\JsonApi\Client\Interfaces\TypeMapperInterface|null $typeMapper + * @param \Psr\Http\Client\ClientInterface|null $client + * + * @return static + */ + public static function create(TypeMapperInterface $typeMapper = null, HttpClientInterface $client = null): self + { + return new static(new Client($client), ResponseParser::create($typeMapper)); + } + /** * @return string */ diff --git a/src/Parsers/DocumentParser.php b/src/Parsers/DocumentParser.php index cf8c383..7db352c 100644 --- a/src/Parsers/DocumentParser.php +++ b/src/Parsers/DocumentParser.php @@ -11,7 +11,9 @@ use Swis\JsonApi\Client\Interfaces\ItemInterface; use Swis\JsonApi\Client\Interfaces\ManyRelationInterface; use Swis\JsonApi\Client\Interfaces\OneRelationInterface; +use Swis\JsonApi\Client\Interfaces\TypeMapperInterface; use Swis\JsonApi\Client\ItemDocument; +use Swis\JsonApi\Client\TypeMapper; class DocumentParser implements DocumentParserInterface { @@ -69,6 +71,29 @@ public function __construct( $this->metaParser = $metaParser; } + /** + * @param \Swis\JsonApi\Client\Interfaces\TypeMapperInterface|null $typeMapper + * + * @return static + */ + public static function create(TypeMapperInterface $typeMapper = null): self + { + $metaParser = new MetaParser(); + $linksParser = new LinksParser($metaParser); + $itemParser = new ItemParser($typeMapper ?? new TypeMapper(), $linksParser, $metaParser); + + return new static( + $itemParser, + new CollectionParser($itemParser), + new ErrorCollectionParser( + new ErrorParser($linksParser, $metaParser) + ), + $linksParser, + new JsonapiParser($metaParser), + $metaParser + ); + } + /** * @param string $json * diff --git a/src/Parsers/ResponseParser.php b/src/Parsers/ResponseParser.php index 836836f..6960ede 100644 --- a/src/Parsers/ResponseParser.php +++ b/src/Parsers/ResponseParser.php @@ -7,6 +7,7 @@ use Swis\JsonApi\Client\Interfaces\DocumentInterface; use Swis\JsonApi\Client\Interfaces\DocumentParserInterface; use Swis\JsonApi\Client\Interfaces\ResponseParserInterface; +use Swis\JsonApi\Client\Interfaces\TypeMapperInterface; use Swis\JsonApi\Client\InvalidResponseDocument; class ResponseParser implements ResponseParserInterface @@ -24,6 +25,16 @@ public function __construct(DocumentParserInterface $parser) $this->parser = $parser; } + /** + * @param \Swis\JsonApi\Client\Interfaces\TypeMapperInterface|null $typeMapper + * + * @return static + */ + public static function create(TypeMapperInterface $typeMapper = null): self + { + return new static(DocumentParser::create($typeMapper)); + } + /** * @param \Psr\Http\Message\ResponseInterface $response * diff --git a/tests/DocumentClientTest.php b/tests/DocumentClientTest.php index 1d3f32a..88ec74d 100644 --- a/tests/DocumentClientTest.php +++ b/tests/DocumentClientTest.php @@ -12,6 +12,14 @@ class DocumentClientTest extends AbstractTest { + /** + * @test + */ + public function it_can_create_an_instance_using_a_factory_method() + { + $this->assertInstanceOf(DocumentClient::class, DocumentClient::create()); + } + /** * @test */ diff --git a/tests/Parsers/DocumentParserTest.php b/tests/Parsers/DocumentParserTest.php index 4bf1a43..0f88bec 100644 --- a/tests/Parsers/DocumentParserTest.php +++ b/tests/Parsers/DocumentParserTest.php @@ -14,14 +14,7 @@ use Swis\JsonApi\Client\Link; use Swis\JsonApi\Client\Links; use Swis\JsonApi\Client\Meta; -use Swis\JsonApi\Client\Parsers\CollectionParser; use Swis\JsonApi\Client\Parsers\DocumentParser; -use Swis\JsonApi\Client\Parsers\ErrorCollectionParser; -use Swis\JsonApi\Client\Parsers\ErrorParser; -use Swis\JsonApi\Client\Parsers\ItemParser; -use Swis\JsonApi\Client\Parsers\JsonapiParser; -use Swis\JsonApi\Client\Parsers\LinksParser; -use Swis\JsonApi\Client\Parsers\MetaParser; use Swis\JsonApi\Client\Tests\AbstractTest; use Swis\JsonApi\Client\Tests\Mocks\Items\ChildItem; use Swis\JsonApi\Client\Tests\Mocks\Items\MasterItem; @@ -29,12 +22,20 @@ class DocumentParserTest extends AbstractTest { + /** + * @test + */ + public function it_can_create_an_instance_using_a_factory_method() + { + $this->assertInstanceOf(DocumentParser::class, DocumentParser::create()); + } + /** * @test */ public function it_converts_jsondocument_to_document() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( [ @@ -51,7 +52,7 @@ public function it_converts_jsondocument_to_document() */ public function it_throws_when_json_is_not_valid() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage('Unable to parse JSON data: Malformed UTF-8 characters, possibly incorrectly encoded'); @@ -67,7 +68,7 @@ public function it_throws_when_json_is_not_valid() */ public function it_throws_when_json_is_not_a_jsonapi_document(string $invalidJson) { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage(sprintf('Document MUST be an object, "%s" given.', gettype(json_decode($invalidJson, false)))); @@ -92,7 +93,7 @@ public function provideInvalidJson(): array */ public function it_throws_when_data_errors_and_meta_are_missing() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage('Document MUST contain at least one of the following properties: `data`, `errors`, `meta`.'); @@ -105,7 +106,7 @@ public function it_throws_when_data_errors_and_meta_are_missing() */ public function it_throws_when_both_data_and_errors_are_present() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage('The properties `data` and `errors` MUST NOT coexist in Document.'); @@ -118,7 +119,7 @@ public function it_throws_when_both_data_and_errors_are_present() */ public function it_throws_when_included_is_present_but_data_is_not() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage('If Document does not contain a `data` property, the `included` property MUST NOT be present either.'); @@ -134,7 +135,7 @@ public function it_throws_when_included_is_present_but_data_is_not() */ public function it_throws_when_data_is_not_an_array_object_or_null($invalidData) { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage(sprintf('Document property "data" MUST be null, an array or an object, "%s" given.', gettype(json_decode($invalidData, false)->data))); @@ -160,7 +161,7 @@ public function provideInvalidData(): array */ public function it_throws_when_included_is_not_an_array($invalidIncluded) { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage(sprintf('Document property "included" MUST be an array, "%s" given.', gettype(json_decode($invalidIncluded, false)->included))); @@ -185,7 +186,7 @@ public function provideInvalidIncluded(): array */ public function it_throws_when_it_finds_duplicate_resources() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $this->expectException(ValidationException::class); $this->expectExceptionMessage('Resources MUST be unique based on their `type` and `id`, 1 duplicate(s) found.'); @@ -221,7 +222,7 @@ public function it_throws_when_it_finds_duplicate_resources() */ public function it_parses_a_resource_document() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( [ @@ -247,7 +248,7 @@ public function it_parses_a_resource_document() */ public function it_parses_a_resource_collection_document() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( [ @@ -276,7 +277,7 @@ public function it_parses_a_resource_collection_document() */ public function it_parses_a_document_without_data() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( [ @@ -295,7 +296,7 @@ public function it_parses_a_document_without_data() */ public function it_parses_included() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( [ @@ -328,7 +329,7 @@ public function it_links_singular_relations_to_items_from_included() $typeMapper = new TypeMapper(); $typeMapper->setMapping('master', MasterItem::class); $typeMapper->setMapping('child', ChildItem::class); - $parser = $this->getDocumentParser($typeMapper); + $parser = DocumentParser::create($typeMapper); $document = $parser->parse( json_encode( @@ -374,7 +375,7 @@ public function it_does_not_link_empty_singular_relations() $typeMapper = new TypeMapper(); $typeMapper->setMapping('master', MasterItem::class); $typeMapper->setMapping('child', ChildItem::class); - $parser = $this->getDocumentParser($typeMapper); + $parser = DocumentParser::create($typeMapper); $document = $parser->parse( json_encode( @@ -417,7 +418,7 @@ public function it_links_plural_relations_to_items_from_included() $typeMapper = new TypeMapper(); $typeMapper->setMapping('master', MasterItem::class); $typeMapper->setMapping('child', ChildItem::class); - $parser = $this->getDocumentParser($typeMapper); + $parser = DocumentParser::create($typeMapper); $document = $parser->parse( json_encode( @@ -478,7 +479,7 @@ public function it_does_not_link_empty_plural_relations() $typeMapper = new TypeMapper(); $typeMapper->setMapping('master', MasterItem::class); $typeMapper->setMapping('child', ChildItem::class); - $parser = $this->getDocumentParser($typeMapper); + $parser = DocumentParser::create($typeMapper); $document = $parser->parse( json_encode( @@ -527,7 +528,7 @@ public function it_does_not_link_empty_plural_relations() */ public function it_parses_links() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( @@ -550,7 +551,7 @@ public function it_parses_links() */ public function it_parses_errors() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( @@ -575,7 +576,7 @@ public function it_parses_errors() */ public function it_parses_meta() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( @@ -598,7 +599,7 @@ public function it_parses_meta() */ public function it_parses_jsonapi() { - $parser = $this->getDocumentParser(); + $parser = DocumentParser::create(); $document = $parser->parse( json_encode( @@ -615,20 +616,4 @@ public function it_parses_jsonapi() static::assertEquals(new Jsonapi('1.0'), $document->getJsonapi()); } - - private function getDocumentParser(TypeMapper $typeMapper = null): DocumentParser - { - $metaParser = new MetaParser(); - $linksParser = new LinksParser($metaParser); - $itemParser = new ItemParser($typeMapper ?? new TypeMapper(), $linksParser, $metaParser); - - return new DocumentParser( - $itemParser, - new CollectionParser($itemParser), - new ErrorCollectionParser(new ErrorParser($linksParser, $metaParser)), - $linksParser, - new JsonapiParser($metaParser), - $metaParser - ); - } } diff --git a/tests/Parsers/ResponseParserTest.php b/tests/Parsers/ResponseParserTest.php index 734e585..e3a76ee 100644 --- a/tests/Parsers/ResponseParserTest.php +++ b/tests/Parsers/ResponseParserTest.php @@ -12,6 +12,14 @@ class ResponseParserTest extends AbstractTest { + /** + * @test + */ + public function it_can_create_an_instance_using_a_factory_method() + { + $this->assertInstanceOf(ResponseParser::class, ResponseParser::create()); + } + /** * @test */