简单Express-GraphQL CRUD

时间:2019-08-05 04:32:59

标签: express mongoose graphql

我是GraphQL的新手。我使用一个简单的CRUD样板来理解这些概念。除更新外,所有功能均有效。 该文档放置在远程MongoDB云中。我可以查询文档列表,创建一个新文档,然后按ID删除。问题仅在于更新。 解析器或架构中可能有问题吗? 谢谢大家!

以下是架构代码(放置在schema.js中):

const { buildSchema } = require('graphql');

module.exports = buildSchema(`
type Hero {
  _id: ID!
  title: String!
  description: String
  date: String!
}
input HeroInput {
  title: String!
  description: String!
  date: String!
}
type RootQuery {
    heroes: [Hero!]!
}
type RootMutation {
    createHero(heroInput: HeroInput): Hero
    deleteHero(id: ID!): Hero
    updateHero(heroInput: HeroInput): Hero
}
schema {
    query: RootQuery
    mutation: RootMutation
}
`);

解析器(放置在resolvers.js中):

const Hero = require('./models/hero');

module.exports = {
  heroes: () => {
    return Hero.find()
      .then(heroes => {
        return heroes.map(hero => {
          return { ...hero._doc, _id: hero.id };
        });
      })
      .catch(err => {
        throw err;
      });
  },
  createHero: args => {
    const hero = new Hero({
      title: args.heroInput.title,
      description: args.heroInput.description,
      date: new Date(args.heroInput.date)
    });
    return hero
      .save()
      .then(result => {
        console.log(result);
        return { ...result._doc, _id: result._doc._id.toString() };
      })
      .catch(err => {
        console.log(err);
        throw err;
      });
  },
  deleteHero: async () => {
    try {
      const hero = await Hero.findById('5d46ccdf437d4a1b111da61b');
      hero.remove();
    } catch (err) {
      throw err;
    }
  },
  updateHero: args => {
    const hero = Hero.findById('5d46ccdf437d4a1b111da61b');
    hero.title = args.heroInput.title;
    hero.description = args.heroInput.description;
    hero.date = new Date(args.heroInput.date);
    return hero
      .save()
      .then(result => {
        console.log(result);
        return { ...result._doc, _id: result._doc._id.toString() };
      })
      .catch(err => {
        console.log(err);
        throw err;
      });
  }
};

出于说明目的,我放置了一个app.js代码:

const express = require('express');
const bodyParser = require('body-parser');
const graphqlHttp = require('express-graphql');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv/config');

const graphQlSchema = require('./schema');
const graphQlResolvers = require('./resolvers');

const app = express();

app.use(bodyParser.json());
app.use(cors());

app.use(
  '/graphql',
  graphqlHttp({
    schema: graphQlSchema,
    rootValue: graphQlResolvers,
    graphiql: true
  })
);

mongoose.connect(
  `mongodb+srv://${process.env.MONGO_USER}:${process.env.MONGO_PASSWORD}@cluster0-vuauc.mongodb.net/${process.env.MONGO_DB}?retryWrites=true&w=majority`,
  { useNewUrlParser: true }
).then(() => {
  console.log('Connection to database established...')
  app.listen(5555);
}).catch(err => {
  console.log(err);
});

2 个答案:

答案 0 :(得分:1)

updateHero: async (hero_id, args) => {
    try {
        const newHero = await Hero.findByIdAndUpdate(hero_id, args, { new: true });
        return newHero;
    } catch (err) {
        console.log(err);
        throw err;
    }
}

在这里newHero将返回更新的文档,假设'hero_id'是动态的。

hero.title = args.heroInput.title;
hero.description = args.heroInput.description;

不需要像 hero.title hero.description 那样做,只需传递新的 args 所需的内容,例如

{title: 'new_title'}

答案 1 :(得分:0)

我编辑了代码,并检查了代码的工作方式。如果有人感兴趣,请参见下面的更新的架构和解析器。

以下是架构:

const { buildSchema } = require('graphql');

module.exports = buildSchema(`
type Hero {
  _id: ID!
  title: String!
  description: String
  date: String!
}
input HeroInput {
  title: String!
  description: String!
  date: String!
}
input HeroUpdate {
  _id: ID!
  title: String!
  description: String
  date: String!
} 
input HeroRemove {
  _id: ID! 
} 
type RootQuery {
    heroes: [Hero!]!
}
type RootMutation {
    createHero(heroInput: HeroInput): Hero
    deleteHero(heroRemove: HeroRemove): Hero
    updateHero(heroUpdate: HeroUpdate): Hero
}
schema {
    query: RootQuery
    mutation: RootMutation
}
`);

解析器:

const Hero = require('./models/hero');

module.exports = {
  heroes: () => {
    return Hero.find()
      .then(heroes => {
        return heroes.map(hero => {
          return { ...hero._doc, _id: hero.id };
        });
      })
      .catch(err => {
        throw err;
      });
  },
  createHero: args => {
    const hero = new Hero({
      title: args.heroInput.title,
      description: args.heroInput.description,
      date: new Date(args.heroInput.date)
    });
    return hero
      .save()
      .then(result => {
        console.log(result);
        return { ...result._doc, _id: result._doc._id.toString() };
      })
      .catch(err => {
        console.log(err);
        throw err;
      });
  },
  deleteHero: async (args) => {
    try {
      const hero = await Hero.findById(args.heroRemove._id);
      hero.remove();
    } catch (err) {
      throw err;
    }
  },
  updateHero: async (args) => {
    try {
      const newHero = await Hero.findByIdAndUpdate(
        args.heroUpdate._id,
        {
          title: args.heroUpdate.title,
          description: args.heroUpdate.description,
          date: new Date(args.heroUpdate.date)
        },
        { new: true }
      );
      return newHero;
    } catch (err) {
      console.log(err);
      throw err;
    }
  }
};