Building the Query
See the API reference for a list of available query builder methods.
With our models already set up, it's time to start using them!
Retrieving a List of Records
See the API reference
Let's start initializing a model and building a simple query that gets all records from the database.
To achieve this, we can use the get
method or its alias all
.
We can get a list of posts using the Post model:
const posts = new Post().get()
GET /posts
[
/* ... */
{
id: 1,
title: 'Post 1',
text: 'Some text here...',
user: {
id: 1,
firstName: 'Joe',
lastName: 'Doe'
}
},
{
id: 2,
title: 'Post 2',
text: 'Some text here...',
user: {
id: 2,
firstName: 'John',
lastName: 'Doe'
}
}
/* ... */
]
Just for convenience, it's possible to make Static calls. We are going to use this approach from now on:
const posts = await Post.get()
GET /posts
[
/* ... */
{
id: 1,
title: 'Post 1',
text: 'Some text here...',
user: {
id: 1,
firstName: 'Joe',
lastName: 'Doe'
}
},
{
id: 2,
title: 'Post 2',
text: 'Some text here...',
user: {
id: 2,
firstName: 'John',
lastName: 'Doe'
}
}
/* ... */
]
$get
method or its alias
$all
,
which handle and unwrap responses within "data".
Retrieving a Single Record
To retrieve a single record from the database, we can use two methods:
first
- Get the first record of a list of records.find
- Find a specific record in the database.
Getting the First Record
See the API reference
Let's start using first
. This method will internally use get
to retrieve a list of records
and then return the first one.
To get the first Post of a list:
const posts = await Post.first()
GET /posts
{
id: 1,
title: 'Post 1',
text: 'Some text here...',
user: {
id: 1,
firstName: 'Joe',
lastName: 'Doe'
}
}
$first
method, which handle and unwrap responses within "data".
Finding a Specific Record
See the API reference
Different from first
, the find
method wil request a specific record from the database.
An identifier must be passed as argument.
To find a specific Post:
const posts = await Post.find(1)
GET /posts/1
{
id: 1,
title: 'Post 1',
text: 'Some text here...',
user: {
id: 1,
firstName: 'Joe',
lastName: 'Doe'
}
}
$find
method, which handle and unwrap responses within "data".
Filtering
One of the most important parts when building a query is filtering, so let's get started!
There are two methods we can use to filter our queries:
where
- Evaluate a value against the column.whereIn
- Evaluate multiple values against the column.
We can use these methods as many times as we want.
Evaluating a Single Value
See the API reference
The where
method can be used to filter the query by evaluating a value against the column.
The first argument is the name of the column, and the second argument is the value to evaluate.
We can filter our Posts to only get results where status
is published
:
const posts = await Post.where('status', 'published').get()
GET /posts?filter[status]=published
Nested Filter
The first argument of where
also accepts an array of keys, which are used to build a nested filter.
So we can filter our Posts to only get results where status
of user
is active
:
const posts = await Post.where([
'user', 'status'
], 'active').get()
GET /posts?filter[user][status]=active
Using an Object
Now is also possible to pass an object.
const posts = await Post.where({
status: 'published',
user: {
status: 'active'
}
}).get()
GET /posts?filter[status]=published&filter[user][status]=active
Evaluating Multiple Values
See the API reference
The whereIn
method is similar to where
, but it accepts multiple values instead of a single one.
The first argument is the name of the column,
and the second argument is an array of values to evaluate.
We can filter our Posts to only get results where status
is published
or archived
:
const posts = await Post.whereIn('status', [
'published', 'archived'
]).get()
GET /posts?filter[status]=published,archived
Nested Filter
The first argument of whereIn
also accepts an array of keys, which are used to build a nested filter.
So we can filter our Posts to only get results where status
of user
is active
or inactive
:
const posts = await Post.whereIn(['user', 'status'], [
'active', 'inactive'
]).get()
GET /posts?filter[user][status]=active,inactive
Using an Object
Now is also possible to pass an object.
const posts = await Post.where({
status: ['published', 'archived'],
user: {
status: ['active', 'inactive']
}
}).get()
GET /posts?filter[status]=published,archived&filter[user][status]=active,inactive
Sorting
See the API reference
We also need to sort our queries, so let's do this now!
The method we want to use now is orderBy
. The arguments are the names of the properties we want to sort.
We can pass as many arguments as we want.
Single Sort
We can sort our Posts by the created_at
date:
const posts = await Post.orderBy('-created_at').get()
GET /posts?sort=-created_at
Multiple Sort
And we can sort by their title
too:
const posts = await Post.orderBy('-created_at', 'title').get()
GET /posts?sort=-created_at
Using an Array
The first argument of orderBy
also accepts an array of string.
const posts = await Post.orderBy(['-created_at', 'title']).get()
GET /posts?sort=-created_at
Including Relationships
See the API reference
Sometimes, we will want to eager load a relationship, and to do so, we can use the include
method or its alias with
.
The arguments are the names of the relationships we want to include. We can pass as many arguments as we want.
Let's eager load the relationships category
and tags
of our Post:
const posts = await Post.include('category', 'tags').get()
GET /posts?include=category,tags
Using an Array
The first argument of include
also accepts an array of string.
const posts = await Post.include(['category', 'tags']).get()
GET /posts?include=category,tags
Appending Attributes
See the API reference
We can also append attributes to our queries using the append
method.
The arguments are the names of the attributes we want to append. We can pass as many arguments as we want.
Let's append the attribute likes
and shares
of our Post:
const posts = await Post.append('likes', 'shares').get()
GET /posts?append=likes,shares
Using an Array
The first argument of append
also accepts an array of string.
const posts = await Post.append(['likes', 'shares']).get()
GET /posts?append=likes,shares
Selecting Fields
See the API reference
If we only need some fields of the model, we can easily select them using the select
method.
If the fields we want to select only belongs to the model, we can pass a list of strings
as the arguments.
But if we want to select fields of relationships as well, then we need to pass an object.
Fields of the Model
The arguments are the names of the fields we want to select. We can pass as many arguments as we want.
We can select only the title
and the text
fields of our Post model:
const posts = await Post.select('title', 'text').get()
GET /posts?fields[posts]=title,text
Fields of Relationships
The argument is an object, which the name of the first key is the resource
defined in the model class,
the name of the other keys are the included relationships, and the values are arrays of fields.
We can select only the name
field of the category we have to eager loaded:
const posts = await Post.include('category').select({
posts: ['title', 'text'],
category: ['name']
}).get()
GET /posts?include=category&fields[posts]=title,text&fields[category]=name
Paginating
A very important feature is paginating, so let's do it now!
There are two methods we will be using here:
page
- Set the current page.limit
- Set the limit of records per page.
Both methods accept a number as an argument.
Let's say we are at page 1, and we want 20 Posts per page:
const posts = await Post.page(1).limit(20).get()
GET /posts?page=1&limit=20
Conditional
We may need to add a clause based on a condition, and we can do so by using the when
method.
The first argument is the flag, and the second argument is the callback with the clause we want.
const search = 'foo'
const posts = await Post.when(search, (query, value) => query.where('title', value)).get()
GET /posts?filter[title]=foo
Applying Custom Parameters
See the API reference
We may also need to use parameters that are not provided by vue-api-query,
and that's when the params
method comes in to help.
The argument is an object of the parameters to add to the query.
const posts = await Post.params({
doSomething: 'yes',
process: false,
multiple: ['awesome', 'amazing', 'super']
}).get()
GET /posts?doSomething=yes&process=false&multiple=awesome,amazing,super
Calling a Custom Resource
See the API reference
In some situations we may also need to define a custom resource endpoint for our model directly in the query. We can override
the default resource dynamically by calling the custom
method.
Defining a Static Resource
If the custom resource is static, you can simply pass the string as an argument.
We can change the Post resource to get the latest Posts:
const posts = await Post.custom('posts/latest').get()
GET /posts/latest
Defining a Dynamic Resource
But it's also possible to build dynamic resource endpoints with hierarchies, by supplying the arguments in the correct order. It accepts models and strings as arguments. If a model is passed, the model's resource will be used, as well as its primary key's value if available.
We can build a resource to get the latest Posts
that belongs to a User:
const user = await User.find(1)
const posts = await Post.custom(user, post, 'latest').get()
GET /users/1
GET /users/1/posts/latest
Configuring the Request
See the API reference
The config
method can be used to configure the current request at query builder. We can pass any config available
from the HTTP Instance. If we are using Axios,
we should pass an AxiosRequestConfig.
We can add headers, change the method, anything we want:
await Post.config({ headers: { /*...*/ } }).get()
Needless Parent Request
One thing to note is that in some cases we may not need to make a request to parent to build the query we want.
If we already know the model's ID, we just need to initialize the model instance with the ID, instead of use find
.
We can get a list of Posts that belongs to an User:
const user = new User({ id: 1 })
const posts = user.posts().get()
GET /users/1/posts
And the same thing can be done if we want to define a dynamic resource.
We can create a new User instance with the ID:
const user = new User({ id: 1 })
const posts = await Post.custom(user, post, 'latest').get()
GET /users/1/posts/latest
Mixing Everything Up
Let's mix everything we have learned so far!
We can get a list of latest Posts, where status
is published
, include the category
relation, append likes
attribute, select title
and text
fields, order by created_at
,
paginate and custom parameters:
const user = new User({ id: 1 })
const posts = await Post
.where('status', 'published')
.include('category')
.append('likes')
.select('title', 'text')
.orderBy('-created_at')
.page(1)
.limit(20)
.params({ process: false })
.custom(user, post, 'latest')
.get()
GET /users/1/posts/latest
?filter[status]=published
&include=category
&append=likes
&fields[posts]=title,text
&sort=-created_at
&page=1
&limit=20
&process=false