如何连接GraphQL和PostgreSQL [英] How to connect GraphQL and PostgreSQL

查看:206
本文介绍了如何连接GraphQL和PostgreSQL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

GraphQL有突变,Postgres有INSERT; GraphQL有查询,Postgres有SELECT。等等。等等。我还没有找到一个示例,说明如何在项目中使用这两个示例,例如,将所有查询从GraphQL中的前端(React,Relay)传递,但实际上将数据存储在Postgres中。

GraphQL has mutations, Postgres has INSERT; GraphQL has queries, Postgres has SELECT's; etc., etc.. I haven't found an example showing how you could use both in a project, for example passing all the queries from front end (React, Relay) in GraphQL, but to a actually store the data in Postgres.

有人知道Facebook作为DB使用的是什么以及它如何与GraphQL连接吗?

Does anyone know what Facebook is using as DB and how it's connected with GraphQL?

现在是否是将数据存储在Postgres中以构建采用GraphQL查询并将其转换为SQL的自定义适配器的唯一选择?

Is the only option of storing data in Postgres right now to build custom "adapters" that take the GraphQL query and convert it into SQL?

推荐答案

GraphQL与数据库无关,因此您可以使用通常用于与数据库进行交互的任何内容,并使用查询或变异的 resolve 方法以调用您定义的函数,该函数将获取/添加一些信息。

GraphQL is database agnostic, so you can use whatever you normally use to interact with the database, and use the query or mutation's resolve method to call a function you've defined that will get/add something to the database.

以下是使用基于promise的 Knex SQL查询生成器进行突变的示例没有Relay的话,您就可以体会到这一概念。我假设您在GraphQL模式中创建了一个具有三个字段的userType: id username ,以及已创建:全部必需,并且您已经定义了 getUser 函数,该函数可查询数据库并返回用户宾语。在数据库中,我也有一个 password 列,但是由于我不希望这样查询,因此将其排除在我的 userType

Here is an example of a mutation using the promise-based Knex SQL query builder, first without Relay to get a feel for the concept. I'm going to assume that you have created a userType in your GraphQL schema that has three fields: id, username, and created: all required, and that you have a getUser function already defined which queries the database and returns a user object. In the database I also have a password column, but since I don't want that queried I leave it out of my userType.

// db.js
// take a user object and use knex to add it to the database, then return the newly
// created user from the db.
const addUser = (user) => (
  knex('users')
  .returning('id') // returns [id]
  .insert({
    username: user.username,
    password: yourPasswordHashFunction(user.password),
    created: Math.floor(Date.now() / 1000), // Unix time in seconds
  })
  .then((id) => (getUser(id[0])))
  .catch((error) => (
    console.log(error)
  ))
);

// schema.js
// the resolve function receives the query inputs as args, then you can call
// your addUser function using them
const mutationType = new GraphQLObjectType({
  name: 'Mutation',
  description: 'Functions to add things to the database.',
  fields: () => ({
    addUser: {
      type: userType,
      args: {
        username: {
          type: new GraphQLNonNull(GraphQLString),
        },
        password: {
          type: new GraphQLNonNull(GraphQLString),
        },
      },
      resolve: (_, args) => (
        addUser({
          username: args.username,
          password: args.password,
        })
      ),
    },
  }),
});

因为Postgres为我创建了 id 我计算了创建的时间戳,我的变异查询中不需要它们。

Since Postgres creates the id for me and I calculate the created timestamp, I don't need them in my mutation query.

graphql-relay 中使用帮助器,并非常靠近继电器入门工具包对我有帮助,因为一次可以吸收很多东西。中继要求您以特定的方式设置架构,以便它可以正常工作,但是想法是相同的:使用您的函数在resolve方法中从数据库获取或添加到数据库。

Using the helpers in graphql-relay and sticking pretty close to the Relay Starter Kit helped me, because it was a lot to take in all at once. Relay requires you to set up your schema in a specific way so that it can work properly, but the idea is the same: use your functions to fetch from or add to the database in the resolve methods.

一个重要的警告是,中继方式希望从 getUser 返回的对象是 User类的实例,因此您必须修改 getUser 来容纳它。

One important caveat is that the Relay way expects that the object returned from getUser is an instance of a class User, so you'll have to modify getUser to accommodate that.

最后一个示例使用中继( fromGlobalId globalIdField mutationWithClientMutationId nodeDefinitions 均来自 graphql-relay ):

The final example using Relay (fromGlobalId, globalIdField, mutationWithClientMutationId, and nodeDefinitions are all from graphql-relay):

/**
 * We get the node interface and field from the Relay library.
 *
 * The first method defines the way we resolve an ID to its object.
 * The second defines the way we resolve an object to its GraphQL type.
 *
 * All your types will implement this nodeInterface
 */
const { nodeInterface, nodeField } = nodeDefinitions(
  (globalId) => {
    const { type, id } = fromGlobalId(globalId);
    if (type === 'User') {
      return getUser(id);
    }
    return null;
  },
  (obj) => {
    if (obj instanceof User) {
      return userType;
    }
    return null;
  }
);

// a globalId is just a base64 encoding of the database id and the type
const userType = new GraphQLObjectType({
  name: 'User',
  description: 'A user.',
  fields: () => ({
    id: globalIdField('User'),
    username: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The username the user has selected.',
    },
    created: {
      type: GraphQLInt,
      description: 'The Unix timestamp in seconds of when the user was created.',
    },
  }),
  interfaces: [nodeInterface],
});

// The "payload" is the data that will be returned from the mutation
const userMutation = mutationWithClientMutationId({
  name: 'AddUser',
  inputFields: {
    username: {
      type: GraphQLString,
    },
    password: {
      type: new GraphQLNonNull(GraphQLString),
    },
  },
  outputFields: {
    user: {
      type: userType,
      resolve: (payload) => getUser(payload.userId),
    },
  },
  mutateAndGetPayload: ({ username, password }) =>
    addUser(
      { username, password }
    ).then((user) => ({ userId: user.id })), // passed to resolve in outputFields
});

const mutationType = new GraphQLObjectType({
  name: 'Mutation',
  description: 'Functions to add things to the database.',
  fields: () => ({
    addUser: userMutation,
  }),
});

const queryType = new GraphQLObjectType({
  name: 'Query',
  fields: () => ({
    node: nodeField,
    user: {
      type: userType,
      args: {
        id: {
          description: 'ID number of the user.',
          type: new GraphQLNonNull(GraphQLID),
        },
      },
      resolve: (root, args) => getUser(args.id),
    },
  }),
});

这篇关于如何连接GraphQL和PostgreSQL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆