Getting Started

Installation

Install and configure the package using the following command :

node ace add @foadonis/graphql

Getting Started

To explore the different capabilities of GraphQL we will create a sample GraphQL API for cooking recipes.

Let's start tih the Recipe type, which is the foundation of our API.

We assume that you already know Adonis and its ORM Lucid. The migrations have been omitted from the tutorial.

Create our Recipe type

The Recipe

We will start with a basic Recipe model.

app/models/recipe.ts
import { ,  } from '@adonisjs/lucid/orm'
import {  } from 'luxon'

export default class  extends  {
  @({ : true })
  declare : string

  @()
  declare : string

  @()
  declare : string | null

  @()
  declare : string[]
}

The ObjectType

We now need to create an object type from our model. It will then be used in our GraphQL schema.

app/models/recipe.ts
import { ,  } from '@adonisjs/lucid/orm'
import { , ,  } from '@foadonis/graphql'
import {  } from 'luxon'

@()
export default class  extends  {
  @({ : true })
  @(() => )
  declare : string

  @()
  @()
  declare : string

  @()
  @({ : true })
  declare : string | null

  @()
  @(() => [])
  declare : string[]
}

For simplicity here we use directly our model in our schema, but you can create a type from any class.

Create the CRUD operations

After that we want to create typical crud operations. Also called queries and mutations. For this we have to create a Resolver (similar to a controller).

The Resolver

app/graphql/recipe_resolver.ts
import  from '#models/recipe'
import { , , , , ,  } from '@foadonis/graphql'

@()
export default class  {
  @(() => )
  (@('id') : number) {
    return .findOrFail()
  }

  @(() => [])
  (@() { ,  }: ) {
    return .query().paginate(, )
  }

  @(() => )
  (@('newRecipeData') : ) {
    return .create()
  }

  @(() => )
  async (@('id') : number) {
    const  = await .find()

    if (!) {
      return false
    }

    await .delete()
    return true
  }
}

The Inputs and Arguments

We are missing two important pieces, the inputs for the recipes query and the arguments for the addRecipe mutation. Let's create them:

app/graphql/recipe_resolver.ts
import { , , ,  } from '@foadonis/graphql'

@()
class  {
  @(() => )
  : number = 0

  @(() => )
  : number = 0
}

@()
class  {
  @()
  declare : string

  @({ : true })
  declare ?: string

  @(() => [])
  declare : string[]
}

Register the Resolver

We must now register our Resolver with the GraphQL server:

start/graphql.ts
import  from '@foadonis/graphql/services/main'

.([() => import('#graphql/resolvers/recipe_resolver')])
Only the root resolvers must be registered this way.

Access the Playground

Everything is now ready!

You can access the GraphQL playground at http://localhost:3000/graphql and start playing with your queries and mutations.

GraphQL Playground

On this page