sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan forbinder du GraphQL og PostgreSQL

GraphQL er databaseagnostisk, så du kan bruge det, du normalt bruger til at interagere med databasen, og bruge forespørgslen eller mutationens resolve metode til at kalde en funktion, du har defineret, som vil få/føje noget til databasen.

Uden relæ

Her er et eksempel på en mutation, der bruger den løftebaserede Knex SQL-forespørgselsbygger, først uden Relay for at få en fornemmelse af konceptet. Jeg vil antage, at du har oprettet en userType i dit GraphQL-skema, der har tre felter:id , username , og created :alt påkrævet, og at du har en getUser funktion allerede defineret, som forespørger databasen og returnerer et brugerobjekt. I databasen har jeg også et password kolonne, men da jeg ikke vil have det forespurgt, udelader jeg det fra min 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,
        })
      ),
    },
  }),
});

Siden Postgres opretter id for mig og jeg beregner den created tidsstempel, jeg har ikke brug for dem i min mutationsforespørgsel.

The Relay Way

Brug af hjælperne i graphql-relay og det hjalp mig at holde mig ret tæt på Relay Starter Kit, for det var meget at tage ind på én gang. Relay kræver, at du opsætter dit skema på en bestemt måde, så det kan fungere korrekt, men ideen er den samme:Brug dine funktioner til at hente fra eller tilføje til databasen i løsningsmetoderne.

En vigtig advarsel er, at Relay-måden forventer, at objektet returneres fra getUser er en forekomst af en klasse User , så du bliver nødt til at ændre getUser for at imødekomme det.

Det sidste eksempel ved hjælp af Relay (fromGlobalId , globalIdField , mutationWithClientMutationId , og nodeDefinitions er alle fra 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. Hvordan kan jeg flette kolonnerne fra to tabeller til ét output?

  2. Implementering af SQL Server Performance Indicator for forespørgsler, lagrede procedurer og triggere

  3. 5 måder at tælle antallet af brugerdefinerede tabeller i en SQL Server-database

  4. Brug af DateTime i en SqlParameter til Stored Procedure, formateringsfejl