Nested Query GraphQl

Tags: , , ,



I am new using graphql and I would like to know how could I filter my query to get the recipes that has some of the ingredient objects I have in my input array.

this is the schema.gql file

type Recipe {
  id: Int
  title: String!
  author: String
  link: String
  category: String
  subcategory:String
  ingredients:[Ingredients]
}

type Ingredients{
    id:Int
    name:String!
    quantity:Float!
    measure:String
    observation:String
  }

type Query {
  recipe: [Recipe]
  ingredient:[Ingredients]
}

this recipe schema has 1 respective service

const db = require('../db')

class RecipeService{
  //PENDENTE FINALIZAR ESSA SERVICE
  async getRecipeByIngredient(ingredient)
}

and the respective Query resolvers

 Recipe: {
    async ingredients(recipe, _, { dataSources }) {
      return await dataSources.IngredientService.getRecipeIngredients(recipe.id)
    },
  },
  Query: {
    recipe: async () => db('Recipe'),
    ingredient: async () => db('Ingredient'),
  }

the main idea here is just to have one filter that can see what recipe has some ingredients that the user will inform via APP.

I got the “recipe” query with all the recipes that I have at the database, but I need a query that get these recipes and filter then using the field ingredient, for example:

  1. Recipe – Sugar Cake with the ingredients: Sugar, Honey, Four…
  2. Recipe – Velvet Cake with the ingredients: Sugar, Vanilla, …

and the user inform Sugar, the API should return theses 2 recipes, but if the user inform Sugar, Honey and Four, the API would return only the option 1.

can anyone help me on it?

thanks a lot.

Answer

I got a solution for this and I would like to share with you.

The filter that I implemented on the resolver:

module.exports = {
  Recipe: {
      ingredients(recipe, _, { dataSources }, info) {
        return  dataSources.IngredientService.getRecipeIngredients(recipe.id)
    }
  },
  Query: {
    recipe(obj, {name}, {dataSources}, info) {
      if (name) {
        return dataSources.IngredientService.getIngredientsByName(name)
      } else {
        return db('Recipe')  
      }
    },
    ingredient: async () => db('Ingredient'),
    recipeByIngredient:async () => db('Recipe'),
  }, Mutation: {
    createRecipe: async (_, { data }) => await (await db('Recipe').insert(data).returning('*'))[0],
    updateRecipe: async (_, { data, id }) => await (await db('Recipe').where({ id }).update(data).returning('*'))[0],
    deleteRecipe: async (_, { filter }) => {
      if (filter.id) {
        return await db('Recipe').where({ id: filter.id }).delete()
      }
      if (filter.title) {
        return await db('Recipe').where({ title: filter.title }).delete()
      }
      throw new Error('Should provide the ID or TITLE')
    }
  }
}

With this resolver module, I created a new filter on the “recipe” Query resolver, that receive the “name” of the ingredient to make the filter and pass it to the Service to implement the filter at the database.

Thanks for the support.



Source: stackoverflow