You can integrate GraphQL with GORM by using a GraphQL server library like gqlgen to define your schema and resolvers, then wiring those resolvers to call your GORM repository methods for database operations. This setup keeps your data access logic clean while exposing a flexible API layer.
First, define your GraphQL schema (schema.graphql) to match your GORM models. For example, if you have a User struct in GORM, your schema might look like this:
type User {
id: ID!
name: String!
email: String!
}
type Query {
users: [User!]!
user(id: ID!): User
}
Next, generate the Go code using gqlgen and implement the resolvers. In your resolver, inject the GORM database instance and use it to fetch data. Here is a practical implementation of the users resolver:
// resolver.go
func (r *queryResolver) Users(ctx context.Context) ([]*User, error) {
var users []User
// Use the GORM DB instance injected into your resolver
if err := r.db.Find(&users).Error; err != nil {
return nil, err
}
return users, nil
}
To set this up, ensure your GORM model matches the GraphQL type. If your GORM model is:
type User struct {
ID uint `gorm:"primaryKey"`
Name string `gorm:"not null"`
Email string `gorm:"uniqueIndex;not null"`
}
You can map the fields directly in gqlgen.yml or rely on the default naming conventions. When handling mutations, simply pass the input struct to your GORM Create or Update methods. For instance, a CreateUser mutation resolver would look like this:
func (r *mutationResolver) CreateUser(ctx context.Context, input CreateUserInput) (*User, error) {
user := User{
Name: input.Name,
Email: input.Email,
}
if err := r.db.Create(&user).Error; err != nil {
return nil, err
}
return &user, nil
}
Run the server with gqlgen server or your custom main function that initializes the GORM DB, sets up the gqlgen handler, and starts the HTTP server. This approach separates your API contract (GraphQL) from your data persistence (GORM), making both layers easier to test and maintain.