sql >> Databáze >  >> RDS >> PostgreSQL

Jak propojit GraphQL a PostgreSQL

GraphQL je databázový agnostik, takže k interakci s databází můžete použít cokoliv, co běžně používáte, a použít resolve dotazu nebo mutace metoda pro volání funkce, kterou jste definovali a která něco získá/přidá do databáze.

Bez relé

Zde je příklad mutace pomocí nástroje pro vytváření dotazů Knex SQL založeného na slibech, nejprve bez Relay, abyste získali představu o konceptu. Budu předpokládat, že jste ve schématu GraphQL vytvořili userType, které má tři pole:id , username a created :vše povinné a že máte getUser již definovaná funkce, která se dotazuje na databázi a vrací objekt uživatele. V databázi mám také password sloupec, ale protože nechci, aby byl dotazován, vynechám jej ve svém 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,
        })
      ),
    },
  }),
});

Protože Postgres vytváří id pro mě a já počítám created timestamp, nepotřebuji je ve svém dotazu na mutaci.

Způsob relé

Použití pomocníků v graphql-relay a pomohlo mi to, že jsem se držel docela blízko Relay Starter Kit, protože toho bylo hodně najednou. Relay vyžaduje, abyste nastavili své schéma specifickým způsobem, aby mohlo správně fungovat, ale myšlenka je stejná:použijte své funkce k načítání nebo přidávání do databáze v metodách řešení.

Jednou z důležitých výhrad je, že způsob přenosu očekává, že se objekt vrátí z getUser je instancí třídy User , takže budete muset upravit getUser abychom tomu vyhověli.

Poslední příklad s použitím Relay (fromGlobalId , globalIdField , mutationWithClientMutationId a nodeDefinitions všechny jsou 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. Omezení bránící vložení prázdného řetězce do MySQL

  2. Jaký je nejpřímější způsob, jak vyplnit prázdná data ve výsledcích SQL (na konci mysql nebo perl)?

  3. Tipy pro poskytování výkonu databáze MySQL – část první

  4. Jako operátor v Entity Framework?