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.

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'
    }
  }
  /* ... */
]

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'
  }
}

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'
  }
}

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

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

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
Sorting is ascending by default and can be reversed by adding a hyphen (-) to the start of the property name.

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. 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 category relationship of our Post:

const posts = await Post.include('category').get()
GET /posts?include=category

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 likes attribute of our Post:

const posts = await Post.append('likes').get()
GET /posts?append=likes

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

Applying Custom Parameters

See the API reference

We may 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

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 using for the example above, 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