[英]graphql-compose, trigger resolver of a nested field
我是 GraphQL 的初學者,並將其與 Node 和graphql-compose一起使用來創建模式。
我不確定這樣做是否正確: AddressTC
是可重用類型,當創建或更新UserTC
或其他類型時,我想自動觸發AddressTC
的驗證。 如果你知道更好的方法,我會接受的。
// userType.js
// In this example we'll use UserTC but this can another type which also use AdressTC.
const UserTC = schemaComposer.createObjectTC({
name: 'User',
fields: {
id: 'String',
name: 'String',
slug: 'String',
actived: 'Boolean',
registered: 'Boolean',
address: AddressTC,
}
});
const UserITC = UserTC.getInputTypeComposer()
UserTC.addResolver({
kind: 'mutation',
name: 'create',
args: {
data: UserITC
},
type: UserTC,
resolve: async ({args: {data}, context}) => {
// Need to trigger validation and geocode of AddressTC
// do something...
// save in database
},
})
// addressType.js
// reusable Address Type
const AddressTC = schemaComposer.createObjectTC({
name: 'Address',
description: 'Type of address',
fields: {
street: 'String',
number: 'String',
postcode: 'String',
city: 'String',
comment: 'String',
country: 'String',
quality: QualityETC
}
});
const AddressITC = AddressTC.getInputTypeComposer()
AddressTC.addResolver({
kind: 'mutation',
name: 'validation',
args: {
data: AddressITC
},
type: AddressTC,
resolve: async ({args: {data}, context}) => {
// When address is puted or updated :
// Make validation
// Geocode {Lat,Lng} with map provider
// Save in DB
},
})
作為您的問題,您可以使用joi等驗證庫,並在解析器中應用您的驗證模式。
import joi from 'joi'
const UserTC = schemaComposer.createObjectTC({
name: 'User',
fields: {
id: 'String',
name: 'String',
slug: 'String',
actived: 'Boolean',
registered: 'Boolean',
address: AddressTC,
}
});
const UserITC = UserTC.getInputTypeComposer()
/* Create it here, or in the address file and import it here.
Personally, I place the validation schemas in separate files
*/
const addressTCSchema = Joi.object().keys({
street: Joi.string().required(),
number: Joi.number().required(),
city: Joi.string().required(),
postcode: Joi.string().required(),
comment: Joi.string().required(),
country: Joi.string().required(),
})
const userTCSchema = Joi.object({
id: Joi.number().integer().required(),
name: Joi.string()
.pattern(new RegExp('^[a-zA-Z]')).required(),
slug: Joi.string()
.pattern(new RegExp('^[a-zA-Z]')).required(),
actived: Joi.boolean().required(),
registered: Joi.boolean().required(),
address: addressTCSchema
})
UserTC.addResolver({
kind: 'mutation',
name: 'create',
args: {
data: UserITC
},
type: UserTC,
resolve: async ({args: {data}, context}) => {
// Need to trigger validation and geocode of AddressTC
const { error } = userTCSchema.validate(data);
if (error) {
// return or send 400 bad request
}
// do someting...
// save in database
},
})
我建議使用解析器包裝器。 這些用於檢查身份驗證/權限之類的事情,但適用於您正在尋找的某種通用類型驗證。
我相信這篇文檔將幫助您獲得更高層次的理解-
https://graphql-compose.github.io/docs/basics/what-is-resolver.html#wrapping-resolver
您需要了解的是 resolverParams 是如何工作的 (rp)。 您可以通過調查 rps 獲得很多關於查詢中發生的事情的信息,並使用包裝器做很多事情。
本文檔特定於 MongoDB 實現,但可以更改代碼以適應任何 DB。 https://graphql-compose.github.io/docs/plugins/plugin-mongoose.html#access-and-modify-mongoose-doc-before-save
這將是我提到的包裝器 function 的一般布局。 該代碼是從上面提到的 MongoDB 實現中抽象出來的。
function 可能看起來像這樣:
function addressValidationWrapper(resolvers){
Object.keys(resolvers).forEach((k) => {
resolvers[k] = resolvers[k].wrapResolve(next => async rp => {
// check if has address field/type
// validate address
// if address valid - resolve
// else throw error
return next(rp)
})
})
return resolvers
}
實現這一點的最佳方法將基於您的應用程序結構以及您如何組成全局模式。 我建議通讀解析器文檔以找出對您有意義的內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.