1

I am developing an application that has a quite sizeable amount of Queries and Mutation. Structures for data are often not complex, but there is plenty of them, so I have made myself a snippet, that generates the most common things repeating throughout them. This snippet also generates an input for mutations so it can be used for both simple and complex data structures. In quite a bit of instances, the input is just for adding a name. The API is supposed to be used mainly by my fronted, but after the app gets mature enough should be publicly available. Is doing this a problem in terms on conventions?

Sample of what I mean

/*=============================================
                    Types
=============================================*/
interface AddSampleSchemaInput {
    input: AddSampleSchema
}
interface AddSampleSchema {
    name: string
}
/*=============================================
                    Main
=============================================*/
export const SampleSchemaModule = {
    typeDefs: gql`
        type Mutation {
            addSampleSchema(input: AddSampleSchemaInput): SampleSchema!
        }
        type SampleSchema {
            _id: ID!
            name: String!
        }
        input AddSampleSchemaInput {
            name: String!
        }
        `
    ,
    resolvers: {
        Mutation: {
            addSampleSchema: async (parents: any, args: AddSampleSchemaInput, context: GraphqlContext) => {
            }
        }
    }
}

Sample of what I assume it should be.

/*=============================================
                    Main
=============================================*/
export const SampleSchemaModule = {
    typeDefs: gql`
        type Mutation {
            addSampleSchema(name: String): SampleSchema!
        }
        type SampleSchema {
            _id: ID!
            name: String!
        }
        `
    ,
    resolvers: {
        Mutation: {
            addSampleSchema: async (parents: any, args: { name: string }, context: GraphqlContext) => {
            }
        }
    }
}

export default SampleSchemaModule

Would usage of the first code example be a problem. This means using input (input AddSampleSchemaInput), even if it were to contain just a single value (in this case name).

Or in other words is using input for every mutation a problem no matter the complexity.

Or the impact on frontent:

addDogBreed({
    variables: {
        input: { 
            name: "Retriever",
            avergeHeight: 0.65
        }
    }
})
addDog({
    variables: {
        input: { 
            name: "Charlie"
        }
    }
})
// ======= VS =======
addDogBreed({
    variables: {
        input: { 
            name: "Retriever",
            avergeHeight: 0.65
        }
    }
})
addDog({
    variables: {
        name: "Charlie"
    }
})

In this case, is having the first one instead of the second one a problem?

MalwareMoon
  • 788
  • 1
  • 2
  • 13
  • I'm not sure if I follow what you are getting at. Can you state it a different way? – Robert Moskal Oct 31 '22 at 01:25
  • @RobertMoskal I did try to further classify. But the entire point just is, if using input type for absolutely every data manipulation aside for queries is a problem. I think it probably should be, but I wanted to consult it with community, as I don't want there to be a need to get used to something that is not standard. Or if it has some performance impact for that matter. – MalwareMoon Oct 31 '22 at 01:41
  • There's different schools of thought, both are fine. However, please add the query documents that the frontends would use to your question, that's where the main difference lies. – Bergi Oct 31 '22 at 02:40
  • Yeah, for now there is nothing we can do, we must specify the `input type` for every arg we need I did ask here https://stackoverflow.com/questions/70691507/graphql-use-simple-object-instead-create-specific-type-on-schema. – FatihAziz Oct 31 '22 at 04:12
  • So what I do now? I only use GraphQL when dealing with Fetching / Get Data, and normal REST API Request for mutating data (create, update, delete). There is no point to overcomplicate GraphQL's `input type` when you can use input validator instead with REST API (express for example) – FatihAziz Oct 31 '22 at 04:15
  • @FatihAziz That's a totally different question – Bergi Oct 31 '22 at 12:52
  • Now I see. what you are getting at. – Robert Moskal Oct 31 '22 at 13:57

2 Answers2

2

Is having an input that only contains one key is something problematic?

No, on the contrary, it is something desirable in GraphQL. While nesting may sometimes seem superfluous, it is key in forward compatibility and extensibility of your schema. You should not have different conventions of how to design your mutation arguments depending on the number of inputs. If you always use an input object, you can easily deprecate existing fields or add new optional fields and stay compatible with all existing clients. If you were to completely change the shape of the mutation arguments just because you have an object with a single key, it would break compatibility.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

I'm not seeing a problem that would drive you to

"only use GraphQL when dealing with Fetching / Get Data, and normal REST API Request for mutating data (create, update, delete)."

Like @Bergi said. Plus you can provide your entity with multiple mutators some which can work like a PATCH or a PUT request.

Robert Moskal
  • 21,737
  • 8
  • 62
  • 86