XML Applications Golang

Hello everyone, in my last blog, Golang SQL JSON

I used JSON for transferring data among application and service, now using same code with a small tweak we can use XML in place of JSON.

The code now looks like this:

Main.go

package main

import (
       "net/http"
       "fmt"
       "io"
       _ "github.com/go-sql-driver/mysql"
       "database/sql"

       "strconv"
       "encoding/xml"
)

var appdatabase *sql.DB



type Userstruct struct {
       Username string
       Age string
       Salary string
}


func insertInDatabase(data Userstruct) error {
       age,_ := strconv.Atoi(data.Age)
       salary,_ := strconv.Atoi(data.Salary)
       _, err := appdatabase.Exec("INSERT INTO emptable(name, age, salary) VALUES(?, ?, ?)", data.Username , age, salary)
       return err

}

func getFromdatabase(uname string, w http.ResponseWriter) error{

       out := Userstruct{}

       err := appdatabase.QueryRow("SELECT * FROM emptable WHERE name=?", uname).Scan(&out.Username, &out.Age, &out.Salary)

       if err != nil {
              return err
       }

       enc := xml.NewEncoder(w)

       err = enc.Encode(&out)

       return err
}

func userAddHandler(w http.ResponseWriter, r *http.Request) {


       //make byte array
       out := make([]byte,1024)

       //
       bodyLen, err := r.Body.Read(out)

       if err != io.EOF {
              fmt.Println(err.Error())
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       var k Userstruct

       fmt.Println(string(out))

       err = xml.Unmarshal(out[:bodyLen],&k)


       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       err = insertInDatabase(k)

       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       w.Write([]byte(`{"error":"success"}`))

}

func userGetHandler(w http.ResponseWriter, r *http.Request) {

       type Userstruct struct {
              Username string
       }

       //make byte array
       out := make([]byte,1024)

       //
       bodyLen, err := r.Body.Read(out)

       if err != io.EOF {
              fmt.Println(err.Error())
              w.Write([]byte(`{"error":"bodyRead"}`))
              return
       }

       var k Userstruct

       //err = json.Unmarshal(out[:bodyLen],&k)

       err = xml.Unmarshal(out[:bodyLen],&k)

       if err != nil {
              w.Write([]byte(err.Error()))
              return
       }

       err = getFromdatabase(k.Username, w)

       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }


}



func StartService(port string) {

       http.HandleFunc("/adduser", userAddHandler)
       http.HandleFunc("/getuser", userGetHandler)
       http.ListenAndServe(":" + port, nil)
}

func main() {

       var err error
       appdatabase, err = sql.Open("mysql", "root:asdf1234@/employee")

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

       StartService("8090")
}

In place of Golang json encoder, I am using xml encoder and rest is same in complete code.

For testing I am again using Advance REST client.

Image of my test can be seen below:

This is for “adduser” functionality.

No we are sending XML raw payload.

capture

This is for “getuser” functionality.

No we are sending XML raw payload and getting XML response.

capture

Have a look, it’s so easy in Golang to change the APIs, whether it’s XML or JSON. You can be a rock star in just few lines of code.

So, this one ends here.

See You Soon.

Happy Coding.

Love,

Rajni

 

 

Using MySQL and JSON with Golang, Small Tutorial

Introduction

“Hello everyone”. REST API is the common web service mechanism that we can find on any system. Using a web service, applications can communicate with each other. Like function calling mechanism. 


APIs can handle data and save it in Database. I will use MySQL. So, I will cover following in this tutorial.

  • Basic HTTP server handling JSON requests.
  • Using JSON inside Golang.
  • Saving and retrieving Data from MySQL.

Setup and Dependencies:

  • Go must be installed on your systems.
  • MYSQL server must be installed.
  • Advanced REST Client, chrome extension.

Note: I will not use any framework. Because frameworks limits the learning. So, be ready for some raw coding.


Getting MySQL connector for Golang:


Before configuring your connector.

  1. Your GOPATH  must be configured.
  2. Now run the following command :  go get github.com/go-sql-driver/mysql

This will have your MySQL connector configured.


This image shows, that go-sql-driver.mysql is installed in my GOPATH.

Getting Your Hands Dirty:

JSON request and response

Create a sample application in golang:

package main


import "net/http"import "strings"import "fmt"


var routes map[string]RouteInterface

func routeHandler(w http.ResponseWriter, r *http.Request) {
//just printing the stuff
       fmt.Println(r)
       b := make([]byte, 1024)
       r.Body.Read(b)
       fmt.Println(string(b))
       fmt.Println(r.Method)
       fmt.Println(string(strings.Join(r.Header["Content-Type"],"")))
       w.Write([]byte("Hello Friends, Wecome to My Blog"))

}

func StartService(port string) {

       http.HandleFunc("/", routeHandler)
       http.ListenAndServe(":" + port, nil)
}

func main() {
        StartService("8090")
}

Run the code using ,

go run main.go

capture

Open Advance Rest Client extension in chrome.

A request was made to http://localhost:8090 and Content-Type was set to JSON.

The Golang application sent, Hello Friends, Wecome to My Blog as responseto the request.

The main.go will print:

&{POST / HTTP/1.1 1 1 map[Content-Type:[application/json] Content-Length:[16]] 0xc0420604c0 16 [] false localhost:8090 map[] map[] map[] [::1]:60563 / 0xc042060500}
json : {“a”:”b”}
POST
application/json

The above program was just a basic of JSON communication. Now let’s begin some cool stuff and create a small application which uses:

  • A service created in Golang
  • MySQL database to save and retrieve data.
  • JSON

###############################################################

Let’s Begin our small application:

Let’s do a simple Simple Design First, following will be our application flow:

Step 1:

Client will send a JSON request,  http://localhost:8090/adduser

{“Username”:”Rajni” , “Age”:”31″, “Salary”:”500000000000″}

Step 2:

Server will receive and validate request, and will add it to database.

Step 3:

Client will send request, http://localhost:8090/getuser

{“Username”:”Rajni”}

Step 4:

Server will return: {“Username”:”Rajni” , “Age”:”31″, “Salary”:”500000000000″}

###############################################################

Create a database and table in MySQL

mysql> create database employee;
Query OK, 1 row affected (0.01 sec)

mysql> use employee
Database changed

mysql> CREATE TABLE `employee`.`new_table` (`name` VARCHAR(45) NOT NULL,`age` INT NOT NULL,`salary` INT NOT NULL,PRIMARY KEY (`name`));

###############################################################

Let’s Write Back-End

Main.go

package main

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

// _ in package means this package will not cause error if unused

//database instance
var appdatabase *sql.DB


// user struct
type Userstruct struct {
       Username string
       Age string
       Salary string
}


func insertInDatabase(data Userstruct) error {
       //convert age to int
       age,_ := strconv.Atoi(data.Age)

       //convert salary to int
       salary,_ := strconv.Atoi(data.Salary)

      //execute statement
       _, err := appdatabase.Exec("INSERT INTO emptable(name, age, salary) 
                    VALUES(?, ?, ?)", data.Username , age, salary)
       return err

}

func getFromdatabase(uname string, w http.ResponseWriter) error{

       out := Userstruct{}

       err := appdatabase.QueryRow("SELECT * FROM emptable WHERE name=?", uname).
                            Scan(&out.Username, &out.Age, &out.Salary)

       if err != nil {
              return err
       }
       
       //create json encoder and assign http response , 
          //which implements the IO interface 
       enc := json.NewEncoder(w)

       err = enc.Encode(&out)

       return err
}

func userAddHandler(w http.ResponseWriter, r *http.Request) {


       //make byte array
       out := make([]byte,1024)

       //
       bodyLen, err := r.Body.Read(out)

       if err != io.EOF {
              fmt.Println(err.Error())
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       var k Userstruct

       err = json.Unmarshal(out[:bodyLen],&k)


       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       err = insertInDatabase(k)

       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }

       w.Write([]byte(`{"error":"success"}`))

}

func userGetHandler(w http.ResponseWriter, r *http.Request) {

       type Userstructlocal struct {
              Username string
       }

       //make byte array
       out := make([]byte,1024)

       //
       bodyLen, err := r.Body.Read(out)

       if err != io.EOF {
              fmt.Println(err.Error())
              w.Write([]byte(`{"error":"bodyRead"}`))
              return
       }

       var k Userstructlocal

       err = json.Unmarshal(out[:bodyLen],&k)


       if err != nil {
              w.Write([]byte(err.Error()))
              return
       }

       err = getFromdatabase(k.Username, w)

       if err != nil {
              w.Write([]byte("{error:" + err.Error() + "}"))
              return
       }


}



func StartService(port string) {

       http.HandleFunc("/adduser", userAddHandler)
       http.HandleFunc("/getuser", userGetHandler)
       http.ListenAndServe(":" + port, nil)
}

func main() {
       var err error
       appdatabase, err = sql.Open("mysql", "root:asdf1234@/employee")
       if err != nil {
              panic(err.Error())
       }
       err = appdatabase.Ping()
       if err != nil {
              fmt.Println(err.Error())
       }

       StartService("8090")
}

The above code is a basic implementation of JSON service which add data to database. To test this I will use ARC chrome extension.

Pasting some images below.

This shows a request is sent to:

http://localhost:8090/adduser

and

{“error”:”success”} is returned.

capture

To check whether user is added, either do a select SQL query or run the following link:

http://localhost:8090/getuser as shown in image below.

capture

Here, we got this. We can see the user in get request.

Summary

JSON can be used to transfer data on the web in a really well structured format. MySQL is a good free database to host our application data.

And  Golang has made it so east to work upon in form of micro services, that with it we can easy create micro services and deploy on tools like Docker.

So, my love for Golang has just begun and hope you will also enjoy the blog.

Good Night, God Bless. 🙂

Regards,

Rajni Kant Sharma