PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak połączyć GraphQL i PostgreSQL

GraphQL jest niezależny od bazy danych, więc możesz użyć wszystkiego, czego zwykle używasz do interakcji z bazą danych i użyć resolve zapytania lub mutacji metoda do wywołania zdefiniowanej przez Ciebie funkcji, która pobierze/doda coś do bazy danych.

Bez przekaźnika

Oto przykład mutacji przy użyciu opartego na obietnicach konstruktora zapytań Knex SQL, najpierw bez Relay, aby poznać koncepcję. Zakładam, że utworzyłeś userType w swoim schemacie GraphQL, który ma trzy pola:id , username i created :wszystko wymagane i masz getUser już zdefiniowana funkcja, która wysyła zapytanie do bazy danych i zwraca obiekt użytkownika. W bazie mam też password kolumna, ale ponieważ nie chcę tego zapytania, zostawiam go poza moim 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,
        })
      ),
    },
  }),
});

Ponieważ Postgres tworzy id dla mnie i obliczam created znacznik czasu, nie potrzebuję ich w moim zapytaniu dotyczącym mutacji.

Droga przekaźnikowa

Korzystanie z pomocników w graphql-relay pomogło mi trzymanie się całkiem blisko zestawu startowego Relay Starter Kit, ponieważ było to dużo do ogarnięcia na raz. Relay wymaga skonfigurowania schematu w określony sposób, aby mógł działać poprawnie, ale idea jest taka sama:użyj swoich funkcji do pobierania lub dodawania do bazy danych w metodach rozwiązywania.

Jednym ważnym zastrzeżeniem jest to, że sposób przekazywania oczekuje, że obiekt zwrócony przez getUser jest instancją klasy User , więc będziesz musiał zmodyfikować getUser aby to dostosować.

Ostatni przykład z użyciem Relay (fromGlobalId , globalIdField , mutationWithClientMutationId i nodeDefinitions wszystkie pochodzą z 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. Czy kolejność tabel w złączeniu ma znaczenie, gdy używane są złączenia LEWE (zewnętrzne)?

  2. Jak przechowywać tablicę lub wiele wartości w jednej kolumnie?

  3. Czy mogę pisać funkcje PostgreSQL w Ruby on Rails?

  4. Jak działa funkcja Scale() w PostgreSQL

  5. Wyszukaj w tablicy JSON obiekt zawierający wartość pasującą do wzorca