Posted in Building REST APIs, Golang, Misc, Tech

Build RESTful API in Golang

Welcome again! After learning some Golang, my next experiment was to build APIs. So, here’s a blog-post for someone interested in trying it out. The only prerequisite to building RESTful APIs is to know the basics of Golang along with some SQL. Link to my blog-post series on Introduction to Golang may come handy.

The code can be broadly divided into two files:

  • migrate.go: Connects to MySQL and creates the necessary tables.
  • base.go: Contains all the API handlers.

Step 1: Establishing Database Connection

We will now be working on the migrate.go file. Certain packages are to be imported before we can start over.

import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)

The package sql provide an interface for the SQL database. In other words, it equips Golang to work with database and create a connection, executing queries and perform other SQL operations. The sql package works along with a database driver. We have used Go’s mysql driver in this case: go-sql-driver/mysql.

db, err := sql.Open("mysql","root:password@(127.0.0.1:3306)/gotest")
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("Connection established successfully")
}
defer db.Close()

sql.Open() opens a database connection to MySQL. This function accepts two parameters – the database used (mysql in this case) and the connection details in the format: username: password@hostname/database_name. Here ‘gotest‘ is the database created to run this project. Appropriate Error message is shown when the connection fails. Defer is used to wait until all the surrounding functions return. Only then is the connection  to the database closed.

err = db.Ping()
if err != nil {
fmt.Println(err.Error())
}

In case the machine is not reachable at all,  sql.Open() does not throw an error. Hence we need to explicitly ping the machine in order to verify the same.

STEP 2: Creating Tables

stmt, err := db.Prepare("CREATE TABLE emp (id int NOT NULL AUTO_INCREMENT, first_name varchar(40), last_name varchar(40), PRIMARY KEY(id));")
if err != nil {
fmt.Println(err.Error())
}
_,err = stmt.Exec()
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("emp table migration successful")
}

Now let’s create the table ‘emp‘ using db.Prepare(). Just to recap, ‘db’ is the handler we obtained after connecting to the database. The SQL create statement is provided as parameter. It returns a handler which is then executed using Exec() function. It also returns an error if the function fails. Error handling is coded accordingly in the last few lines.

STEP 3: Building the APIs

We now have everything in-place to start building the APIs. Create the file base.go. We will be importing some new libraries apart from those we have already come across. “Gin” is a HTTP web framework written in golang. The package “bytes” implements functions for manipulating byte slices. “net/http” provides implementations for Client Server Communication.

import (
"fmt"
"database/sql"
"bytes"
"net/http"
"encoding/json"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
)

Next, create a database connection using sql.Open() along with implementation of  error handling.

func main() {
db, err := sql.Open("mysql","root:pwd@(127.0.0.1:3306)/gotest")
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("Connection established successfully")
}
defer db.Close()
//Checking for connection:
err = db.Ping()
if err != nil {
fmt.Println(err.Error())
}

Create a golang type called Emp which will hold each row from the database and help in processing them. The type is a carbon copy for a typical row in the database containing “id”, “first_name” and “last_name” as its variables.

type Emp struct {
id int
first_name string
last_name string
}

Step 4: The GET request

A simple GET request can be created with the help of Gin which creates a handler to place a http GET request. It takes as input the URL string which is to be matched and function to handle the data returned.

router.GET("/emp/:id", func(c *gin.Context) {
var (
emp Emp
result gin.H
)
id := c.Param("id")
row := db.QueryRow("select id,first_name,last_name from emp where id = ?;",id)
err := row.Scan(&emp.id,&emp.first_name,&emp.last_name)
if err != nil {
//if no results found send Nill
result = gin.H{
"result": nil,
"count": 0,
}} else {
result = gin.H{
"result": gin.H{
"id": emp.id,
"first_name": emp.first_name,
"last_name": emp.last_name,
},
"count": 1,
}}
c.JSON(http.StatusOK, result)
})

 

Here the handler will match /emp/1/ but will not match /emp. The function stores the id, first name and last name into the type Emp by querying the database with the id obtained from the user in the GET request. The result string is constructed and passed as a JSON which serves as the output.

Similarly,

  • A GET request can be constructed to obtain all the employee data in the database.
  • POST request can be used to insert a new record or
  • PUT can modify an existing record.
  • You can similarly delete one or more records using the DELETE request.

Code for each of the above APIs can be found on my github.

Finally, let us see the above APIs in Action.

Here’s an example of a PUT request. We are here updating the first & last name of employee #2. The port in use is 3000. Note the message shown on successful execution.

PUT

Let’s now verify if the name of employee #2 was successfully modified as claimed by the above output. Here’s the GET request:

GET

The entire code can be found on: Github/RESTful-API-with-Golang-and-MySql

Posted in Golang, Tech

Go – Concurrency

Concurrency is when two or more tasks make progress simultaneously. It could be very tedious to get it right in most of the programming languages. However, Go has a rich support to concurrency and makes the task very easy.

Goroutines:

Goroutines are functions or methods that can run concurrently with other methods. They are light-weight threads. The cost of creating a goroutine is very small compared to that of an actual thread. Hence a GO application commonly has thousands of goroutines running concurrently.

  • Goroutines are managed by GO runtimes
  • go exroutine(a,b) starts a new goroutine that runs exroutine(a,b)
  • Here, the evaluation of exroutine,a,b happens in the current goroutine. The execution happens in the new goroutine.
package main

import (
	"fmt"
	"time"
)

func say(s string) {
	for i := 0; i < 10; i++ {
		time.Sleep(100 * time.Millisecond)
		fmt.Println(s)
	}
}

func main() {
	go say("is fun")
	say("learning go")
}

Channels:

  • Channels facilitate sending and receiving values. It is achieved using the channel operator ‘<-‘
  • Sending a to channel chch <- a
  • Receive from ch and assign it to aa := <-ch (Data flows in the direction of the arrow)
  • Channels must be created before using it: ch := make(chan int)
  • Send and Receive blocks implicitly until the other side is ready and hence is synchronized.
package main

import "fmt"

func sum(s []int, c chan int){
   sum := 0
   for _,v := range s{
      sum += v
   }
   c <- sum
}

func main(){
   lst := []int{200, 100, 900, 30, 40, 70, 400, 450}
   c := make(chan int)
   go sum(lst[:len(lst)/2],c)
   go sum(lst[len(lst)/2:],c)
   x,y := <-c, <-c
   fmt.Println(x,y,x+y)
}
  • Channels can also be bufferred. The buffer length should be provided as the second argument to makech := make(chan int, 100)
  • A channel can be closed to indicate that no more values can be sent. close(ch)
  • Only the sender should close a channel (not the receiver).
  • Receivers can check if a channel has been closed using the second parameter:       a, ok := <-ch ok is False if the channel is closed.
  • range can be used to keep receiving values until the channel is closed.
for i := range ch {
   fmt.Println(i)
} 
  • Closing a channel is not mandatory. It is only required to send a message to the receiver that no more values are being sent through the channel. It can also be useful to terminate a range loop.

Select

Select lets a goroutine wait on multiple communication operations. It chooses the case that is ready. If multiple are ready, it randomly makes a choice. Default case is chosen if no other case is ready.

select {
	case c <- x:
		x, y = y, x+y
	case <-quit:
		fmt.Println("quit")
		return
	default:
         	fmt.Println("    .")
	}

Mutex:

Mutex or mutual exclusion ensures that only one goroutine can access a variable at a given time to avoid conflicts. Mutex is provided by the sync library which has two methods: Lock and Unlock.

  • A block of code can be executed in mutual exclusion by enclosing it in a call to lock.
  • Defer ensures the mutex is unlocked when required.
package main

import (
	"fmt"
	"sync"
	"time"
)

type mutexUsage struct {
	v   map[string]int
	mx sync.Mutex
}

func (m *mutexUsage) Incr(key string) {
	m.mx.Lock()
	m.v[key]++
	m.mx.Unlock()
}

func (m *mutexUsage) Value(key string) int {
	m.mx.Lock()
	defer m.mx.Unlock()
	return m.v[key]
}

func main() {
	m := mutexUsage{v: make(map[string]int)}
	for i := 0; i < 100; i++ {
		go m.Incr("somekey")
	}

	time.Sleep(time.Second)
	fmt.Println(m.Value("somekey"))
}

Previous Post: Methods and Interfaces

Posted in Golang, Tech

Go – Methods and Interfaces

Methods

GO has no Classes. However, it has Methods that can be defined on ‘types’. A Method is a function with a special ‘receiver’ argument. In the example below, ‘v‘ is the receiver of the type ‘Square‘, to the method ‘Sqroot‘.

package main

import (
   "math"
   "fmt"
)

type Square struct {
   x, y float64
}

func (v Square) Sqroot() float64 {
   return math.Sqrt(v.x*v.x + v.y*v.y)
}

func main() {
   s := Square{3,4}
   fmt.Println(s.Sqroot())
}
  • Methods can be declared on non-struct types too.
  • A Method can only be declared on a type which is present in the same package as the method.

Pointer Receivers

A method can also be declared with the receiver being a Pointer. A Pointer receiver is very commonly used, as it can modify the underlying value of the type.

There can be two reasons to choose a pointer receiver instead of a value. First is to modify the underlying value and second to avoid copying the value on each method call. If the receiver is large, pointer receiver can prove to be more efficient.

package main

import (
   "math"
   "fmt"
)

type Square struct {
   x, y float64
}

func (v Square) Sqroot() float64 {
   return math.Sqrt(v.x*v.x + v.y*v.y)
}

func (v *Square) Scale(val float64) {
   v.x = v.x * val
   v.y = v.y * val
}

func main() {
   s := Square{3,4}
   s.Scale(100)
   fmt.Println(s.Sqroot())
}

Interfaces

An Interface is a set of method signatures.

type ExInt interface {
	Ifs() float64
}
func(f float64) Ifs() float64 {
   return float64(-f)
}
  • Interfaces are implemented implicitly. No “implements” keyword required.
  • Interfaces can have ‘nil‘ underlying value.
  • An empty interface can hold value of any type interface{}

Errors:

Go uses error values to express error states. An Error type is a built in Interface which looks like this:

type error interface {
    Error() string
}

Functions return an Error value. The calling code should handle errors by testing if the error equals ‘nil

Reader:

  • The reader interface is a part of the ‘io’ package.
  • It helps identify when end of stream of data is reached.
  • The Read method populates the number of bytes of data as specified.
  • The two return values are 1)Number of bytes populated and 2) An error value.
package main

import (
    "fmt"
    "io"
    "strings"
)

func main() {
    r := strings.NewReader("You are using Readers!")

    b := make([]byte, 8)
    for {
        n, err := r.Read(b)
	fmt.Printf("n = %v err = %v b = %v\n", n, err, b)
	fmt.Printf("b[:n] = %q\n", b[:n])
	if err == io.EOF {
	    break
 	    }
        }
}

Output:

n = 8 err =  b = [89 111 117 32 97 114 101 32]
b[:n] = "You are "
n = 8 err =  b = [117 115 105 110 103 32 82 101]
b[:n] = "using Re"
n = 6 err =  b = [97 100 101 114 115 33 82 101]
b[:n] = "aders!"
n = 0 err = EOF b = [97 100 101 114 115 33 82 101]
b[:n] = ""

Previous post: GO – Types (part 2)

Next Post: Go – Concurrency

Posted in Golang, Tech

GO – Types (part 2)

Range

Range iterates over a slice. Range returns two values while iterating over a slice. First is the index of the element and second a copy of the element at that index.

package main

import "fmt"

var t = []int{1, 3, 6, 9, 12, 15, 18, 21}

func main() {
	
	for i,v := range t {
	   fmt.Printf("%d => %d\n", i, v)
	}
}
  • Index or Value can be skipped by assigning it to _.
  • If only indexes are required, the “value” can be dropped entirely.
func main() {
	
	fmt.Printf("Values:\n")
	for _,v := range t {
	   fmt.Printf("%d, ", v)
	}
	
    fmt.Printf("\nIndex:\n")
    for i:= range t {
	   fmt.Printf("%d, ", i)
	}

}

Map

Map is nothing but a key-value pair. ‘Make’ function can be used to initialize a map. Zero value of a map is ‘Nil‘. Keys cannot be added to a ‘nil’ map.

package main

import "fmt"

var Emp map[string]int

func main() {
   Emp = make(map[string]int)
   Emp["John"] = 34
   Emp["Jeff"] = 20
   fmt.Println(Emp)
   fmt.Println(Emp["John"])
}

Map Literals:

package main

import "fmt"

type address struct {
  street, city string
  }

var Emp = map[string]address{
	"John": address{"abc street","London"},
	"Jeff": {"def street","Boston"},
}

The top-level type name (address in this case) can be omitted as well.

Mutating Maps

m = make(map[string]int)

  • Insert/Update” m["Mary"] = 58
  • Retrieve an element: fmt.Println(m["Mary"])
  • delete: delete(m,"Mary")
  • Check if a key is present: val, present := m["Jerry"] If the key is present, val will return the value and present will be True. If the key is not present, val will be 0 and present will be False.

Implementing Word Count

A small exercise to create a Map which will contain the count of each letter in a given word:

package main

import (
	"strings"
	"fmt"
)

func WordCount(s string) map[string]int {
    split := strings.Fields(s)
	wc := make(map[string]int)
	for i:=0;i<len(split);i++ {
	   wc[split[i]] = len(split[i])
	}
	return wc
}

func main() {
	fmt.Println(WordCount("I am learning Go!"))
}

Function values

In GO, Functions can also be passed around, similar to values.

package main

import (
  "fmt"
  "math"
)

func compute(fn func(float64, float64) float64) float64 {
   return fn(4,3)
}

func main() {
   sqrt := func(x,y float64) float64 {
       return math.Sqrt(x*x + y*y)
    }
   fmt.Println(compute(math.Pow))
   fmt.Println(compute(sqrt))
}

Function Closures

Closure is a function that references values from outside its body.

package main

import (
 "fmt"
)

func closure() func(int) int {
 sum := 0
 return func(x int) int {
 sum +=x
 return sum
 }
}
func main() {
 sum1,sum2 := closure(), closure()
 for i:=0;i<10;i++ {
 fmt.Println(sum1(i),sum2(-1*i))
 }
}

Previous post: GO – Types (part 1)

Next Post: Go – Methods and Interfaces

Posted in Golang, Tech

GO – Types (part 1)

Pointers

264px-Pointers.svg

 

  • GO has pointers as in C. A pointer holds the memory address of a value.
  • & operator generates a pointer to its operand
  • ‘*’ operator refers to the underlying value of the pointer

 

package main

import "fmt"

func main() {
  i := 24
  p := &i
  fmt.Println(p)
  *p = *p/2      // This is called "dereferencing" or "indirecting".
  fmt.Println(i)
}

Output:

0xc420082010
12

Structs

Struct is a collection of fields. The fields can be accessed using a dot(.)

package main

import "fmt"

type Emp struct {
   Name string
   Age int
   ID string
}

func main() {
  e1 := Emp{"John",23,"1234"}
  fmt.Println(e1)
  e1.Age = 30
  fmt.Println(e1)
}

Pointers to Structs

Stucts can be accessed through a struct pointer. The struct field (Name) of a struct pointer (sp) can be accessed as sp.Name

package main

import "fmt"

type Emp struct {
   Name string
   Age int
   ID string
}

func main() {
  e1 := Emp{"John",23,"1234"}
  sp := &e1
  fmt.Println(sp.Name)
  sp.Name = "James"
  fmt.Println(sp.Name)
}

Struct Literals

Struct Literal is a newly allocated struct value. It is not required to allocate values to all the fields. Just a few fields can be used. The order of assignment also doesn’t matter. The unassigned values are implicitly assigned the Zero value of its type.

package main

import "fmt"

type strLit struct {
   X int
   Y string
   Z bool
}

var (   //Struct Literals:
  s1 = strLit{}   
  s2 = strLit{X:1,Y:"golang"}
)

func main() {
  fmt.Println(s1)
  fmt.Println(s2)
}

Arrays:

Array is of Fixed size in GO. It is declared as abc [n]T where abc is an Array of n values with the type T.

func main() {
   var a [2]string
   a[0] = "Dobby is a"
   a[1] = "free elf"
   fmt.Println(a)
   fmt.Println(a[0],a[1])
   
   vowels := [6]string{"a","e","i","o","u"}
   fmt.Println(vowels)
}

Slice literal

A slice is a dynamicalled sized Array.

  • A slice does not store any data. Slices are like references to an Array. Modifying an element in the slice results in modifying the underlying array.
  • A slice literal creates an array and builds a slice that references it.
func main() {
   vowels := [6]string{"a","e","i","o","u"}
   var sub []string = vowels[:3]
   fmt.Println(sub)
   
   t := []int{1,2,3,4}
	 fmt.Println(t)
}
  • When slicing, 0 is taken as the default low bound and the length of the slice as the default high bound (similar to Python Arrays). Ex. For the array: t [10]int these expressions are equivalent: t[:], t[:10], t[0:10], t[0:]
  • Slice Length: Number of elements it contains. Can be obtained using the function len(t)
  • Slice capacity: Maximum number of elements the slice can contain. Can be obtained using the function cap(t)
  • Nil Slice: The slice’s len() and cap() is zero. The ‘zero’ value of a slice is ‘Nil’
func main() {
  var s[]int 
  fmt.Println(s, len(s), cap(s))
    if s == nil {
      fmt.Println("nil!")
    }
}

Make – for creating slices

Dynamically sized arrays can be created using the ‘make‘ function. The length and capacity of the slice can be passed as arguments to the ‘make’ function.

package main

import "fmt"

func main() {
  a := make([]int,4,6)
  printSlice("a",a)
	
  b := make([]int,2,6)
  printSlice("b",b)
	
  c:= b[:4]
  printSlice("c",c)
	
  d:= b[1:]
  printSlice("d",d)	
}

func printSlice(s string, x []int) {
  fmt.Printf("%s len=%d cap=%d %v\n",
		s, len(x), cap(x), x)
}

Slices of slices:

Slices can contain other slices too.

package main

import "fmt"

func main() {
	sliceEx := [][]string{
	[]string{"Superman","Batman","Wonder Woman"},
	[]string{"Hulk","Ironman","Spiderman","Captain America"},
	[]string{""},
	}
	fmt.Println(sliceEx)
}

Appending to a slice:

New elements can be appended to a slice using the ‘append‘ function. More than one element can be appended in a single function call. The first parameter is the slice followed by the elements.

func main() {
 var t []int
 
 t = append(t,0)
 t = append(t,1,2,3,4)
}

 

Previous post: Go – Flow Control

Next Post: GO – Types (part 2)

 

Posted in Golang, Tech

GO – Flow Control

The All-purpose For loop

GO has a single looping construct which is the For loop. For loop has three components similar to that in C/Javascript:

  • Init statement – Executed before the loop starts
  • Conditional statement – Checked before every iteration
  • Post statement – executed after every iteration.

However, unlike C/Java/Javascript there is no parentheses surrounding the components.

for i:=0; i< 10; i++ {
   fmt.Println(i)
}

The For loop can also be written without the init and the post statements:

for ;i<10; {
   fmt.Println(i)
}

For can also be a while loop:

for i<10 {
   fmt.Println(i)
}

Conditional Statement:

The IF statement does not have to be surrounded by a parentheses. However braces { } are required.

if x<y {
  fmt.Println(x+2)
}

If statement can also have an initial short statement that is executed before the condition. Variable declared inside an if short statement is also available in the else clause

if x := math.Pow(x, n); x < y {
  x = x+2)
} else { 
  x = x - 2
}

Switch

  • Switch in GO does not require a ‘break’ statement in the end of each case. It implicitly runs only on the first selected case and not on all cases that follow.
  • The cases in GO need not be confined to integers alone.
  • Switch cases evaluate from top to bottom and stops when it matches a statement.
  • Switch can also be written without a condition.This evaluates to switch true
func main() {
	fmt.Println("When's Saturday?")
	today := time.Now().Weekday()
	fmt.Println(today + 1)
	switch time.Saturday {
	case today + 0:
		fmt.Println("Today.")
	case today + 1:
		fmt.Println("Tomorrow.")
	case today + 2:
		fmt.Println("In two days.")
	default:
		fmt.Println("Too far away.")
}

Defer

Defer statement defers the execution of a function until all the surrounding functions return. The defer statement is evaluated immediately but the function call is not executed until the surrounding functions return.

func main() {
 defer fmt.Println("lang")
 defer fmt.Println("GO")
 fmt.Println("Welcome")
 fmt.Println("to")
}

Deferred function calls are evaluated and pushed into a stack. The deferred function calls are executed in last-in-first-out order.

Next Post: Go Types (part 1)

Previous Post: Go – Getting Started

GO – Getting Started

GO or Golang is known for its Efficiency, Concurrency and Scalability to large systems. Some of its distinctive features are:

  • Clean, readable and modular code with minimum boilerplate.
  • Is Statically typed
  • Faster compilation time
  • Remote Package Management
  • goroutines (light-weight processes), channels (connects goroutins) and the Select statement
  • Supports Networking and Multiprocessing.

GO was created at google in 2009 by Robert Griesemer, Rob Pike and Ken Thompson.

Gopher-ru

Syntax:

Let us start by understanding the basic structure and syntax.

package main

import (
  "fmt"
  "time"
)

func main() {
  fmt.Println("Welcome to Golang! The time is: ", time.Now())
}
  • “main” is the package where the execution starts
  • Import: The above code uses the packages “fmt” and “time”. Multiple packages can be grouped into a single import statement (by enclosing within paranthesis).
  • Exported names from a package should always start with a capital letter (Ex. time.Now() – ‘Now’  is the exported name from the package ‘time’)

Compile and run on local:

  • Create a file welcome.go in the project directory. Ensure the PATH variable includes the go installation directory (“/usr/local/go/bin”)
  • go build (creates an executable)
  • ./golang – to execute

Functions:

Function can take zero or more arguments.

func add(x int, y int) int {
	return x + y
}

Notice that the type is written after the variable name. The type of the returned result is specified after the paranthesis.

  • When two or more function parameters share the same type(x int, y int) , it can be written as (x,y int)
  • When the function returns more than one result, it is written as:
func sum(x,y int) (string,int) {
   return "sum: ", x+y
}
  • Naked return statement: Returns the named return values. Should be used in short functions only.
func sampleret(x,y int) (a,b int) {
   a = x + 10/3
   b = y + 10/3
   return
}

Variables:

‘var’ statement declares a list of variables. They can be at the Package level or Function level.

Different ways of declaring variables:

var i int
var x,y int = 10, 11
a := 3 

a := 3 is a short assignment statement that can be used in the place of var inside the function. It is not available outside the function.

Basic types:

  • List of basic types:
bool
string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte 

rune (represents a Unicode code point)

float32 float64

complex64 complex128
  • Representing Zero value for various types:
0 -> for int
"" (empty string) -> for strings
false -> for boolean
  • Type Conversion:
var i int = 100
var j float64 = float64(i)
  • Type Inference:

When a variable is declared without explicitly specifying its type, it either takes the same type as the value on the right hand side:

var i int = 20
j := i (j is int)

or assigns a type depending on the value: i := 1.1234 (float64)

  • Constants:

const Pi = 3.14 – Const cannot be declared using ‘:=’

In this post, we discussed some of Go’s distinctive features and had a quick look at Structure, basic syntax, types and variables.

Next post: GO – Flow Control