Introduction
In GraphQL, input types are used to define the structure of the data that can be passed as arguments to queries and mutations. They are similar to object types but are specifically designed for input purposes. Input types help in validating and structuring the data that the client sends to the server.
Key Concepts
- Definition of Input Types
- Input types are defined using the
input
keyword. - They are used to encapsulate multiple arguments into a single argument.
- Input types cannot have fields that are other object types, only scalar types or other input types.
- Syntax
The syntax for defining an input type is similar to defining an object type but uses the input
keyword.
- Using Input Types in Mutations
Input types are commonly used in mutations to pass complex data structures.
- Example Mutation
Here is an example of how you might use an input type in a mutation:
mutation { createUser(input: { name: "John Doe", age: 30, email: "[email protected]" }) { id name email } }
Practical Example
Step-by-Step Example
-
Define the Input Type:
input UserInput { name: String! age: Int email: String! }
-
Define the Mutation:
type Mutation { createUser(input: UserInput!): User }
-
Define the User Type:
type User { id: ID! name: String! age: Int email: String! }
-
Resolver for the Mutation:
const resolvers = { Mutation: { createUser: (parent, args, context, info) => { const { input } = args; // Simulate user creation const newUser = { id: Date.now().toString(), ...input }; // Here you would typically save the user to a database return newUser; } } };
Complete Example
Here is a complete example including schema and resolver:
Schema Definition:
type User { id: ID! name: String! age: Int email: String! } input UserInput { name: String! age: Int email: String! } type Mutation { createUser(input: UserInput!): User } type Query { users: [User] }
Resolver Implementation:
const { ApolloServer, gql } = require('apollo-server'); const typeDefs = gql` type User { id: ID! name: String! age: Int email: String! } input UserInput { name: String! age: Int email: String! } type Mutation { createUser(input: UserInput!): User } type Query { users: [User] } `; let users = []; const resolvers = { Query: { users: () => users, }, Mutation: { createUser: (parent, { input }) => { const newUser = { id: Date.now().toString(), ...input, }; users.push(newUser); return newUser; }, }, }; const server = new ApolloServer({ typeDefs, resolvers }); server.listen().then(({ url }) => { console.log(`🚀 Server ready at ${url}`); });
Exercises
Exercise 1: Define and Use an Input Type
- Define an input type
ProductInput
with fieldsname
,price
, anddescription
. - Create a mutation
addProduct
that takesProductInput
as an argument and returns aProduct
type. - Implement the resolver for
addProduct
.
Solution:
input ProductInput { name: String! price: Float! description: String } type Product { id: ID! name: String! price: Float! description: String } type Mutation { addProduct(input: ProductInput!): Product }
Resolver:
const resolvers = { Mutation: { addProduct: (parent, { input }) => { const newProduct = { id: Date.now().toString(), ...input, }; // Here you would typically save the product to a database return newProduct; }, }, };
Exercise 2: Extend the User Input Type
- Add a new field
address
of typeString
to theUserInput
type. - Update the
createUser
mutation to handle the newaddress
field.
Solution:
input UserInput { name: String! age: Int email: String! address: String } type Mutation { createUser(input: UserInput!): User }
Resolver:
const resolvers = { Mutation: { createUser: (parent, { input }) => { const newUser = { id: Date.now().toString(), ...input, }; // Here you would typically save the user to a database return newUser; }, }, };
Conclusion
Input types in GraphQL are essential for structuring and validating the data sent from the client to the server. They simplify the process of passing complex data structures and ensure that the data adheres to the defined schema. By mastering input types, you can create more robust and maintainable GraphQL APIs.