PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Cách kết nối GraphQL và PostgreSQL

GraphQL là cơ sở dữ liệu bất khả tri, vì vậy bạn có thể sử dụng bất cứ thứ gì bạn thường sử dụng để tương tác với cơ sở dữ liệu và sử dụng resolve của truy vấn hoặc đột biến để gọi một hàm mà bạn đã xác định sẽ lấy / thêm thứ gì đó vào cơ sở dữ liệu.

Không có chuyển tiếp

Dưới đây là một ví dụ về đột biến bằng cách sử dụng trình tạo truy vấn Knex SQL dựa trên lời hứa, trước tiên không có Chuyển tiếp để có cảm nhận về khái niệm này. Tôi sẽ giả sử rằng bạn đã tạo một userType trong lược đồ GraphQL có ba trường:id , usernamecreated :tất cả đều bắt buộc và bạn có getUser đã xác định hàm nào truy vấn cơ sở dữ liệu và trả về một đối tượng người dùng. Trong cơ sở dữ liệu, tôi cũng có một password , nhưng vì tôi không muốn nó được truy vấn nên tôi bỏ nó ra khỏi userType của mình .

// 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,
        })
      ),
    },
  }),
});

Vì Postgres tạo id cho tôi và tôi tính toán created dấu thời gian, tôi không cần chúng trong truy vấn đột biến của mình.

Cách chuyển tiếp

Sử dụng trình trợ giúp trong graphql-relay và việc gắn bó khá chặt chẽ với Bộ khởi động tiếp sức đã giúp ích cho tôi, bởi vì nó rất nhiều thứ để thực hiện tất cả cùng một lúc. Relay yêu cầu bạn thiết lập lược đồ của mình theo một cách cụ thể để nó có thể hoạt động bình thường, nhưng ý tưởng vẫn giống nhau:sử dụng các hàm của bạn để tìm nạp hoặc thêm vào cơ sở dữ liệu trong các phương thức giải quyết.

Một lưu ý quan trọng là cách Relay mong đợi rằng đối tượng được trả về từ getUser là một bản sao của một lớp User , vì vậy bạn sẽ phải sửa đổi getUser để đáp ứng điều đó.

Ví dụ cuối cùng sử dụng Relay (fromGlobalId , globalIdField , mutationWithClientMutationIdnodeDefinitions tất cả đều từ 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),
    },
  }),
});


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Các khóa chính với Apache Spark

  2. lỗi khi cài đặt psycopg2, không tìm thấy thư viện cho -lssl

  3. Thực hiện truy vấn hàng giờ hoạt động này trong PostgreSQL

  4. Chèn Từ điển Python bằng Psycopg2

  5. Lỗi drop Rails + Postgres:cơ sở dữ liệu đang được người dùng khác truy cập