Defining Resources
Let's first take a high-level look at how resources are used. A resource class represents a single model/entity from your application that needs to be transformed into a structure of your API (most often JSON).
Source Models (Entities)
Source models are defined by your application which can be for example:
- Doctrine entities,
- Active record instances (eg. Phalcon ORM models),
- Enums,
- Simple arrays, 🤪
- any other object which you want to expose via API.
Basic Usage
If you want to convert your source model to an API resource you have to create a new resource object by passing the source model to the constructor:
// The source model:
$product = $productRepository->find(1);
// The resource:
$resource = new ProductResource($product);
// The HTTP response:
$response = new JsonResponse($resource->resolve());
Creating Resources
For example, here is a simple User resource class:
namespace App\ApiResources;
use Konekt\Resource\Resource;
class User extends Resource
{
public function toArray(): array
{
return [
'id' => $this->attribute('id'),
'name' => $this->attribute('name'),
'email' => $this->attribute('email'),
'created_at' => $this->attribute('created_at'),
'updated_at' => $this->attribute('updated_at')
];
}
}
Do not use the
toArray()
method when returning HTTP responses, use theresolve()
method instead.
Every resource class defines a toArray
method which returns the array of attributes that should be
returned with the HTTP response. Source model properties can be accessed via
$this->attribute('fieldname')
method. This call will fetch the property from the source model via:
$source['field_name']
if the source model is an array,$source->toArray()['field_name']
if the source model has atoArray()
method,$source->__toArray()['field_name']
if the source model has a__toArray()
method,$source->fieldName()
if the fieldName is an "is"-er (starts with 'is', 'has', 'can', 'was', 'should', 'allows') and source has such a method,$source->getFieldName()
if the source model has such a method,$source->fieldName
if the source has such a property (won't work via magic getter),$source->field_name
property (also works via magic getter)
The behavior above is defined by the default built-in transformer that ships with this library. See the Transformers section for details about customization.
Using Resources
Once the resource is defined, it may be returned from a route or controller:
class ProductController
{
public function getAction($request)
{
$product = new ProductResource(Product::find($request->get('id')));
return new JsonResponse($product->resolve());
}
}
Resource Collections
If you are returning a collection of resources, you may use the
collection()
factory method to create a resource instance:
class UserController
{
public function index($request)
{
$users = UserResource::collection(UserRepository::findAll());
return new JsonResponse($users->resolve());
}
}
This method is simple and does not allow any addition of meta data that may need to be returned with the collection.
Separating Collections and Single Resources
If you would like to return responses in different format for collections than for single resources, then you have to create a dedicated resource to represent the collection.
TO BE WRITTEN.. ¯_(ツ)_/¯
Also mention subcollections (to specify the resource and not ->toArray())
Next: Transformers »