The make:resource
Assistant command may be used to create a resource class. Resources are placed in your application's app/Http/Resources
directory by default. @ostro/http/resources/json/jsonResource
is a resource that extends the @ostro/http/resources/json/jsonResource
class:
node assistant make:resource UserResource
In addition to developing resources that convert individual models, you can also create resources that transform collections of models. This allows you to add links and other meta information related to a whole collection of a specific resource in your JSON answers.
When establishing a resource, use the —collection
parameter to build a resource collection. Alternatively, inserting the word Collection in the resource name tells OstroJS to construct a collection resource. The @ostro/http/resources/json/resourceCollection
class is extended by collection resources:
node assistant make:resource User --collection
node assistant make:resource UserCollection
Let's take a high-level look at how resources are utilised in OstroJS before digging into all of the choices accessible to you when developing resources. A resource class denotes a single model that must be converted to a JSON representation. Here's an example of a UserResource
resource class:
const jsonResource = require("@ostro/http/resources/json/jsonResources")
class UserResource extends jsonResource {
/**
* Transform the resource into an array/object.
*
*/
static toObject(data) {
return {
'id' : data.id,
'name' : data.name,
'email' : data.email,
'created_at' : data.created_at,
'updated_at' : data.updated_at,
}
}
}
module.exports = UserResource;
Every resource class has a toArray
function that produces an array of characteristics that should be converted to JSON when a route or controller method returns the resource.
It's worth noting that model properties may be accessed straight from the this variable. This is because, for convenience, a resource class will automatically proxy property and method access to the underlying model. A route or controller can return the resource after it has been defined. The resource's function Object() { [native code] } accepts the underlying model instance:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({ response, params }) {
response.send(new UserResource(await User.findOrFail(params.id)));
});
When establishing the resource instance in your route or controller, utilise the collection method offered by your resource class if you're returning a collection of resources or a paginated response:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({ response, params }) {
response.send(UserResource.collection(await User.all()));
});
It's possible that your resource collection
will be returned from a route or controller after you've defined it:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({response,params}) {
response.send(UserResource.collection(await User.all()));
});
In essence, resources are straightforward. They merely have to convert a model into an array. As a result, each resource has a toArray
function that converts your model's characteristics into an API-friendly array that can be returned from your app's routes or controllers:
const jsonResource = require("@ostro/http/resources/json/jsonResources")
class UserResource extends JsonResource
{
/**
* Transform the resource into an array/object.
*
*/
static toObject(data) {
return {
'id' : data.id,
'name' : data.name,
'email' : data.email,
'created_at' : data.created_at,
'updated_at' : data.updated_at,
}
}
}
module.exports = UserResource
A resource
can be returned directly from a route or controller once it has been defined:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({ response, params }) {
response.send(new UserResource(await User.findOrFail(params.id)));
});
You can add related resources to the array produced by your resource's toArray
function if you want to include them in your answer. In this example, we'll utilise the collection method of the PostResource
resource to add the user's blog entries to the resource response:
const PostResource = require('~/app/http/resources/postResource');
/**
* Transform the resource into an array / object.
*
*/
static toObject(data) {
return {
'id' : data.id,
'name' : data.name,
'email' : data.email,
'posts' : PostResource.collection(data.posts),
'created_at' : data.created_at,
'updated_at' : data.updated_at,
};
}
While resources convert a single model to an array, resource collections do the same for a group of models. However, because all resources include a collection
function to construct a "ad-hoc" resource collection on the fly, it is not required to declare a resource collection class for each of your models:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({ response, params }) {
response.send(UserResource.collection(await User.all()));
});
While resources
convert a single model to an array, resource collections do the same for a group of models. However, because all resources include a collection
function to construct a "ad-hoc" resource collection on the fly, it is not required to declare a resource collection class for each of your models:
const ResourceCollection = require("@ostro/http/resources/json/ResourceCollection")
class UserCollection extends ResourceCollection {
/**
* Transform the resource collection into an array / object.
*
*/
static toObject(data) {
return {
'data' : data,
'links' : {
'self' : 'link-value',
},
};
}
}
module.exports = UserCollection
Resource collections
, like solitary resources, can be returned directly from routes or controllers:
const UserResource = require('~/app/http/resources/userResource');
const User = require('~/app/models/user');
Route.get('/user/:id', async function ({ response, params }) {
response.send(new UserResource(await User.all()));
});
You may require a transformation layer between your Eloquent models and the JSON replies that are actually returned to your application's users when constructing an API. For example, you could want to show some properties to a subset of users but not to others, or you might want to always include certain relationships in your models' JSON representation. Eloquent's resource classes make it simple and expressive to convert your models and model collections to JSON.
Of course, you can always use the toJson methods to convert Eloquent models or collections to JSON; but, Eloquent resources allow more comprehensive and robust control over the JSON serialisation of your models and relationships.