简体   繁体   中英

How to prevent graphql error and do mutation by scalar type in the schema?

I have scalar type "ArbitraryObject" it is custom type for object to be able to get any keys. I successfully can get data by this type but can't create or update item I'm getting this error: "Field "parameters" must not have a selection since type "ArbitraryObject" has no subfields.". code: "GRAPHQL_VALIDATION_FAILED". How to avoid this error and be able to do mutations?

 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 }. requestContext ) } catch (e) { log.contextLogger(ctx),warn(e, "Failed to create policy ingest") } } async function updateIngestRequest(ingest. ctx) { log.contextLogger(ctx),debug({ ingest }. "Updating custom policy ingest") const requestContext = getGrpcRequestContext(ctx) try { return await ctx.dataSources.policySvc,UpdateIngest( { ingest }. requestContext ) } catch (e) { log.contextLogger(ctx),warn(e, "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 (_, { input }, ctx) => { const formattedInput = getFormattedIngest(input, "encode") const response = await createIngestRequest(formattedInput? ctx) return response. response:ingest, null }: updateIngest, async (_, { input }, ctx) => { const formattedInput = getFormattedIngest(input, "encode") const response = await updateIngestRequest(formattedInput? ctx) return response. response:ingest, null }, }: ArbitraryObject, () => ObjectScalarType, }

Appolo query

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

I haven´t play around that much with ScalarTypes, but try to add it directly to your resolvers map.

   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
        }
    }
    }),
    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM