我最难弄清楚如何在php中正确格式化graphql api突变POST请求。
如果我对字符串进行硬编码并将其用作 POST 请求中的数据,它的工作方式如下:
'{"query":"mutation{addPlay(input: {title: \"two\"}){ properties { title } } }"}'
但是如果我有一个输入值的 php 数组:
$test_data = array(
'title' => 'two'
);
Run Code Online (Sandbox Code Playgroud)
我似乎无法正确格式化。json_encode 还在 graphql 因错误而拒绝的键周围加上双引号Syntax Error GraphQL request (1:26) Expected Name, found String。
我最终需要一个解决方案,将更大更复杂的数组转换为可用的东西。
我们正在研究一个相当复杂的 GraphQL 模式,其中我们有几个属于各种微服务的对象类型,其中每个对象类型都有一个我们可以查询的自然 API 端点。因此,如果可以直接为某些对象类型定义特定的解析器,则将非常方便,执行如下操作:
const typeDefs = gql`
type Query {
getBook(bookId: ID!): BookPayload
}
type BookPayload {
book: Book
userErrors: UserError
}
type Book {
id: ID!
title: String
author: String
}
`;
const resolvers = {
Query: {
getBook: (parent, args, context, info) => {
return {
book: { id: args.bookId }
}
},
Book: (parent) => { // this object type level resolver doesn't seem to work
return {
id: parent.id,
...fetchBookMetadata(parent.id)
};
}
};
Run Code Online (Sandbox Code Playgroud)
我知道这是一个微不足道的例子,可能看起来有点过度设计,但当模式开始变得非常复杂时,它确实更有意义(至少对我们而言),到处都是数百个交叉引用。现在有解决这个问题的好方法吗?
所以我有一个使用 apollo-server-express 运行的 apollo-server:
const PORT = process.env.PORT || 8000
const graphqlPath = process.env.GRAPHQL || 'graphql'
const app = express()
app.use(cors())
app.use(bodyParser.text({ type: 'application/graphql' }))
const gqlServer = new ApolloServer({
typeDefs: schema,
resolvers,
context: {
me: users[1]
},
debug: true,
tracing: true
})
gqlServer.applyMiddleware({ app, path: `/${graphqlPath}` })
app.listen(PORT, () => console.log(`graphql listening on port ${PORT}`))
module.exports = app
Run Code Online (Sandbox Code Playgroud)
它在本地主机上完美运行,但是将其部署到heroku,当我运行操场时,它变得很奇怪:
以下是控制台错误的示例:
POST <graphql_server_url> 400(错误请求)
错误:响应不成功:收到状态代码 400
我有graphql apollo-server-hapi。我尝试添加缓存控制,如下所示:
const graphqlOptions = {
schema,
tracing: true,
cacheControl: true,
};
Run Code Online (Sandbox Code Playgroud)
但是当我尝试在架构基础上添加缓存选项时:
type Author @cacheControl(maxAge: 60) {
id: Int
firstName: String
lastName: String
posts: [Post]
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误消息:
Error: Unknown directive "cacheControl".
Run Code Online (Sandbox Code Playgroud)
你能帮忙吗,在架构上应用缓存控制的正确方法是什么?
我按照下面的说明进行操作,但似乎不起作用。
是否可以在 graphql 订阅上获得联合结果,特别是在 AppSync 中?
我在 AppSync 中尝试了以下操作,但收到错误“订阅的输出类型无效”
type Mutation {
test1Mutation(test1arg: Test1Input!): Test1,
test2Mutation(test2arg: Test2Input!): Test2
}
union DataMutationResult = Test1 | Test2
type Subscription {
dataMutation(id: ID!): DataMutationResult
@aws_subscribe(mutations: ["test1Mutation", "test2Mutation"])
}
Run Code Online (Sandbox Code Playgroud) 我是 nodejs 和 apollo 服务器的新手,所以不要评判我。
问题听起来与标题完全相同:“如何在解析器函数中获取 graphql 字符串?”。
实际上,每个解析器中都有四个 args:parent、args、context、info。这里的一些信息:https : //www.apollographql.com/docs/apollo-server/essentials/data#type-signature
我决定编写函数,在上下文中收集嵌套对象以重新生成查询字符串。为什么我需要它?好问题。我正在编写微服务,所以当我将嵌套查询嵌套到当前微服务之外的字段时,我通过 http 传递查询。
我的解析器:
eventByID: async (root, args, context) => {
const event = await EventModel.findById(root.id);
event.creator = await nestedContextProvider(context, 'creator', event.creator);
return eventFascade(event); //just fascade for object - nothing serious
Run Code Online (Sandbox Code Playgroud)
},
它引用了nestedContextProvider 来解决嵌套上下文:
const nestedQueryTraverser = (nestedQueryArray) => {
const nestedQueryTraversed = nestedQueryArray.selectionSet.selections.map(element => (
element.selectionSet === undefined
? element.name.value
: `${element.name.value}{${nestedQueryTraverser(element)}}`));
return nestedQueryTraversed;
};
const nestedContextProvider = async (context, checkField, ID) => {
if (context.operation.selectionSet.selections[0].selectionSet.selections …Run Code Online (Sandbox Code Playgroud) 我正在尝试将错误记录到哨兵,但我所能访问的formatError只是不包含本机错误的选项,以便哨兵可以显示堆栈跟踪等等。
我公司具有面向服务的架构。因此,我的应用程序的 GraphQL 服务器必须调用其他服务来完成来自前端的数据请求。
让我们想象一下我的 GraphQL 模式定义了 type User。此类型的数据来自两个来源:
username,age和friends。User仅与我的应用程序相关的相关数据的 SQL 数据库:favoriteFood, favoriteSport.让我们假设用户帐户服务的端点自动返回usernameand age,但您必须传递查询参数friends=true才能检索friends数据,因为这是一项昂贵的操作。
鉴于此背景,以下查询在getUser解析器中提出了一些优化挑战:
query GetUser {
getUser {
username
favoriteFood
}
}
Run Code Online (Sandbox Code Playgroud)
挑战 #1
当getUser解析器向用户帐户服务发出请求时,它如何知道是否也需要请求friends数据?
挑战 #2 当解析器查询我的应用程序的数据库以获取其他用户数据时,它如何知道要从数据库中检索哪些字段?
对于这两个挑战,我能找到的唯一解决方案是通过info解析器接收到的第四个参数检查解析器中的查询。这将允许它找出是否friends应该在对用户帐户服务的 REST 调用中请求,并且它将能够构建正确的SELECT查询以从我的应用程序的数据库中检索所需的数据。
这是正确的方法吗?这似乎是 GraphQL 实现必须一直运行的用例,因此我希望遇到一个被广泛接受的解决方案。但是,我没有找到很多解决这个问题的文章,也没有广泛使用的 NPM 模块似乎存在(graphql-parse-resolve-info是 PostGraphile 的一部分,但每周只有大约 12k 的下载量,而graphql-fields有大约 18.5 k …
这可能编码
架构
import { gql } from 'apollo-server-express';
export default gql`
extend type Mutation {
signUp(
lastName: String!
): String!
}
`;
Run Code Online (Sandbox Code Playgroud)
解析器
{
Query: {},
Mutation: {
signUp: async (
_,
{ lastName}
) => {
try {
console.log(lastName)
return 'ok';
} catch (error) {
return 'error';
}
},
},
};
Run Code Online (Sandbox Code Playgroud)
要求
mutation($lastName:String){
signUp(lastName:$lastName)
}
Run Code Online (Sandbox Code Playgroud)
查询验证
{"lastName":"Darjo" }
Run Code Online (Sandbox Code Playgroud)
我无法理解,但我收到错误
"类型为 \"String\" 的变量 \"$lastName\" 用于期望类型为 \"String!\" 的位置。",
但是当我移除标志时! lastName: String一切正常。
我就是无法理解。是什么原因 ?。
我很惊讶我找不到一个库或示例来执行以下操作:
我想要对服务器的每个请求的简单服务器日志,该日志将说明请求的查询或更改,以及完成请求所用的时间
我知道有插件和扩展框架。但我不确定在两个回调之间保持状态的最佳做法是什么:requestDidStart和willSendResponse
会吐出的东西:
path="createAccountMutation" service=20ms
Run Code Online (Sandbox Code Playgroud)
额外的功劳是显示有效载荷的大小
path="createAccountMutation" service=20ms bytes=355
Run Code Online (Sandbox Code Playgroud)
很想在打字稿中看到解决方案
注意:我找到了apollo-log——但它不做请求持续时间
谢谢!
apollo-server ×10
graphql ×8
apollo ×4
node.js ×3
javascript ×2
aws-appsync ×1
caching ×1
graphql-js ×1
hapijs ×1
heroku ×1
optimization ×1
php ×1
typescript ×1