如何从服务器执行GraphQL查询

17

我正在使用 graphql-express 创建一个端点,以便可以在其中执行 GraphQL 查询。尽管我正在使用 Sequelize 和 SQL 数据库,但从服务器直接使用它感觉不对,因为它在我的 GraphQL resolve 函数之外。我该如何在与定义它的同一台服务器上查询我的 GraphQL API?

这是我设置 GraphQL 端点的方法:

const express = require('express');
const router = express.Router();
const graphqlHTTP = require('express-graphql');
const gqlOptions = {
   schema: require('./schema')
};
router.use('/', graphqlHTTP(gqlOptions));

modules.exports = router;

基本上我想做的是能够像这样做某事:

query(`
  {
    user(id: ${id}) {
      name
    }
  }
`)

我该如何创建这个query函数?

3个回答

24

GraphQL.js本身不需要HTTP服务器来运行。express-graphql只是一个帮助程序,用于将查询解析器挂载到HTTP端点。

您可以将模式和查询传递给graphql,它会返回一个Promise对象,该对象将查询解析为数据。

graphql({schema, requestString}).then(result => {
  console.log(result);
});

所以:

const {graphql} = require('graphql');
const schema = require('./schema');
function query (requestString) {
  return graphql({schema, requestString});
}

query(`
  {
    user(id: ${id}) {
      name
    }
  }
`).then(data => {
  console.log(data);
})

要获取更多选项,请查看源代码 https://github.com/graphql/graphql-js/blob/fb27b92a5f66466fd8143efc41e1d6b9da97b1f4/src/graphql.js#L62 - Vincent Cantin
这里还有graphql函数的官方文档页面:https://graphql.org/graphql-js/graphql/#graphql - mossjm
1
GraphQL 16 不再支持位置参数。 - jonS90

3

我希望能够完善@aᴍɪʀ的回答,提供正确查询/变更参数的方法:

const params = {
  username: 'john',
  password: 'hello, world!',
  userData: {
    ...
  }
}

query(`mutation createUser(
          $username: String!,
          $password: String!,
          $userData: UserInput) {
  createUserWithPassword(
    username: $username,
    password: $password,
    userData: $userData) {
    id
    name {
      familyName
      givenName
    }
  }
}`, params)

这样,您就不必在各个地方处理字符串构造细节"'


3
查询函数不也需要改变吗?你的调用传递了两个参数而不是一个。 - ZenVentzi

1
感谢其他答案,这是针对Nextjs中的getServerSideProps、getStaticProps、getStaticPaths和getStaticProps,包括MongoDB上下文。需要这个是因为如果你的graphql服务器在api路由中,当你构建它时,它不会构建,因为你在api路由中的服务器没有运行。
Mongo文件:plugin/zDb/index:
import {MongoClient} from "mongodb"

export const connectToDatabase = async() => {
  const client = new MongoClient(process.env.MONGODB_URI, {useNewUrlParser: true, useUnifiedTopology: true})
  let cachedConnection
  if(cachedConnection) return cachedConnection
  try {
    const connection = await client.connect()
    cachedConnection = connection
    return connection
  } catch(error) {
    console.error(error)
  }
}

export const mongoServer = async() => {
  const connect = await connectToDatabase()
  return connect.db(process.env.DB_NAME)
}

在 pages 文件夹中,例如 index.js 文件主页:
import {graphql} from 'graphql'
import {schema} from '@/plugin/zSchema/schema'
import {mongoServer} from '@/plugin/zDb/index'
async function query(source, variableValues) {
  return graphql({schema, source, contextValue: {mongo: await mongoServer()}, variableValues})
}
export async function getServerSideProps(ctx) {
  const listingCurrent = await query(`query($keyField: String, $keyValue: String) {
    ListingRQlistingListKeyValue(keyField: $keyField, keyValue: $keyValue) {
      address
      urlSlug
      imageFeature {
        photoName
      }
    }
  }`, {
    keyField: 'offerStatus'
    , keyValue: 'CURRENT'
  })
  return {props: {
    listingCurrent: listingCurrent.data.ListingRQlistingListKeyValue
  }
}
}

请注意:graphql调用字段名称来自于:https://github.com/graphql/graphql-js/blob/fb27b92a5f66466fd8143efc41e1d6b9da97b1f4/src/graphql.js#L62
export type GraphQLArgs = {|
  schema: GraphQLSchema,
  source: string | Source,
  rootValue?: mixed,
  contextValue?: mixed,
  variableValues?: ?ObjMap<mixed>,
  operationName?: ?string,
  fieldResolver?: ?GraphQLFieldResolver<any, any>,
|};

我的模式文件:plugin/zSchema/schema.js

import { makeExecutableSchema } from '@graphql-tools/schema'
import {resolvers} from '@/plugin/zSchema/resolvers'
import {typeDefs} from '@/plugin/zSchema/typeDefs'

export const schema = makeExecutableSchema({resolvers, typeDefs})

@/plugin 文件夹:我在名为 jsconfig.json 的根文件中使用它,将所有文件夹放在 root/plugin 中,并使用 @/plugin 调用它。您可以按照通常的方式导入自己的文件夹结构。

{
  "compilerOptions": {
    "baseUrl": "."
    , "paths": {
      "@/*": ["./*"]
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接