Download the PHP package woohoolabs/yin without Composer

On this page you can find all versions of the php package woohoolabs/yin. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package yin

Woohoo Labs. Yin

Latest Version on Packagist Build Status Coverage Status Quality Score Total Downloads Gitter

Woohoo Labs. Yin is a PHP framework which helps you to build beautifully crafted JSON:APIs.

Table of Contents

Introduction

JSON:API specification reached 1.0 on 29th May 2015 and we also believe it is a big day for RESTful APIs as this specification can help you make APIs more robust and future-proof. Woohoo Labs. Yin (named after Yin-Yang) was born to bring efficiency and elegance to your JSON:API servers, while Woohoo Labs. Yang is its client-side counterpart.

Features

Why Yin?

Complete JSON:API framework

Woohoo Labs. Yin is a framework-agnostic library which supports the vast majority of the JSON:API 1.1 specification: it provides various capabilities including content negotiation, error handling and pagination, as well as fetching, creation, updating and deleting resources. Although Yin consists of many loosely coupled packages and classes which can be used separately, the framework is most powerful when used in its entirety.

Efficiency

We designed Yin to be as efficient as possible. That's why attributes and relationships are transformed only and if only they are requested. This feature is extremely advantageous when there are a lot of resources to transform or a rarely required transformation is very expensive. Furthermore, as transformers are stateless, the overhead of having a separate model object for each resource is avoided. Additionally, due to statelessness, the overall library works really well with dependency injection.

Supplementary middleware

There is some additional middleware for Woohoo Labs. Yin you might find useful. It can facilitate various tasks like error handling (via transformation of exceptions into JSON:API error responses), dispatching JSON:API-aware controllers or debugging (via syntax checking and validation of requests and responses).

Install

The only thing you need before getting started is Composer.

Install a PSR-7 implementation:

Because Yin requires a PSR-7 implementation (a package which provides the psr/http-message-implementation virtual package), you must install one first. You may use Laminas Diactoros or any other library of your preference:

Install Yin:

To install the latest version of this library, run the command below:

Note: The tests and examples won't be downloaded by default. You have to use composer require woohoolabs/yin --prefer-source or clone the repository if you need them.

The latest version of Yin requires PHP 7.1 at least but you can use Yin 2.0.6 for PHP 7.0.

Install the optional dependencies:

If you want to take advantage of request/response validation then you have to also ask for the following dependencies:

Basic Usage

When using Woohoo Labs. Yin, you will create:

Furthermore, a JsonApi class will be responsible for the instrumentation, while a PSR-7 compatible JsonApiRequest class provides functionalities you commonly need.

Documents

The following sections will guide you through creating documents for successful responses and creating or building error documents.

Documents for successful responses

For successful requests, you must return information about one or more resources. Woohoo Labs. Yin provides multiple abstract classes that help you to create your own documents for different use cases:

As the AbstractSuccessfulDocument is only useful for special use-cases (e.g. when a document can contain resources of multiple types), we will not cover it here.

The difference between the AbstractSimpleResourceDocument and the AbstractSingleResourceDocument classes is that the first one doesn't need a resource object. For this reason, it is preferable to use the former for only really simple domain objects (like messages), while the latter works better for more complex domain objects (like users or addresses).

Let's first have a quick look at the AbstractSimpleResourceDocument: it has a getResource() abstract method which needs to be implemented when you extend this class. The getResource() method returns the whole transformed resource as an array including the type, id, attributes, and relationships like below:

Please note that AbstractSimpleResourceDocument doesn't support some features out-of-the-box like sparse fieldsets, automatic inclusion of related resources etc. That's why this document type should only be considered as a quick-and-dirty solution, and generally you should choose another, more advanced document type introduced below in the majority of the use cases.

AbstractSingleResourceDocument and AbstractCollectionDocument both need a resource object in order to work, which is a concept introduced in the following sections. For now, it is enough to know that one must be passed for the documents during instantiation. This means that a minimal constructor of your documents should look like this:

You can of course provide other dependencies for your constructor or completely omit it if you don't need it.

When you extend either AbstractSingleResourceDocument or AbstractCollectionDocument, they both require you to implement the following methods:

The description says it very clear: if you want a jsonapi member in your response, then create a new JsonApiObject. Its constructor expects the JSON:API version number and an optional meta object (as an array).

Documents may also have a "meta" member which can contain any non-standard information. The example above adds information about pagination to the document.

Note that the object property is a variable of any type (in this case it is a hypothetical collection), and this is the main "subject" of the document.

This time, we want a self link to appear in the document. For this purpose, we utilize the getResourceId() method, which is a shortcut of calling the resource (which is introduced below) to obtain the ID of the primary resource ($this->resource->getId($this->object)).

The only difference between the AbstractSingleResourceDocument and AbstractCollectionDocument is the way they regard the object. The first one regards it as a single domain object while the latter regards it as an iterable collection.

Usage

Documents can be transformed to HTTP responses. The easiest way to achieve this is to use the JsonApi class and choose the appropriate response type. Successful documents support three kinds of responses:

Documents for error responses

An AbstractErrorDocument can be used to create reusable documents for error responses. It also requires the same abstract methods to be implemented as the successful ones, but additionally an addError() method can be used to include error items.

There is an ErrorDocument too, which makes it possible to build error responses on-the-fly:

Resources

Documents for successful responses can contain one or more top-level resources and included resources. That's why resources are responsible for converting domain objects into JSON:API resources and resource identifiers.

Although you are encouraged to create one transformer for each resource type, you also have the ability to define "composite" resources following the Composite design pattern.

Resources must implement the ResourceInterface. In order to facilitate this job, you can also extend the AbstractResource class.

Children of the AbstractResource class need several abstract methods to be implemented - most of them are similar to the ones seen in the Document objects. The following example illustrates a resource dealing with a book domain object and its "authors" and "publisher" relationships.

Generally, you don't use resources directly. Only documents need them to be able to fill the "data", the "included", and the "relationship" members in the responses.

Hydrators

Hydrators allow us to initialize the properties of a domain object as required by the current HTTP request. This means, when a client wants to create or update a resource, hydrators can help instantiate a domain object, which can then be validated, saved etc.

There are three abstract hydrator classes in Woohoo Labs. Yin:

For the sake of brevity, we only introduce the usage of the latter class as it is simply the union of AbstractCreateHydrator and AbstractUpdateHydrator. Let's have a look at an example hydrator:

According to the book example, the following request:

will result in the following Book domain object:

Exceptions

Woohoo Labs. Yin was designed to make error handling as easy and customizable as possible. That's why all the default exceptions extend the JsonApiException class and contain an error document with the appropriate error object(s). That's why if you want to respond with an error document in case of an exception you need to do the following:

To guarantee total customizability, we introduced the concept of Exception Factories. These are classes which create all the exceptions thrown by Woohoo Labs. Yin. As an Exception Factory of your own choice is passed to every transformer and hydrator, you can completely customize what kind of exceptions are thrown.

The default Exception Factory creates children of JsonApiExceptions but you are free to create any JsonApiExceptionInterface exceptions. If you only want to customize the error document or the error objects of your exceptions, just extend the basic Exception class and create your createErrorDocument() or getErrors() methods.

JsonApi class

The JsonApi class is the orchestrator of the whole framework. It is highly recommended to utilize this class if you want to use the entire functionality of Woohoo Labs. Yin. You can find various examples about the usage of it in the example directory.

JsonApiRequest class

The JsonApiRequest class implements the WoohooLabs\Yin\JsonApi\Request\JsonApiRequestInterface which extends the PSR-7 ServerRequestInterface with some useful, JSON:API related methods. For further information about the available methods, please refer to the documentation of JsonApiRequestInterface.

Advanced Usage

This section guides you through the advanced features of Yin.

Pagination

Yin is able to help you paginate your collection of resources. First, it provides some shortcuts for querying the request query parameters when page-based, offset-based, or cursor-based pagination strategies are used.

Page-based pagination

Yin looks for the page[number] and the page[size] query parameters and parses their value. If any of them is missing then the default page number or size will be used ("1" and "10" in the following example).

Fixed page-based pagination

Yin looks for the page[number] query parameter and parses its value. If it is missing then the default page number will be used ("1" in the following example). This strategy can be useful if you do not want to expose the page size at all.

Offset-based pagination

Yin looks for the page[offset] and the page[limit] query parameters and parses their value. If any of them is missing then the default offset or limit will be used ("1" and "10" in the following example).

Cursor-based pagination

Yin looks for the page[cursor] and the page[size] query parameters and parses their value. If any of them is missing then the default cursor or size will be used ("2016-10-01" or 10 in the following example).

Fixed cursor-based pagination

Yin looks for the page[cursor] query parameter and parses its value. If it is missing then the default cursor will be used ("2016-10-01" in the following example).

Custom pagination

If you need a custom pagination strategy, you may use the JsonApiRequestInterface::getPagination() method which returns an array of pagination parameters.

Usage

As soon as you have the appropriate pagination object, you may use them when you fetch your data from a data source:

Pagination links

The JSON:API spec makes it available to provide pagination links for your resource collections. Yin is able to help you in this regard too. You have use the DocumentLinks::setPagination() method when you define links for your documents. It expects the paginated URI and an object implementing the PaginationLinkProviderInterface as seen in the following example:

To make things even easier, there are some LinkProvider traits in order to ease the development of PaginationLinkProviderInterface implementations of the built-in pagination strategies. For example a collection for the User objects can use the PageBasedPaginationLinkProviderTrait. This way, only three abstract methods has to be implemented:

You can find the full example here.

Loading relationship data efficiently

Sometimes it can be beneficial or necessary to fine-tune data retrieval of relationshipS. A possible scenario might be when you have a "to-many" relationship containing gazillion items. If this relationship isn't always needed than you might only want to return a data key of a relationship when the relationship itself is included in the response. This optimization can save you bandwidth by omitting resource linkage.

An example is extracted from the UserResource example class:

By using the omitDataWhenNotIncluded() method, the relationship data will be omitted when the relationship is not included. However, sometimes this optimization is not enough on its own. Even though we can save bandwidth with the prior technique, the relationship still has to be loaded from the data source (probably from a database), because we pass it to the relationship object with the setData() method.

This problem can be mitigated by lazy-loading the relationship. To do so, you have to use setDataAsCallable() method instead of setData():

This way, the contacts of a user will only be loaded when the given relationship's data key is present in the response, allowing your API to be as efficient as possible.

Injecting metadata into documents

Metadata can be injected into documents on-the-fly. This comes handy if you want to customize or decorate your responses. For example if you would like to inject a cache ID into the response document, you could use the following:

Usually, the last argument of each responder method can be used to add meta data to your documents.

Content negotiation

The JSON:API standard specifies some rules about content negotiation. Woohoo Labs. Yin tries to help you enforce them with the RequestValidator class. Let's first create a request validator to see it in action:

In order to customize the exceptions which can be thrown, it is necessary to provide an Exception Factory. On the other hand, the $includeOriginalMessageInResponse argument can be useful in a development environment when you also want to return the original request body that triggered the exception in the error response.

In order to validate whether the current request's Accept and Content-Type headers conform to the JSON:API specification, use this method:

Request/response validation

You can use the following method to check if the query parameters of the current request are in line with the naming rules:

Note: In order to apply the following validations, remember to install the optional dependencies of Yin.

Furthermore, the request body can be validated if it is a well-formed JSON document:

Similarly, responses can be validated too. Let's create a response validator first:

To ensure that the response body is a well-formed JSON document, one can use the following method:

To ensure that the response body is a well-formed JSON:API document, one can use the following method:

Validating the responses can be useful in a development environment to find possible bugs early.

Custom serialization

You can configure Yin to serialize responses in a custom way instead of using the default serializer (JsonSerializer) that utilizes the json_encode() function to write JSON:API documents into the response body.

In the majority of the use-cases, the default serializer should be sufficient for your needs, but sometimes you might need more sophistication. Or sometimes you want to do nasty things like returning your JSON:API response as an array without any serialization in case your API endpoint was called "internally".

In order to use a custom serializer, create a class implementing SerializerInterface and setup your JsonApi instance accordingly (pay attention to the last argument):

Custom deserialization

You can configure Yin to deserialize requests in a custom way instead of using the default deserializer (JsonDeserializer) that utilizes the json_decode() function to parse the contents of the request body.

In the majority of the use-cases, the default deserializer should be sufficient for your needs, but sometimes you might need more sophistication. Or sometimes you want to do nasty things like calling your JSON:API endpoints "internally" without converting your request body to JSON format.

In order to use a custom deserializer, create a class implementing DeserializerInterface and setup your JsonApiRequest instance accordingly (pay attention to the last argument):

Middleware

If you use a middleware-oriented framework (like Woohoo Labs. Harmony, Zend-Stratigility, Zend-Expressive or Slim Framework 3), you will find the Yin-middleware library quite useful. Read the documentation to learn about its advantages!

Examples

Fetching a single resource

Fetching a collection of resources

Fetching a relationship

Creating a new resource

Updating a resource

Updating a relationship of a resource

How to try it out

If you want to see how Yin works, have a look at the examples. If docker-compose and make is available on your system, then just run the following commands in order to try out the example API:

And finally, just visit the following URL: localhost:8080. You can even restrict the retrieved fields and relationships via the fields and include parameters as specified by JSON:API.

Example URIs for the book examples:

Example URIs for the user examples:

When you finished your work, simply stop the webserver:

If the prerequisites are not available for you, you have to set up a webserver, and install PHP on your host system as well as the dependencies via Composer.

Integrations

Versioning

This library follows SemVer v2.0.0.

Change Log

Please see CHANGELOG for more information on recent changes.

Testing

Woohoo Labs. Yin has a PHPUnit test suite. To run the tests, run the following command from the project folder:

Additionally, you may run docker-compose up or make test in order to execute the tests.

Contributing

Please see CONTRIBUTING for details.

Support

Please see SUPPORT for details.

Credits

License

The MIT License (MIT). Please see the License File for more information.


All versions of yin with dependencies

PHP Build Version
Package Version
Requires php Version ^7.1.0||^8.0.0
psr/http-message-implementation Version ^1.0.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package woohoolabs/yin contains the following files

Loading the files please wait ....