Create a GraphQL API using Golang – Part 1

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”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s