PHP code example of woohoolabs / yin

1. Go to this page and download the library: Download woohoolabs/yin library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

woohoolabs / yin example snippets


protected function getResource(): array
{
    return [
        "type"       => "<type>",
        "id"         => "<ID>",
        "attributes" => [
            "key" => "value",
        ],
    ];
}

public function __construct(MyResource $resource)
{
    parent::__construct($resource);
}

/**
 * Provides information about the "jsonapi" member of the current document.
 *
 * The method returns a new JsonApiObject object if this member should be present or null
 * if it should be omitted from the response.
 */
public function getJsonApi(): ?JsonApiObject
{
    return new JsonApiObject("1.1");
}

/**
 * Provides information about the "meta" member of the current document.
 *
 * The method returns an array of non-standard meta information about the document. If
 * this array is empty, the member won't appear in the response.
 */
public function getMeta(): array
{
    return [
        "page" => [
            "offset" => $this->object->getOffset(),
            "limit" => $this->object->getLimit(),
            "total" => $this->object->getCount(),
        ]
    ];
}

/**
 * Provides information about the "links" member of the current document.
 *
 * The method returns a new DocumentLinks object if you want to provide linkage data
 * for the document or null if the member should be omitted from the response.
 */
public function getLinks(): ?DocumentLinks
{
    return new DocumentLinks(
        "https://example.com/api",
        [
            "self" => new Link("/books/" . $this->getResourceId())
        ]
    );

    /* This is equivalent to the following:
    return DocumentLinks::createWithBaseUri(
        "https://example.com/api",
        [
            "self" => new Link("/books/" . $this->getResourceId())
        ]
    );
}

/** @var AbstractErrorDocument $errorDocument */
$errorDocument = new MyErrorDocument();
$errorDocument->addError(new MyError());

/** @var ErrorDocument $errorDocument */
$errorDocument = new ErrorDocument();
$errorDocument->setJsonApi(new JsonApiObject("1.0"));
$errorDocument->setLinks(ErrorLinks::createWithoutBaseUri()->setAbout("https://example.com/api/errors/404")));
$errorDocument->addError(new MyError());

class BookResource extends AbstractResource
{
    /**
     * @var AuthorResource
     */
    private $authorResource;

    /**
     * @var PublisherResource
     */
    private $publisherResource;

    /**
     * You can type-hint the object property this way.
     * @var array
     */
    protected $object;

    public function __construct(
        AuthorResource $authorResource,
        PublisherResource $publisherResource
    ) {
        $this->authorResource = $authorResource;
        $this->publisherResource = $publisherResource;
    }

    /**
     * Provides information about the "type" member of the current resource.
     *
     * The method returns the type of the current resource.
     *
     * @param array $book
     */
    public function getType($book): string
    {
        return "book";
    }

    /**
     * Provides information about the "id" member of the current resource.
     *
     * The method returns the ID of the current resource which should be a UUID.
     *
     * @param array $book
     */
    public function getId($book): string
    {
        return $this->object["id"];

        // This is equivalent to the following (the $book parameter is used this time instead of $this->object):
        return $book["id"];
    }

    /**
     * Provides information about the "meta" member of the current resource.
     *
     * The method returns an array of non-standard meta information about the resource. If
     * this array is empty, the member won't appear in the response.
     *
     * @param array $book
     */
    public function getMeta($book): array
    {
        return [];
    }

    /**
     * Provides information about the "links" member of the current resource.
     *
     * The method returns a new ResourceLinks object if you want to provide linkage
     * data about the resource or null if it should be omitted from the response.
     *
     * @param array $book
     */
    public function getLinks($book): ?ResourceLinks
    {
        return new ResourceLinks::createWithoutBaseUri()->setSelf(new Link("/books/" . $this->getId($book)));

        // This is equivalent to the following:
        // return new ResourceLinks("", new Link("/books/" . $this->getResourceId()));
    }

    /**
     * Provides information about the "attributes" member of the current resource.
     *
     * The method returns an array where the keys signify the attribute names,
     * while the values are callables receiving the domain object as an argument,
     * and they should return the value of the corresponding attribute.
     *
     * @param array $book
     * @return callable[]
     */
    public function getAttributes($book): array
    {
        return [
            "title" => function () {
                return $this->object["title"];
            },
            "pages" => function () {
                return (int) $this->object["pages"];
            },
        ];

        // This is equivalent to the following (the $book parameter is used this time instead of $this->object):
        return [
            "title" => function (array $book) {
                return $book["title"];
            },
            "pages" => function (array $book) {
                return (int) $book["pages"];
            },
        ];
    }

    /**
     * Returns an array of relationship names which are 

class BookHydrator extends AbstractHydrator
{
    /**
     * Determines which resource types can be accepted by the hydrator.
     *
     * The method should return an array of acceptable resource types. When such a resource is received for hydration
     * which can't be accepted (its type doesn't match the acceptable types of the hydrator), a ResourceTypeUnacceptable
     * exception will be raised.
     *
     * @return string[]
     */
    protected function getAcceptedTypes(): array
    {
        return ["book"];
    }

    /**
     * Validates a client-generated ID.
     *
     * If the $clientGeneratedId is not a valid ID for the domain object, then
     * the appropriate exception should be thrown: if it is not well-formed then
     * a ClientGeneratedIdNotSupported exception can be raised, if the ID already
     * exists then a ClientGeneratedIdAlreadyExists exception can be thrown.
     *
     * @throws ClientGeneratedIdNotSupported
     * @throws ClientGeneratedIdAlreadyExists
     * @throws Exception
     */
    protected function validateClientGeneratedId(
        string $clientGeneratedId,
        JsonApiRequestInterface $request,
        ExceptionFactoryInterface $exceptionFactory
    ) {
        if ($clientGeneratedId !== null) {
            throw $exceptionFactory->createClientGeneratedIdNotSupportedException($request, $clientGeneratedId);
        }
    }

    /**
     * Produces a new ID for the domain objects.
     *
     * UUID-s are preferred according to the JSON:API specification.
     */
    protected function generateId(): string
    {
        return Uuid::generate();
    }

    /**
     * Sets the given ID for the domain object.
     *
     * The method mutates the domain object and sets the given ID for it.
     * If it is an immutable object or an array the whole, updated domain
     * object can be returned.
     *
     * @param array $book
     * @return mixed|void
     */
    protected function setId($book, string $id)
    {
        $book["id"] = $id;

        return $book;
    }

    /**
     * You can validate the request.
     *
     * @throws JsonApiExceptionInterface
     */
    protected function validateRequest(JsonApiRequestInterface $request): void
    {
        // WARNING! THIS CONDITION CONTRADICTS TO THE SPEC
        if ($request->getAttribute("title") === null) {
            throw new LogicException("The 'title' attribute is     return $book;
            },
            "publisher" => function (array &$book, ToOneRelationship $publisher, $data, string $relationshipName) {
                $book["publisher"] = BookRepository::getPublisher($publisher->getResourceIdentifier()->getId());
            },
        ];
    }

    /**
     * You can validate the domain object after it has been hydrated from the request.
     * @param mixed $book
     */
    protected function validateDomainObject($book): void
    {
        if (empty($book["authors"])) {
            throw new LogicException("The 'authors' relationship cannot be empty!");
        }
    }
}

try {
    // Do something which results in an exception
} catch (JsonApiExceptionInterface $e) {
    // Get the error document from the exception
    $errorDocument = $e->getErrorDocument();

    // Instantiate the responder - make sure to pass the correct dependencies to it
    $responder = Responder::create($request, $response, $exceptionFactory, $serializer);

    // Create a response from the error document
    $responder->genericError($errorDocument);

    // Emit the HTTP response
    sendResponse($response);
}

$pagination = $jsonApi->getPaginationFactory()->createPageBasedPagination(1, 10);

$pagination = $jsonApi->getPaginationFactory()->createFixedPageBasedPagination(1);

$pagination = $jsonApi->getPaginationFactory()->createOffsetBasedPagination(1, 10);

$pagination = $jsonApi->getPaginationFactory()->createCursorBasedPagination("2016-10-01", 10);

$pagination = $jsonApi->getPaginationFactory()->createFixedCursorBasedPagination("2016-10-01");

$paginationParams = $jsonApi->getRequest()->getPagination();

$pagination = new CustomPagination($paginationParams["from"] ?? 1, $paginationParams["to"] ?? 1);

public function getLinks(): ?DocumentLinks
{
    return DocumentLinks::createWithoutBaseUri()->setPagination("/users", $this->object);
}

class UserCollection implements PaginationLinkProviderInterface
{
    use PageBasedPaginationLinkProviderTrait;

    public function getTotalItems(): int
    {
        // ...
    }

    public function getPage(): int
    {
        // ...
    }

    public function getSize(): int
    {
        // ...
    }

    // ...
}

public function getRelationships($user): array
{
    return [
        "contacts" => function (array $user) {
            return
                ToManyRelationship::create()
                    ->setData($user["contacts"], $this->contactTransformer)
                    ->omitDataWhenNotIncluded();
        },
    ];
}

public function getRelationships($user): array
{
    return [
        "contacts" => function (array $user) {
            return
                ToManyRelationship::create()
                    ->setDataAsCallable(
                        function () use ($user) {
                            // Lazily load contacts from the data source
                            return $user->loadContactsFromDataSource();
                        },
                        $this->contactTransformer
                    )
                    ->omitDataWhenNotIncluded()
                ;
        },
    ];
}

// Calculate the cache ID
$cacheId = calculateCacheId();

// Respond with "200 Ok" status code along with the book document containing the cache ID in the meta data
return $jsonApi->respond()->ok($document, $book, ["cache_id" => $cacheId]);

$requestValidator = new RequestValidator(new DefaultExceptionFactory(), $

$requestValidator->negotiate($request);

$requestValidator->validateQueryParams($request);

$requestValidator->validateJsonBody($request);

$responseValidator = new ResponseValidator(
    new JsonSerializer(),
    new DefaultExceptionFactory(),
    $

$responseValidator->validateJsonBody($response);

$responseValidator->validateJsonApiBody($response);

$jsonApi = new JsonApi(new JsonApiRequest(), new Response(), new DefaultExceptionFactory(), new CustomSerializer());

$request = new JsonApiRequest(ServerRequestFactory::fromGlobals(), new DefaultExceptionFactory(), new CustomDeserializer());

public function getBook(JsonApi $jsonApi): ResponseInterface
{
    // Getting the "id" of the currently requested book
    $id = $jsonApi->getRequest()->getAttribute("id");

    // Retrieving a book domain object with an ID of $id
    $book = BookRepository::getBook($id);

    // Instantiating a book document
    $document = new BookDocument(
        new BookResource(
            new AuthorResource(),
            new PublisherResource()
        )
    );

    // Responding with "200 Ok" status code along with the book document
    return $jsonApi->respond()->ok($document, $book);
}

public function getUsers(JsonApi $jsonApi): ResponseInterface
{
    // Extracting pagination information from the request, page = 1, size = 10 if it is missing
    $pagination = $jsonApi->getPaginationFactory()->createPageBasedPagination(1, 10);

    // Fetching a paginated collection of user domain objects
    $users = UserRepository::getUsers($pagination->getPage(), $pagination->getSize());

    // Instantiating a users document
    $document = new UsersDocument(new UserResource(new ContactResource()));

    // Responding with "200 Ok" status code along with the users document
    return $jsonApi->respond()->ok($document, $users);
}

public function getBookRelationships(JsonApi $jsonApi): ResponseInterface
{
    // Getting the "id" of the currently requested book
    $id = $jsonApi->getRequest()->getAttribute("id");

    // Getting the currently requested relationship's name
    $relationshipName = $jsonApi->getRequest()->getAttribute("rel");

    // Retrieving a book domain object with an ID of $id
    $book = BookRepository::getBook($id);

    // Instantiating a book document
    $document = new BookDocument(
        new BookResource(
            new AuthorResource(),
            new PublisherResource(
                new RepresentativeResource()
            )
        )
    );

    // Responding with "200 Ok" status code along with the requested relationship document
    return $jsonApi->respond()->okWithRelationship($relationshipName, $document, $book);
}

public function createBook(JsonApi $jsonApi): ResponseInterface
{
    // Hydrating a new book domain object from the request
    $book = $jsonApi->hydrate(new BookHydrator(), []);

    // Saving the newly created book
    // ...

    // Creating the book document to be sent as the response
    $document = new BookDocument(
        new BookResource(
            new AuthorResource(),
            new PublisherResource(
                new RepresentativeResource()
            )
        )
    );

    // Responding with "201 Created" status code along with the book document
    return $jsonApi->respond()->created($document, $book);
}

public function updateBook(JsonApi $jsonApi): ResponseInterface
{
    // Retrieving a book domain object with an ID of $id
    $id = $jsonApi->getRequest()->getResourceId();
    $book = BookRepository::getBook($id);

    // Hydrating the retrieved book domain object from the request
    $book = $jsonApi->hydrate(new BookHydrator(), $book);

    // Updating the book
    // ...

    // Instantiating the book document
    $document = new BookDocument(
        new BookResource(
            new AuthorResource(),
            new PublisherResource(
                new RepresentativeResource()
            )
        )
    );

    // Responding with "200 Ok" status code along with the book document
    return $jsonApi->respond()->ok($document, $book);
}

public function updateBookRelationship(JsonApi $jsonApi): ResponseInterface
{
    // Checking the name of the currently requested relationship
    $relationshipName = $jsonApi->getRequest()->getAttribute("rel");

    // Retrieving a book domain object with an ID of $id
    $id = $jsonApi->getRequest()->getAttribute("id");
    $book = BookRepository::getBook($id);
    if ($book === null) {
        die("A book with an ID of '$id' can't be found!");
    }

    // Hydrating the retrieved book domain object from the request
    $book = $jsonApi->hydrateRelationship($relationshipName, new BookHydrator(), $book);

    // Instantiating a book document
    $document = new BookDocument(
        new BookResource(
            new AuthorResource(),
            new PublisherResource(
                new RepresentativeResource()
            )
        )
    );

    // Responding with "200 Ok" status code along with the book document
    return $jsonApi->respond()->ok($document, $book);
}