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.