For the past couple of days, I have been tinkering with GraphQL and followed an awesome blog post, and created my own GraphQL API. But the blog post only contains Creating Links and Getting Links. I understand all the components and started extending the application to support the Update & Delete as well.
You should complete this and follow my blog to extend the app. Let’s start –
Get A Single Link
At first, add a query in the GraphQL Schema – graph/schema.graphqls
type Query {
links: [Link!]!
link(id: ID!): Link!
}
Then run the $ go run github.com/99designs/gqlgen generate
You will see a resolver being created in schema.resolvers.go
with the below function signature –
func (r *queryResolver) Link(ctx context.Context, id string) (*model.Link, error) {
Now go to the internal/links/links.go
and add a Get method to get the Link with respect to the id from the database.
func Get(id string) Links {
var link Links
stmt, err := database.Db.Prepare("SELECT ID, Title, Address FROM Links WHERE ID=?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
err = stmt.QueryRow(id).Scan(&link.ID, &link.Title, &link.Address)
if err != nil {
log.Fatal(err)
}
return link
}
Now it’s time for the resolver to come in picture –
func (r *queryResolver) Link(ctx context.Context, id string) (*model.Link, error) {
link := links.Get(id)
return &model.Link{
ID: link.ID,
Title: link.Title,
Address: link.Address,
}, nil
}
Update A Link
Now is the time to update an existing link. Now this time as we are writing into the database we have to use mutations.
type Mutation {
updateLink(id: ID!, input: NewLink!): Link!
}
Now let’s generate the same using $ go run github.com/99designs/gqlgen generate
And add the Update method in the links.go –
func (link Links) Update(id string) int64 {
stmt, err := database.Db.Prepare("UPDATE Links SET Title=? , Address=? WHERE ID=?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec(link.Title, link.Address, id)
if err != nil {
log.Fatal(err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
return rowsAffected
}
Here we are taking the id input and doing an update operation on to it and returning the affected rows count.
Now it’s time for the resolvers –
func (r *mutationResolver) UpdateLink(ctx context.Context, id string, input model.NewLink) (*model.Link, error) {
link := links.Links{
Title: input.Title,
Address: input.Address,
}
rowsAffected := link.Update(id)
if rowsAffected == 0 {
return nil, errors.New("zero rows affected")
}
return &model.Link{
ID: id,
Title: link.Title,
Address: link.Address,
}, nil
}
Here we are taking the GraphQL input and doing an update operation on that and returning the updated value with an in-between affected rows check for 0.
Delete A Link
Now as usual add the mutation first in the schema –
type Mutation {
deleteLink(id: ID!): String!
}
Now let’s generate the same using $ go run github.com/99designs/gqlgen generate
Now add the code in the links.go to perform the delete operation –
func Delete(id string) int64 {
stmt, err := database.Db.Prepare("DELETE FROM Links WHERE ID=?")
if err != nil {
log.Fatal(err)
}
defer stmt.Close()
res, err := stmt.Exec(id)
if err != nil {
log.Fatal(err)
}
rowsAffected, err := res.RowsAffected()
if err != nil {
log.Fatal(err)
}
return rowsAffected
}
Here we run the delete query and get the rows affected count and return it.
Now it’s time to resolve it –
func (r *mutationResolver) DeleteLink(ctx context.Context, id string) (string, error) {
rowsAffected := links.Delete(id)
if rowsAffected == 0 {
return "", errors.New("zero rows affected")
}
return fmt.Sprintf("%v rows affected", rowsAffected), nil
}
Here we call the delete with the desired id string as an input and if got deleted successfully then we return a string with “<number> rows affected”.