微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何防止graphql错误并通过模式中的标量类型进行突变?

如何解决如何防止graphql错误并通过模式中的标量类型进行突变?

我有标量类型“ArbitraryObject”,它是对象的自定义类型,可以获取任何键。我成功地可以通过这种类型获取数据,但无法创建或更新项目我收到此错误:“字段“参数”不能有选择,因为“ArbitraryObject”类型没有子字段。”。代码:“GRAPHQL_VALIDATION_Failed”。如何避免这个错误并能够进行突变?

import * as log from "../../logger"
import { getGrpcRequestContext } from "../../clients"
import { struct } from "pb-util"
import { GraphQLScalarType } from "graphql"
import { Kind } from "graphql/language"

export const typeDefs = `
    scalar ArbitraryObject

    enum FieldTransformOperation {
        copY
        EXTRACT_SUBSTRING
        EXTRACT_REGULAR_EXPRESSION
    }
    
    type ParametersTransform {
        preTagField: String
        substringReplacements: ArbitraryObject
        groupNamesToTagsMap: ArbitraryObject
        replacementGroupsMap: ArbitraryObject
        targetGroup: String
    }

    type FieldTransform {
        sourceKey: String
        operation: FieldTransformOperation
        parameters: ParametersTransform
    }

    type Ingest {
        name: String
        requiredKeys: [String]
        fieldTransforms: [FieldTransform]
    }  

    input PolicyByNameInput {
        name: String!
    }

    input ParametersTransformInput {
        preTagField: String
        substringReplacements: ArbitraryObject
        groupNamesToTagsMap: ArbitraryObject
        replacementGroupsMap: ArbitraryObject
        targetGroup: String
    }

    input FieldTransformInput {
        sourceKey: String
        operation: FieldTransformOperation
        parameters: ParametersTransformInput
    }
    
    input IngestInput {
        name: String
        requiredKeys: [String]
        fieldTransforms: [FieldTransformInput]
    }

    extend type Query {
        defaultIngest(input: PolicyByNameInput): Ingest
    }

    extend type Mutation {
        createIngest(input: IngestInput): Ingest
        updateIngest(input: IngestInput): Ingest
    }
`

// custom Object type for the possibility to have Object with any keys
const ObjectScalarType = () => new GraphQLScalarType({
    name: 'ArbitraryObject',description: 'Arbitrary object',parseValue: (value) => {
        try {
            return JSON.stringify(value)
        } catch (e) {
            log.contextLogger(e).error(e,"Failed to parse field transform additional data")
            return null
        }
    },serialize: (value) => {
            if (value === 'object' || value.length) {
                return value
            } else {
                try {
                   return  JSON.parse(value)
                } catch (e) {
                    log.contextLogger(e).error(e,"Failed to serialize field transform additional data")
                    return null
                }
            }
    },parseLiteral: (ast) => {
        switch (ast.kind) {
            case Kind.STRING: return JSON.parse(ast.value)
            case Kind.OBJECT: throw new Error(`Failed to parse arbitrary object for ObjectScalarType`)
            default: return null
        }
    }
})

async function getDefaultIngest(name,ctx) {
    log.contextLogger(ctx).debug({ name },"Getting default policy ingest")
    const requestContext = getGrpcRequestContext(ctx)
    try {
        return await ctx.dataSources.policySvc.GetDefaultIngest(
            name,requestContext
        )
    } catch (e) {
        log.contextLogger(ctx).warn(e,"Failed to get default policy ingest")
    }
}

async function createIngestRequest(ingest,ctx) {
    log.contextLogger(ctx).debug({ ingest },"Creating custom policy ingest")
    const requestContext = getGrpcRequestContext(ctx)
    try {
        return await ctx.dataSources.policySvc.CreateIngest(
            { ingest },"Failed to create policy ingest")
    }
}

async function updateIngestRequest(ingest,"Updating custom policy ingest")
    const requestContext = getGrpcRequestContext(ctx)
    try {
        return await ctx.dataSources.policySvc.UpdateIngest(
            { ingest },"Failed to update policy ingest")
    }
}

// encode/decode for grcp struct "parameters"
function getFormattedIngest(data,action) {
    const ingest = data
    if(ingest.fieldTransforms && ingest.fieldTransforms.length) {
        ingest.fieldTransforms = ingest.fieldTransforms.map(field => {
            if(field.parameters) {
                const decodedParams = struct[action](field.parameters)
                return {...field,parameters: decodedParams}
            } else {
                return field
            }
        })
    }
    return ingest
}

export const resolvers = {
    Query: {
        defaultIngest: async (_,{ input },ctx) => {
            const response = await getDefaultIngest(input,ctx)
            return response ? getFormattedIngest(response.ingest,"decode") : null
        },Mutation: {
        createIngest: async (_,ctx) => {
            const formattedInput = getFormattedIngest(input,"encode")
            const response = await createIngestRequest(formattedInput,ctx)
            return response ? response.ingest : null
        },updateIngest: async (_,"encode")
            const response = await updateIngestRequest(formattedInput,},ArbitraryObject: () => ObjectScalarType,}

Appolo 查询

gql`query ${scope}Ingest($input: PolicyByNameInput){
                policy: ${scope}Ingest(input: $input) {
                    name
                    requiredKeys
                    fieldTransforms {
                        sourceKey
                        operation
                        parameters {
                            preTagField
                            targetGroup
                            substringReplacements
                            groupNamesToTagsMap
                            replacementGroupsMap
                        }
                    }
            }`

解决方法

我没有过多地使用 ScalarTypes,但尝试将其直接添加到您的解析器映射中。

   export const resolvers = {
    ArbitraryObject: new GraphQLScalarType({
      name: 'ArbitraryObject',description: 'Arbitrary object',parseValue: (value) => {
        try {
            return JSON.stringify(value)
        } catch (e) {
            log.contextLogger(e).error(e,"Failed to parse field transform additional data")
            return null
        }
    },serialize: (value) => {
            if (value === 'object' || value.length) {
                return value
            } else {
                try {
                   return  JSON.parse(value)
                } catch (e) {
                    log.contextLogger(e).error(e,"Failed to serialize field transform additional data")
                    return null
                }
            }
    },parseLiteral: (ast) => {
        switch (ast.kind) {
            case Kind.STRING: return JSON.parse(ast.value)
            case Kind.OBJECT: throw new Error(`failed to parse arbitrary object for ObjectScalarType`)
            default: return null
        }
    }
    }),...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。