What is this article about?
Import
Debug
Variables and Declarations
Function Declarations
Data Type
Structure, enum, class
Maps, Arrays and Slices
Interfaces
Concurrency
Pointer
How to create a routes ( Storing routes, static routes, dynamic routes, Forwarding routes… )
Working with web handlers, requests, and ResponseWriter instances: parse request data, response JSON
Making a middleware in Golang
Handling errors and the Error interface in Golang
Concurrency in Golang
Microservice and Monolithic with Golang, java, nodejs
Using structures and closures for stateful handlers
Validating input for Go structures and user inputs
Rendering and content negotiation
Implementing and using middleware
Building a reverse proxy application
About GRPC clients

Variables and Declarations

It is quite simple to define a variables, look the example code below
Example Code


package main

import "fmt"

func main() {

// `var` declares 1 or more variables.
var a = "initial"
fmt.Println(a)

// You can declare multiple variables at once.
var b, c int = 1, 2
fmt.Println(b, c)

// Go will infer the type of initialized variables.
var d = true
fmt.Println(d)

// Variables declared without a corresponding
// initialization are _zero-valued_. For example, the
// zero value for an `int` is `0`.
var e int
fmt.Println(e)

// The `:=` syntax is shorthand for declaring and
// initializing a variable, e.g. for
// `var f string = "apple"` in this case.
f := "apple"
fmt.Println(f)
}

Declaring and Calling Functions in Golang

In Golang, we declare a function using the func keyword. A function has a name, a list of comma-separated input parameters along with their types, the result type(s), and a body.
Following is an example of a simple function called avg that takes two input parameters of type float64 and returns the average of the inputs. The result is also of type float64:
func avg(x float64, y float64) float64 {
return (x + y) / 2
}

Now, calling a function is very simple. You just need to pass the required number of parameters to the function like this:
avg(6.56, 13.44)

Here is an example to call func sum and average:


package main
import "fmt"

func avg(x float64, y float64) float64 {
return (x + y) / 2
}
func sum(x float64, y float64) float64 {
return x + y
}

func main() {
x := 5.75
y := 6.25

result := avg(x, y)

fmt.Printf("Average of %.2f and %.2f = %.2f\n", x, y, result)

sum := sum(x,y)
fmt.Printf("Sum of %.2f and %.2f = %.2f\n", x, y, sum )
}

//go run func.go

What is an interface in Golang ?

Interfaces
An interface type is defined as a set of method signatures.
A value of interface type can hold any value that implements those methods.
It is a kind of protocol
Example

type Abser interface {
	Abs() float64
}

How to create a web server

Here, we use the “net/http” package
The default port is 8080
Look the example code below



package main

import (
"fmt"
"log"
"net/http"
)
func main() {
// http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request){
// fmt.Fprintf(w, "Hello!")
// })
http.HandleFunc("/hello", helloHandler) // Update this line of code

fmt.Printf("Starting server at port 8080\n")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatal(err)
}
}

func helloHandler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/hello" {
http.Error(w, "404 not found.", http.StatusNotFound)
return
}

if r.Method != "GET" {
http.Error(w, "Method is not supported.", http.StatusNotFound)
return
}

fmt.Fprintf(w, "Hello! My name is Huy ")
}



Run the code and do a request on localhost:8080/hello, you will see this

Screen Shot 2021-03-11 at 10.26.26 AM

How to create a routes

How to create a Storing routes

How to create a static routes

How to create a dynamic routes

How to create a Forwarding routes

How to get data from API request

// File: main.go
package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
)

type Person struct {
    Name string
    Age  int
}

func personCreate(w http.ResponseWriter, r *http.Request) {
    // Declare a new Person struct.
    var p Person

    // Try to decode the request body into the struct. If there is an error,
    // respond to the client with the error message and a 400 status code.
    err := json.NewDecoder(r.Body).Decode(&p)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
        return
    }

    // Do something with the Person struct...
    fmt.Fprintf(w, "Person: %+v", p)
}

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/person/create", personCreate)

    err := http.ListenAndServe(":4000", mux)
    log.Fatal(err)
}

Run the go file above
go run main.go
Then, try to test it with a curl

/* test curl
curl --location --request POST 'localhost:4000/person/create' \
--header 'X-Access-Token: xxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"Name":"Tôi là ABC", "Age": 40}'
*/

The rusult is like below
Screen Shot 2021-03-14 at 6.02.16 PM

How to response a JSON

Use “encoding/json”
and write to http response
For example

package main

import (
  "encoding/json"
  "net/http"
  "log"
)

type Profile struct {
  Name    string
  Hobbies []string
}

func main() {
  http.HandleFunc("/", foo)
  log.Println("Starting server on port 4000...")
  http.ListenAndServe(":4000", nil)

}

func foo(w http.ResponseWriter, r *http.Request) {
  profile := Profile{"Alex", []string{"snowboarding", "programming"}}

  js, err := json.Marshal(profile)
  if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
  }

  w.Header().Set("Content-Type", "application/json")
  w.Write(js)
}
/* test curl
curl --location --request POST 'localhost:4000' \
--header 'X-Access-Token: xxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"Name":"Tôi là ABC", "Age": 40}'
*/

Concurrency in Golang

Handling errors and the Error interface in Golang

Working with web handlers, requests, and ResponseWriter instances

Making a middleware in Golang

A middleware handler is simply an http.Handler that wraps another http.Handler to do some pre- and/or post-processing of the request. It’s called “middleware” because it sits in the middle between the Go web server and the actual handler.
middleware_golang

//File: main.go
package main

import (
  "log"
  "net/http"
)

func middlewareOne(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    log.Println("Executing middlewareOne")
    next.ServeHTTP(w, r)
    log.Println("Executing middlewareOne again")
  })
}

func middlewareTwo(next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    log.Println("Executing middlewareTwo")
    if r.URL.Path == "/foo" {
      return
    }

    next.ServeHTTP(w, r)
    log.Println("Executing middlewareTwo again")
  })
}

func final(w http.ResponseWriter, r *http.Request) {
  log.Println("Executing finalHandler")
  w.Write([]byte("OK"))
}

func main() {
  mux := http.NewServeMux()

  finalHandler := http.HandlerFunc(final)
  mux.Handle("/", middlewareOne(middlewareTwo(finalHandler)))

  log.Println("Listening on :3000...")
  err := http.ListenAndServe(":3000", mux)
  log.Fatal(err)
}  

Microservice and Monolithic with Golang, java, nodejs

monolithic-and-microservices-architecture

Here we can have a look of the big picture
Architecture-Of-Microservices-Microservice-Architecture-Edureka

Microservice-Architecture-Of-UBER-Microservice-Architecture-Edureka-768x762
(Example of Microservice Architecture of Uber – Microservice Architecture.)

Building a reverse proxy application

Create a file name process.go

package proxy

import (
    "bytes"
    "net/http"
    "net/url"
)

// ProcessRequest modifies the request in accordnance
// with Proxy settings
func (p *Proxy) ProcessRequest(r *http.Request) error {
    proxyURLRaw := p.BaseURL + r.URL.String()

    proxyURL, err := url.Parse(proxyURLRaw)
    if err != nil {
        return err
    }
    r.URL = proxyURL
    r.Host = proxyURL.Host
    r.RequestURI = ""
    return nil
}

// CopyResponse takes the client response and writes everything
// to the ResponseWriter in the original handler
func CopyResponse(w http.ResponseWriter, resp *http.Response) {
    var out bytes.Buffer
    out.ReadFrom(resp.Body)

    for key, values := range resp.Header {
        for _, value := range values {
        w.Header().Add(key, value)
        }
    }

    w.WriteHeader(resp.StatusCode)
    w.Write(out.Bytes())
}

Create another file name proxy.go

package proxy

import (
    "log"
    "net/http"
)

// Proxy holds our configured client
// and BaseURL to proxy to”
type Proxy struct {
    Client *http.Client
    BaseURL string
}

// ServeHTTP means that proxy implements the Handler interface
// It manipulates the request, forwards it to BaseURL, then 
// returns the response
func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if err := p.ProcessRequest(r); err != nil {
        log.Printf("error occurred during process request: %s", 
        err.Error())
        w.WriteHeader(http.StatusBadRequest)
        return
    }

    resp, err := p.Client.Do(r)
    if err != nil {
        log.Printf("error occurred during client operation: 
        %s", err.Error())
        w.WriteHeader(http.StatusInternalServerError)
        return
    }
    defer resp.Body.Close()
    CopyResponse(w, resp)
}


Finally, a main.go

package main

import (
    "fmt"
    "net/http"
    "proxy"
)

func main() {
  p := &proxy.Proxy{
      Client: http.DefaultClient,
      BaseURL: "https://www.golang.org",
  }
  http.Handle("/", p)
  fmt.Println("Listening on port :3333")
  err := http.ListenAndServe(":3333", nil)
  panic(err)
}

About GRPC clients

GRPC is a high-performance RPC framework that is built using protocol buffers (https://developers.google.com/protocol-buffers) and HTTP/2 (https://http2.github.io). Creating a GRPC client in Go involves many of the same intricacies as working with Go HTTP clients

# Keyword
OAuth2
NoSQL with MongoDB
WEB Clients and APIs
REST
gRPC
parallel and async request
interface
connect database
database handler
validate user input: don’t ever trust user input
Test tool

Working with web handlers, requests, and ResponseWriter instances
Using structures and closures for stateful handlers
Validating input for Go structures and user inputs
Rendering and content negotiation
Implementing and using middleware
Building a reverse proxy application
Exporting GRPC as a JSON API
Using Kafka with Sarama
GoFlow
Consumer and producer
Serverless
Apex, Lambda, AWS Lambda
Memory allocation and heap management

Reference:
https://openmymind.net/The-Little-Go-Book/
Download ebook Go here

Bài viết khác

Build for global scale: AFK scale cube and basic rule to build an application for global scale

REF https://akfpartners.com/growth-blog/scale-cube

PostgreSQL : subquery, CTE

What is subquery in PostgreSQL? In PostgreSQL, a subquery is a query that is nested inside another query. The subquery is executed first, and its results are used as input to the outer query. Subqueries can be used in various contexts, such as in the SELECT, WHERE, and HAVING clauses of a query. For example, […]

Optimize SQL : rule and todo list

Some rule and todo list to Optimize SQL REF https://www.pgmustard.com/blog/indexing-best-practices-postgresql

PostgreSQL Compound indexes

What is Compound indexes in PostgreSQL? A compound index (also known as a composite index or a multi-column index) refers to an index that is created on two or more columns of a table. It allows PostgreSQL to quickly find rows that match a query condition based on the values in multiple columns, which can […]

Use AWS to deploy your applications and services

Amazon Web Services (AWS) is a cloud computing platform that provides a wide range of services to help businesses and individuals build and deploy applications in the cloud. AWS offers a variety of services such as compute, storage, databases, networking, security, and more. In this guide, we will walk through the steps to get started […]

Use docker to run go project

Docker is a powerful tool that enables developers to create, deploy and run applications in a containerized environment. Using Docker to run Go projects has many advantages, including the ability to isolate your application from the underlying operating system, simplifying the deployment process, and allowing for greater scalability and flexibility. In this guide, we will […]