Developing a Simple Web Application using Go
This article is intended to develop a simple web-server. We will first start with a basic web server and learn to write tests. Then we will move on to writing a web-server which interacts with a database and refine the code by giving it a structure and making it testable.
Pre-Requisites:
1. If you are new to Go, it is recommended that you go through the go tour
2. Go is installed in your system
3. $GOPATH is set
4. IDE (I prefer GoLand)
5. Basic knowledge of REST
Test Driven Development
Personally, I follow test driven development because it forces me to follow a structure. One thinks of the problem statement first, formulates all the use cases and then develops the application. If our implementation is missing some of the use cases, when the tests run it will fail pointing out that we have to change our code accordingly. On the other hand, developing the code first and then writing tests will not allow one to think of all the use cases. The tests will be based solely on the implementation and certain edge cases can be missed out. For example, if I were to implement a calculator function, it is likely that I will miss out on the divide by zero edge case if I take a development first approach.
Writing a simple web application
Create a new folder under your working directory called web-server. Create a file inside this. Name it main.go
Since we will follow test driven development, just fill in the basic structure of main.go. The goal is to create a server that prints dog when a request is made to /animal.
In the test file, write a test function that makes a request to the handler and expects Dog as output.
Command to run tests
go test ./...
The test will fail now since the handler is not defined.
main.go
The package net/http is used to build a web-server.
The HandleFunc registers the function handler. ListenAndServe listens to the network on the address specified and serves the request.
When a request is made to localhost:9000/animal, the server checks the handler registered for this route and calls the function. The handler simply writes Dog to the response writer.
Steps to run the application:
- start the server using the command go run main.go
- create a request: go to your browser(you can use any REST client as well) and type localhost:9000/animal. This is the output you will see:
Using Datastore to store and retrieve data
Going one step ahead, let’s build a web application that uses a datastore. The web-server now will read from a datastore and write into it.The example below uses MySQL as a datastore.
The package database/sql is used in order to connect and interact with SQL.
The handler is more intelligent now. The output is based on the request method. When the request method is GET it simply retrieves the information from the database and displays it as a JSON. You can enhance this to accept query parameters and list based on the filters that is applied. When the request method is POST, the body is expected to be in JSON. This body is read into the struct Animal and inserted into the database.
Introducing a struct, mysqlConfig and a variable db.
var db *sql.DB
type mysqlConfig struct{
host string
user string
password string
port string
db string
}
Writing tests:
Refer to the following .sql file. We are creating a database called animal and a table called animals.
DROP DATABASE IF EXISTS animal;
CREATE DATABASE animal;
USE animal;CREATE TABLE animals(
name varchar(50),
age int);INSERT INTO animals VALUES('Hippo',10);
Testcases:
1. When method is POST, insert into datastore.
2. When method is GET, retrieve the rows in datastore
3. When method is DELETE, method not allowed. status code 405.
main_test.go
main.go
A connection is made to database by taking the configs from the environment variables. It is set to the variable db.
Note: The variable db here is global. Db connection lasts for the entire life cycle of server’s and does not change.
If you like this post, do checkout my next post on layered architecture