{"id":13713413,"url":"https://github.com/jeffotoni/goworkshopdevops","last_synced_at":"2025-10-29T04:18:28.037Z","repository":{"id":57624560,"uuid":"167730209","full_name":"jeffotoni/goworkshopdevops","owner":"jeffotoni","description":"Workshop material for 8 hours using golang","archived":false,"fork":false,"pushed_at":"2021-10-29T13:44:27.000Z","size":10825,"stargazers_count":69,"open_issues_count":0,"forks_count":10,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-20T06:44:20.869Z","etag":null,"topics":["go","golang","golang-language","gopath","mod-vendor","numeric-types","pointer-types","slice","slice-types"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jeffotoni.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-26T19:32:18.000Z","updated_at":"2025-01-31T04:54:29.000Z","dependencies_parsed_at":"2022-08-26T22:12:29.135Z","dependency_job_id":null,"html_url":"https://github.com/jeffotoni/goworkshopdevops","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jeffotoni%2Fgoworkshopdevops/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jeffotoni","download_url":"https://codeload.github.com/jeffotoni/goworkshopdevops/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245760541,"owners_count":20667886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","golang-language","gopath","mod-vendor","numeric-types","pointer-types","slice","slice-types"],"created_at":"2024-08-02T23:01:35.571Z","updated_at":"2025-10-29T04:18:27.948Z","avatar_url":"https://github.com/jeffotoni.png","language":null,"readme":"\u003ch2 align=\"center\"\u003e\n  \u003cbr/\u003e\n  \u003cimg src=\"https://github.com/jeffotoni/gocompilation/blob/master/golang-compilation.png\" alt=\"logo\" width=\"670\" /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n  \u003cbr /\u003e\n\u003c/h2\u003e\n\n# DevOps BootCamp\n\nMaterial for **8 hours** Practical Immersion **with Golang**\nThis is a material in Golang to be presented **\"face-to-face\"** in a **\"hand in hand\"** Workshop that will be done in 8 hours.\n\n# Golang Workshop DevOps\n---\n\nAll content aims at the basic level of the student many practical examples were made with details richness to make life easier than it is initiating.\n\nIf you know little and almost nothing programming will not be problem every manual was made to level starting to advanced.\nAll the difficulties I had when I started trying to contemplate this material.\nWe will try to improve the material all the time so we can have a reference when it comes to **Go**.\n\nI hope you all enjoy it and can serve as a base for learning and help several possible Gophers.\n\nThe content and references used are from the [Golang Official Site](https://golang.org) and the material being developed \nwhich is a compilation of all Golang language and can be checked here [jeffotoni/Compilation]( https://github.com/jeffotoni/goworkshopdevops#installation).\n\nSome presentations I made can be viewed here [Presentations](https://speakerdeck.com/jeffotoni).\n\nThere are thousands of references today regarding Golang, let's start at the beginning and we could not stop talking about [Golang Tour](https://tour.golang.org).\nWell that site here [Play Golang](https://play.golang.org/p/ayud1GTDJ0G) or [Play Go Space](https://goplay.space/#ayud1GTDJ0G) we can play Golang online.\n\nWe have a very interesting link that we have been able to search for packages written in Golang  check out this link: [Go Doc](https://godoc.org/)\n\nWe have this link that presents us as a manual all libs developed in Golang [Dev Docs](https://devdocs.io/go/)\n\nHere we find an awesome go, there are several lists as it is, and sometimes it's cool to check out some libs to help us with some projects. [awesome-go](https://awesome-go.com)\n\nSoon below some channels that I participate and can find me online.\n\n### Telegram:\n   - [gobr](https://t.me/go_br)\n### Slack: \n   - [gophers.slack.com](https://gophers.slack.com)\n      - Brazil\n      - Brasil\n      - General\n      - Go-kit\n      - Gotimefm\n      \n## Lab 01 Install and Commands Golang\n\n- [Overview](#overview)\n- [Introduction Installation](#introduction-installation)\n  - [Installation](#installation)\n    - [Linux](#linux)\n    - [$GOPATH](#gopath)\n    - [Test your installation](#test-your-installation)\n    - [Workspace](#workspace)\n    - [Outside GOPATH](#outside-gopath)\n- [Installation Docker](#installation-docker)\n\t- [Install Docker to Golang](#install-docker-to-golang)\n\t- [Compile your app Inside the Docker Container](#compile-your-app-inside-the-docker-container)\n\t- [Cross-compile Your app Inside the Docker Container](#cross-compile-your-app-inside-the-docker-container)\n- [Introduction Golang](#introduction-golang)\n  - [Golang Language](#golang-language)\n    - [Keywords](#keywords)\n    - [Operators and Punctuation](#operators-and-punctuation)\n    - [Println Print](#println-print)\n    - [Bufio NewWriter](#bufio-newWriter)\n    - [Func Main](#func-main)\n- [Go Commands](#go-commands)\n   - [Go Commands Introduction](#go-commands-introduction)\n   - [Go Run](#go-run) \n   - [Go Build](#go-build)\n   - [Go Install](#go-install)\n   - [Go Get](#go-get)\n   - [Go Mod](#go-mod)\n   - [Go Mod Init](#go-mod-init)\n   - [Go Mod Vendor](#go-mod-vendor)\n   - [GO111MODULE](#go111module)\n   - [Go Test](#go-test)\n\n## Lab 02 The Golang Types\n\n- [Types](#types)\n   - [Numeric Types](#numeric-types)\n   - [String Types](#string-types)\n   - [Pointer Types](#pointer-types)\n   - [Array Types](#array-types)\n   - [Slice Types](#slice-types)\n   - [Struct Types](#struct-types)\n   - [Struct In C](#struct-in-c)\n   - [Struct Type Tags Json](#struct-type-tags-json)\n   - [Fatih Structs to Map](#fatih-structs-to-map)\n   - [Map Types](#map-types)\n   - [Map Literals Continued](#map-literals-continued)\n   - [Channel Types](#channel-types)\n   - [Blank Identifier](#blank-identifier)\n   - [Interface Types](#interface-types)\n\t - [Here's an Interface as a Method](#heres-an-interface-as-a-method)\n\t - [Interface as Type](#interface-as-type)\n   - [Exercise One](#exercise-one)\n- [Control Structures](#control-structures)\n  - [Control](#control)\n    - [Control Return](#control-return)\n    - [Control Goto](#control-goto)\n    - [Control if Else](#control-if-else)\n    - [Control For Break Continue](#control-for-break-continue)\n    - [Control Switch Case Break](#control-switch-case-break)\n    - [Control Label](#control-label)\n    - [Control Range](#control-range)\n- [Errors](#Errors)\n  - [Introduction Errors](#introduction-Errors)\n    - [How Error Control Works](#how-error-control-works)\n    - [Errors New](#errorsnew)\n    - [Custom Errors](#custom-errors)    \n    - [fmt Errorf](#fmt-errorf)\n- [Functions](#functions)\n  - [Introduction Function](#introduction-function)\n    - [Return Multiple Values](#return-multiple-values) \n    - [Variadic Functions](#variadic-functions) \n    - [Functions as a Parameter](#functions-as-a-parameter) \n    - [Closures](#closures)\n    - [Recursion](#recursion)\n    - [Asynchronous Functions](#asynchronous-functions)\n- [Defer](#defer)\n- [Exercise Two](#exercise-two)\n\n## Lab 03 Parse with Golang, Yaml, Toml and Json\n\n- [Json](#Json)\n  - [Introduction](#introduction)\n    - [Json Marshal Encode](#json-marshal-encode)\n    - [Json MarshalIndent](#json-marshalIndent)\n    - [Option Omitempty](#option-omitempty)\n    - [Initialized Collections of Data](#initialized-collections-of-data)\n    - [Json NewEncoder](#json-newencoder)\n    - [Json Unmarshal Decode](#json-unmarshal-decode)\n    - [Generic JSON with Interface {} and Assertion](#generic-json-with-interface-and-assertion)\n    - [Dynamic Type](#dynamic-type)\n    - [What is Reflection](#what-is-reflection)\n    - [Making Reflect with Struct](#making-reflect-with-struct)\n- [Parse Json](#Json)\n\t- [Reading and Parsing a JSON File](#reading-and-parsing-a-json-file)\n\t- [Parsing with Structs](#parsing-with-structs)\n\t- [Parsing with Map and Interface](#parsing-with-map-and-interface)\n\t- [Parsing in Yaml Format Using Go](#parsing-in-yaml-format-using-go)\n\t- [Parsing in Toml Format Using Go](#parsing-in-toml-format-using-go)\n\t- [Parsing with Viper](#parsing-with-viper)\n- [Links Json to Golang](#links-json-to-golang)\n- [Exercise Three](#Exercise-three)\n\n## Lab 04 Building apis with net/http\n\n- [Introduction http](#introduction-http)\n\t- [Type Handler](#type-handler)\n\t- [Type HandlerFunc](#type-HandlerFunc)\n\t- [Func http Handlefunc](#func-http-handlefunc)\n\t- [Func http Handle](#func-http-handle)\n\t- [Func http Error](#func-http-error)\n\t- [Constants Common HTTP Methods](#constants-common-http-methods)\n\t- [Type ServeMux](#type-servemux)\n\t- [Type NewServeMux](#type-newservemux)\n\t- [Func ServeMux HandleFunc](#func-servemux-handleFunc)\n\t- [Type ServeMux Handle](#type-servemux-handle)\n\t- [Func ListenAndServe](#func-listenandserve)\n\t- [Func ListenAndServeTLS](#func-listenandservetls)\n\t- [Other Muxes](#other-muxes)\n\t- [Testing Http endpoints](#testing-Http-endpoints)\n\t- [Http Shutdown Gracefully](#http-shutdown-gracefully)\n\t- [Middleware](#middleware)\n\t- [http DetectContentType](#http-detectcontenttype)\n\t- [http DetectContentType](#http-detectcontenttype)    \n- [Exercise Five](#Exercise-five)\n- [net/http Client](#)\n  - [Introduction](#)\n    - [http.Transport](#)\n    - [http.Client](#)\n    - [http.Get](#)\n    - [http,Post](#)\n    - [http.NewRequest](#)\n    - [Context.WithCancel](#)\n- [Exercise Six](#Exercise-six)\n\n- [net/http Server Pages](#)\n  - [Introduction](#)\n    - [http.FileServer](#)\n    - [http.NotFound](#)\n    - [Disable http.FileServer](#)\n    - [http.Dir](#)\n    - [http.StripPrefix](#)    \n- [Exercise Seven](#Exercise-seven)\n\n## Lab 05 Using Golang to Create Command Line Programs\n\n- [Golang Cli](#golang-cli)\n  - [Introduction](#)\n  \t- [Environment Variables](#environment-variables)\n  \t- [Open and Read File](#open-write-file)\n  \t- [Write File](#write-file)\n  \t- [New Scanner and Scan](#new-scanner-and-scan)\n  \t- [Stdout](#stdout)\n    - [Stdin](#stdin)\n    - [Go Flag Types](#go-flag-types)\n    - [Go Flag Parse](go-flag-parse)\n    - [Go Flag PrintDefaults](go-flag-printDefaults)\n    - [Os Args](#os-args)\n    - [Func Init](#func-init)\n    - [Go Exec Command](#go-exec-command)\n    - [Parse Url](#parse-url)\n    - [Parse Yaml](#parse-yaml)\n\n- [Exercise Five](#Exercise-five)\n\n## Lab 06 Goroutine The Power\n\n- [Goroutine](#)\n  - [Introduction](#)\n    - [Channel](#)\n    - [Parallelism](#)\n    - [GOMAXPROCS](#)\n    - [WaitGroup](#)\n    - [Race Conditions](#)\n    - [Worker](#)\n    - [Context](#)\n    - [Ticker](#)\n    - [Singleton Connect Thread Safe](#)\n\n- [Exercise Four](#Exercise-four)\n\n### Overview\n---\n\nGo is a powerful language when it comes to competition and high performance, with a clean and efficient architecture. It grows year after \nyear and every day the communities grow even more.\n\nSome paradigms have been broken to make it a high performance language, where competition is one of its strengths. Go makes it easy to \ncreate programs that take full advantage of multicore and networked machines, while the new type system allows you to build flexible and modular programs.\n\nIt is a fast and statically compiled language that looks like a dynamically interpreted language. This feature Golang becomes \na unique language as the subject is web.\n\nGo is a compiled, competing, strong and statically typed programming language.\nIt is a \"General Use\" language that can be used to solve various problems and in different areas.\nProblems involving competition, web applications, high performance applications, development of APIs, communications sockets etc ... \nIs where language is increasingly becoming prominent in the market and in communities.\n\n### Introduction Installation\n\nIn golang the installation is all very simple and practical, for Linux, Mac and Windows.\n\nJust copy the files to the correct directory for each operating system and export the paths to the environment and prompt, golang is installed.\n\nLet's take a look at how we do this.\n\n### Installation \n---\n\nWe will download the file, unpack it and install it in /usr/local/go, if we have golang already installed in the machine we will have to remove the existing one to leave our installation as unique.\nLet's create our directory in our workspace and test to see if everything went well\n\n### Linux\n\n```bash\n$ sudo rm -rf /usr/local/go\n$ wget https://dl.google.com/go/go1.11.5.linux-amd64.tar.gz\n$ sudo tar -C /usr/local -xzf go$VERSION.$OS-$ARCH.tar.gz\n```\n\n### $GOPATH\n\n$GOPATH is the golang in your $HOME, this is necessary for your projects to use pkg and build properly. This was mandatory for all versions before version 1.11. The cool thing is that from now on we will not have to create projects in $GOPATH, we can create in any other directory that is not in $GOPATH.\n\nHere is the link to the versioning proposal [Proposal: Versioned Go Modules](https://go.googlesource.com/proposal/+/master/design/24301-versioned-go.md/) or [Go 1.11 Modules](https://github.com/golang/go/wiki/Modules/)\n\nWe'll detail how to work with **go mod**, it was one of the best experiences I had for versioning projects using Golang.\n\nLet's set up our environment to run Go. Add **/usr/local/go/bin** to the PATH environment variable. You can do this by adding this line to your **/etc/profile** (for a system-wide installation) or **$HOME/.profile**. \n\n```bash\n$ export PATH=$PATH:/usr/local/go/bin\n```\n\n**Note**: changes made to a profile file may not apply until the next time you log into your computer. To apply the changes immediately, just run the shell commands directly or execute them from the profile using a command such as source $HOME/.profile. \n\n```bash\n$ echo \"export GOPATH=$HOME/go\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH=$PATH:/usr/local/go/bin\" \u003e\u003e $HOME/.profile\n$ echo \"export PATH=$PATH:$GOPATH/bin\" \u003e\u003e $HOME/.profile\n```\n\n### Test our Installation\n\nLet's run go version to see if everything is correct.\n\n```bash\n$ go version\ngo version go1.11.5 linux/amd64\n```\n\nCheck that Go is installed correctly by setting up a workspace and building a simple program, as follows. \n\nCreate your **workspace** directory, $HOME/go. (If you'd like to use a different directory, you will need to set the $GOPATH environment variable.)\n\nNext, make the directory src/hello inside your workspace, and in that directory create a file named hello.go that looks like:\n\n### Workspace\n\nWorkspace is our place of work, where we will organize our directories with our projects. As shown above, until **Go version 1.11** we were forced to do everything under the Workspace. $GOPATH Down Projects.\n\n**Example Hello**\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go\n$ mkdir $HOME/go/src\n$ mkdir $HOME/go/src/hello\n$ vim $HOME/go/src/hello/hello.go\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-hello\n      |-hello.go\n```\n\n**Example Project**\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/go/src/project1\n$ mkdir $HOME/go/src/project1/my-pkg\n$ mkdir $HOME/go/src/project1/my-cmd\n$ mkdir $HOME/go/src/project1/my-vendor\n$ mkdir $HOME/go/src/project1/my-logs\n$ mkdir $HOME/go/src/project1/my-models\n$ mkdir $HOME/go/src/project1/my-repo\n$ mkdir $HOME/go/src/project1/my-handler\n```\n\n```bash\n$GOPATH/\n  |-src\n    |-github.com/user/project1/\n        |-cmd (of project1)\n          |-main.go\n        |-vendor\n        |-logs\n        |-models\n        |-repo\n        |-handler\n    |-github.com/user/project2/\n      ....\n      ....\n```\n\nThe $GOPATH environment variable tells the Go tool where your workspace is located. \n\n```go\n$ go get github.com/user/project1\n```\n\nThe **go get** command fetches source repositories from the internet and places them in your workspace.\nPackage paths matter to the Go tool. Using \"github.com/...\" means the tool knows how to fetch your repository. \n\nIn the scenario above everything would have to stay in our **$GOPATH** so that our projects worked correctly.\n\n### Outside $GOPATH\n\nNow we can do our projects without being in $GOPATH, we can, for example, do it in any directory.\n\n**Project Outside GOPATH**\n\n```bash\n$ export GOPATH=$HOME/go\n$ mkdir $HOME/2019/project1\n$ mkdir $HOME/2019/project1/my-pkg\n$ mkdir $HOME/2019/project1/my-cmd\n$ mkdir $HOME/2019/project1/my-logs\n$ mkdir $HOME/2019/project1/my-models\n$ mkdir $HOME/2019/project1/my-repo\n$ mkdir $HOME/2019/project1/my-handler\n```\n```bash\n$HOME/\n  |-2019\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nWe can put our project in any directory now.\n\n```bash\n$HOME/\n  |-any-directory\n    |-github.com/user/project1/\n      |-cmd\n        |-main.go\n      |-vendor\n      |-logs\n      |-models\n      |-repo\n      |-handler\n```\n\nFor the above scenario, we will have to use **go mod** in our project so that all external packages can work correctly, in this way we will be able to manage them correctly and version.\nMore information can be found here: [Wiki Go Modules](https://github.com/golang/go/wiki/Modules)\n\nPractical example of how you will proceed:\n```go\n$ go mod init github.com/user/project1\n```\n\n**Note**: \nWhen we use go mod in $GOPATH we will have to enable using GO111MODULE=on, so that it can work within the $GOPATH structure.\nSo our program can compile successfully.\n\n```go\n$ GO111MODULE=on go run cmd/main.go\n$ GO111MODULE=on go build -o project1 cmd/main.go\n```\n\n### Installation Docker\n\nIf we do not want to install directly on our operating system golang we can install it in a docker container.\n\nWe can upload a docker container with the installed language and compile and run our programs from this container.\n\nLet's check how we can do it below.\n\nMore information and details you can visit this link: [hub.docker](https://hub.docker.com/_/golang)\n\n### Install Docker to Golang\n\n```bash\n$ docker pull golang\n```\n\n### Compile Your app Inside The Docker Container\n\nThere may be occasions where it is not appropriate to run your app inside a container. To compile, but not run your app inside the \nDocker instance, you can write something like:\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.11.5 go build -v\n```\n\nThis will add your current directory as a volume to the container, set the working directory to the volume, and run the command go build which will tell go to compile the project in the working directory and output the executable to myapp. Alternatively, if you have a Makefile, you can run the make command inside your container.\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp golang:1.11.5 make\n```\n\n### Cross-compile Your app Inside The Docker Container\nIf you need to compile your application for a platform other than linux/amd64 (such as windows/386):\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/myapp -w /usr/src/myapp -e GOOS=windows \\\n-e GOARCH=386 golang:1.11.5 go build -v\n```\n\n### Example main.go\n\nLet's do our test program, let's call it main.go\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main(){\n\tfmt.Println(\"My first program being compiled by a docker container!\")\n}\n```\n\nNow let's run a program to see if it works correctly\n\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.11.5 go run main.go\n```\n\nOutput:\n```bash\nMy first program being compiled by a docker container!\n```\n\nCheck the version:\n```bash\n$ docker run --rm -v \"$PWD\":/usr/src/main -w /usr/src/main golang:1.11.5 go versio\n```\n\nOutput:\n```bash\ngo version go1.11.5 linux/amd64\n```\n\n### Introduction Golang\n---\n\nGo is a general-purpose language designed with systems programming in mind. It is strongly typed and garbage-collected and has explicit support for concurrent programming. \nPrograms are constructed from packages, whose properties allow efficient management of dependencies.\n\nThe grammar is compact and regular, allowing for easy analysis by automatic tools such as integrated development environments.\n\n### Golang Language\n---\n\n### Keywords\n\nThe following keywords are reserved and may not be used as identifiers. \n\n```bash\nbreak        default      func         interface    select\ncase         defer        go           map          struct\nchan         else         goto         package      switch\nconst        fallthrough  if           range        type\ncontinue     for          import       return       var\n```\n\n### Operators and Punctuation\n\nThe following character sequences represent operators (including assignment operators) and punctuation: \n\n```bash\n+    \u0026     +=    \u0026=     \u0026\u0026    ==    !=    (    )\n-    |     -=    |=     ||    \u003c     \u003c=    [    ]\n*    ^     *=    ^=     \u003c-    \u003e     \u003e=    {    }\n/    \u003c\u003c    /=    \u003c\u003c=    ++    =     :=    ,    ;\n%    \u003e\u003e    %=    \u003e\u003e=    --    !     ...   .    :\n     \u0026^          \u0026^=\n```\n\n### Println Print\n\nLet's learn how to send data to screen which is actually **stdout** standard output we will see more ahead with details on **stdout** and **stdin**.\n\nLet's know **print, println and fmt.Println**\n\nCurrent implementations provide several built-in functions useful during bootstrapping. These functions are documented for completeness but are not guaranteed to stay in the language. They do not return a result. \n\nImplementation restriction: **print** and **println** need not accept arbitrary argument types, but printing of boolean, numeric, and string types must be supported. \n\n**println is an built-in function** (into the runtime) which may eventually be removed, while the **fmt package** is in the standard library, which will persist.\n\n\n```bash\nFunction   Behavior\n\nprint      prints all arguments; formatting of arguments is implementation-specific\nprintln    like print but prints spaces between arguments and a newline at the end\n```\n\nusing print:\n```go\n// test print\npackage main\n\nfunc main() {\n   print(\"debugging my system with print\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with print\n```\n\nusing println:\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"debugging my system with println\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with println\n```\n\nusing fmt.Println:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n   fmt.Println(\"debugging my system with fmt.Println\")\n}\n```\n\nOutput:\n```bash\ndebugging my system with fmt.Println\n```\n\nThe goal of starting and running the print, println or fmt.Println command is to help us with the tests we will be performing from now on at every step of our Go learning.\n\n\n### Bufio NewWriter\n\n```bash\nbufio.Writer\n```\n\nDoing many small writes can hurt performance. Each write is ultimately a syscall and if doing frequently can put burden on the CPU. Devices like disks work better dealing with block-aligned data. To avoid the overhead of many small write operations Golang is shipped with bufio.Writer. Data, instead of going straight to destination (implementing io.Writer interface) are first accumulated inside the buffer and send out when buffer is full:\n\nLet’s visualise how buffering works with nine writes (one character each) when buffer has space for 4 characters:\n\n```bash\nproducer         buffer           destination (io.Writer)\n \n   a    -----\u003e   a\n   b    -----\u003e   ab\n   c    -----\u003e   abc\n   d    -----\u003e   abcd\n   e    -----\u003e   e      ------\u003e   abcd\n   f    -----\u003e   ef               abcd\n   g    -----\u003e   efg              abcd\n   h    -----\u003e   efgh             abcd\n   i    -----\u003e   i      ------\u003e   abcdefgh\n```\n\nCheck out the example below\n```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"os\"\n)\n\n// creating the write object pointer\n// so that we can receive value in every\n// scope of our program\nvar writer *bufio.Writer\n\nfunc main() {\n\t// All screen output will be redirected\n\t// to bufio.NewWriter\n\twriter = bufio.NewWriter(os.Stdout)\n\ts := \"How many stars does Orion have?\\n\"\n\tvar b byte = 'H'\n\n\twriter.WriteString(s)\n\twriter.WriteByte(b)\n\twriter.WriteString(\"\\n\")\n\n\t// when all the functions finishes it closes\n\t// the buffer and sends to the.Stdout\n\tdefer writer.Flush()\n}\n```\n\nOutput:\n```bash\nHow many stars does Orion have?\nH\n```\n\n### Func Main\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Printf(\"hello, Gophers\\n\")\n}\n```\n\nThen **build** it with the **go tool**: \n\n```go\n$ cd $HOME/go/src/hello\n$ go build\n```\n\nOr we can compile like this:\n```go\n$ cd $HOME/go/src/hello\n$ go build -o hello hello.go\n```\n\nThe command above will build an executable named hello in the directory alongside your source code. Execute it to see the greeting: \n\n```go\n$ ./hello\nhello, Gophers\n```\n\nCheck also the command **run** it with the go: \n\n```go\n$ go run hello.go\nhello, Gophers\n```\n\nIf you see the **\"hello, Gophers\"** message then your Go installation **is working**.\n\nYou can run **go install** to install the binary into your workspace's **bin** directory or **go clean -i** to remove it.\n\nExample: go install\n```go\n$ pwd\n$ $HOME/go/src/hello\n$ cd $HOME/go/src/hello\n$ go install\n$ ls -lhs $HOME/go/bin\n-rwxrwxr-x 1 user user 2,9M nov  8 03:11 hello\n```\n\nExample: go clean -i\n\n```go\n$ go clean -i \n$ ls -lhs $HOME/go/bin\n```\n\n### Go Commands\n---\n\n### Go Commands Introduction\n\nIn golang we have an arsenal to help us when it comes to compiling, testing, documenting, managing Profiling etc.\n\n```bash\nbug         start a bug report\nbuild       compile packages and dependencies\nclean       remove object files and cached files\ndoc         show documentation for package or symbol\nenv         print Go environment information\nfix         update packages to use new APIs\nfmt         gofmt (reformat) package sources\ngenerate    generate Go files by processing source\nget         download and install packages and dependencies\ninstall     compile and install packages and dependencies\nlist        list packages or modules\nmod         module maintenance\nrun         compile and run Go program\ntest        test packages\ntool        run specified go tool\nversion     print Go version\nvet         report likely mistakes in packages\n```\n\nUse \"go help \" for more information about a command.\n\n\n### Go Run\n---\n\nUsage:\n```bash\ngo run [build flags] [-exec xprog] package [arguments...]\n```\n\nRun compiles and runs the named main Go package. Typically the package is specified as a list of .go source files, but it may also be an import path, file system path, or pattern matching a single known package, as in 'go run .' or 'go run my/cmd'.\n\nBy default, 'go run' runs the compiled binary directly: 'a.out arguments...'. If the -exec flag is given, 'go run' invokes the binary using xprog: \n\nIf the -exec flag is not given, GOOS or GOARCH is different from the system default, and a program named go_$GOOS_$GOARCH_exec can be found on the current search path, 'go run' invokes the binary using that program, for example 'go_nacl_386_exec a.out arguments...'. This allows execution of cross-compiled programs when a simulator or other execution method is available.\n\nThe exit status of Run is not the exit status of the compiled binary.\n\nFor more about build flags, see 'go help build'. For more about specifying packages, see 'go help packages'.\n\nSee below an example:\n\n```go\n// test println\npackage main\n\nfunc main() {\n   println(\"Debugging my system with println\")\n}\n```\nGo run:\n```bash\ngo run println.go\n```\n\nOutput:\n```bash\nDebugging my system with println\n```\n\n### Go Build\n---\n\nBuild compiles the packages named by the import paths, along with their dependencies, but it does not install the results. \n\nWhen compiling packages, build ignores files that end in '_test.go'.\n\nThe -o flag, only allowed when compiling a single package, forces build to write the resulting executable or object to the named output file, instead of the default behavior described in the last two paragraphs.\n\nThe -i flag installs the packages that are dependencies of the target.\n\n```go\n$ go build [-o output] [-i] [build flags] [packages]\n```\n\nSee an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Println(\"Workshop Golang 2019.\")\n}\n```\n\nOutput:\n```bash\nWorkshop Golang 2019.\n```\n\nNormal compilation\n```go\ngo build -o hello hello.go\n```\n\nOutput:\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,9M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\nLeaving the file smaller after compiling\n```go\ngo build -ldflags=\"-s -w\" hello.go\n```\n\nOutput:\n```bash\n$ ls -lh \n-rwxrwxr-x 1 root root **1,3M** jan 18 12:42 hello\n-rw-rw-r-- 1 root root   75 jan 17 12:04 hello.go\n```\n\n### Go Install\n---\n\nInstall packages and dependencies\n\nUsage:\n```bash\n$ go install [-i] [build flags] [packages]\n```\n\nInstall compiles and installs the packages named by the import paths.\n\nThe **-i flag** installs the dependencies of the named packages as well.\n\nFor more about the build flags, see 'go help build'. For more about specifying packages, see 'go help packages'.\n\n### Go Get\n---\n\nThe **'go get'** command changes behavior depending on whether the go command is running in module-aware mode or legacy GOPATH mode. This help text, accessible as 'go help module-get' even in legacy GOPATH mode, describes 'go get' as it operates in module-aware mode.\n\nUsage:\n```bash\n$ go get [-d] [-m] [-u] [-v] [-insecure] [build flags] [packages]\n```\n\nGet downloads the packages named by the import paths, along with their dependencies. It then installs the named packages, like 'go install'.\n\nLook at the flags accepted below:\n```bash\nThe -d flag instructs get to stop after downloading the packages; that is, it instructs get not to install the packages.\n\nThe -f flag, valid only when -u is set, forces get -u not to verify that each package has been checked out from the source control repository implied by its import path. This can be useful if the source is a local fork of the original.\n\nThe -fix flag instructs get to run the fix tool on the downloaded packages before resolving dependencies or building the code.\n\nThe -insecure flag permits fetching from repositories and resolving custom domains using insecure schemes such as HTTP. Use with caution.\n\nThe -t flag instructs get to also download the packages required to build the tests for the specified packages.\n\nThe -u flag instructs get to use the network to update the named packages and their dependencies. By default, get uses the network to check out missing packages but does not use it to look for updates to existing packages.\n\nThe -v flag enables verbose progress and debug output.\n```\n\nExamples:\n```bash\n$ go get -v github.com/guptarohit/asciigraph\n$ go get -u github.com/mxk/go-sqlite\n$ go get -v github.com/google/uuid\n$ go get -v github.com/sirupsen/logru\n```\n\n\n### Go Mod\n---\n\nA module is a collection of related Go packages. Modules are the unit of source code interchange and versioning. The go command has direct support for working with modules, including recording and resolving dependencies on other modules. Modules replace the old GOPATH-based approach to specifying which source files are used in a given build. \n\nUsage:\n\n```bash\n$ go mod \u003ccommand\u003e [arguments]\n```\nA module is defined by a tree of Go source files with a **go.mod** file in the tree's root directory. The directory containing the go.mod file is called the module root. Typically the module root will also correspond to a source code repository root (but in general it need not). The module is the set of all Go packages in the module root and its subdirectories, but excluding subtrees with their own go.mod files.\n\nThe \"module path\" is the import path prefix corresponding to the module root. The go.mod file defines the module path and lists the specific versions of other modules that should be used when resolving imports during a build, by giving their module paths and versions.\n\nFor example, this go.mod declares that the directory containing it is the root of the module with path example.com/m, and it also declares that the module depends on specific versions of golang.org/x/text and gopkg.in/yaml.v2: \n\n```bash\n$ go mod init github.com/user/gomyproject\n\nrequire (\n  golang.org/x/text v0.3.0\n  gopkg.in/yaml.v2 v2.1.0\n)\n```\nThe go.mod file can also specify replacements and excluded versions that only apply when building the module directly; they are ignored when the module is incorporated into a larger build. For more about the go.mod file, see 'go help go.mod'.\n\nTo start a new module, simply create a go.mod file in the root of the module's directory tree, containing only a module statement. The 'go mod init' command can be used to do this: \n\n```bash\n$ go mod init github.com/user/gomyproject\n```\nIn a project already using an existing dependency management tool like **godep, glide, or dep, 'go mod init'** will also add require statements matching the existing configuration.\n\nOnce the go.mod file exists, no additional steps are required: go commands like **'go build'**, **'go test'**, or even **'go list'** will automatically add new dependencies as needed to satisfy imports.\n\nThe commands are: \n\n```bash\ndownload    download modules to local cache\nedit        edit go.mod from tools or scripts\ngraph       print module requirement graph\ninit        initialize new module in current directory\ntidy        add missing and remove unused modules\nvendor      make vendored copy of dependencies\nverify      verify dependencies have expected content\nwhy         explain why packages or modules are needed\n```\nUse \"go help mod \u003ccommand\u003e\" for more information about a command.\n\n\n### Go Mod Init\n\nInitialize new module in current directory\n\nUsage:\n\n```bash\n$ go mod init [module]\n```\n\nInit initializes and writes a new **go.mod** to the current directory, in effect creating a new module rooted at the current directory. The file go.mod must not already exist. If possible, init will guess the module path from import comments (see 'go help importpath') or from version control configuration. To override this guess, supply the module path as an argument. \n\n\n```bash\n$ go mod init github.com/user/gomyproject2\n\nrequire (\n  github.com/dgrijalva/jwt-go v3.2.0+incompatible\n  github.com/didip/tollbooth v4.0.0+incompatible\n  github.com/go-sql-driver/mysql v1.4.1\n  github.com/patrickmn/go-cache v2.1.0+incompatible // indirect\n  golang.org/x/crypto v0.0.0-20190103213133-ff983b9c42bc\n  golang.org/x/time v0.0.0-20181108054448-85acf8d2951c // indirect\n)\n```\n\n### Go Mod Vendor\n\nThe go mod vendor command will download all dependencies to the \"vendor\" directory.\nWhen using go mod init the packages are not in your directory.\n\n```bash\n$ cd gomyproject2\n$ go mod vendor\n```\n\nOutput:\n```bash\n$ ls -lh vendor\ntotal 8,0K\ndrwxrwxr-x 3 root root 4,0K jan 27 01:47 github.com\n-rw-rw-r-- 1 root root  137 jan 27 01:47 modules.txt\n```\n\n### GO111MODULE\n\nGo 1.11 includes preliminary support for Go modules, including a new module-aware 'go get' command. We intend to keep revising this support, while preserving compatibility, until it can be declared official (no longer preliminary), and then at a later point we may remove support for work in GOPATH and the old 'go get' command.\n\nThe quickest way to take advantage of the new Go 1.11 module support is to check out your repository into a directory outside GOPATH/src, create a go.mod file (described in the next section) there, and run go commands from within that file tree.\n\nFor more fine-grained control, the module support in Go 1.11 respects a temporary environment variable, GO111MODULE, which can be set to one of three string values: off, on, or auto (the default). If GO111MODULE=off, then the go command never uses the new module support. Instead it looks in vendor directories and GOPATH to find dependencies; we now refer to this as \"GOPATH mode.\" If GO111MODULE=on, then the go command requires the use of modules, never consulting GOPATH. We refer to this as the command being module-aware or running in \"module-aware mode\". If GO111MODULE=auto or is unset, then the go command enables or disables module support based on the current directory. Module support is enabled only when the current directory is outside GOPATH/src and itself contains a go.mod file or is below a directory containing a go.mod file.\n\nIn module-aware mode, GOPATH no longer defines the meaning of imports during a build, but it still stores downloaded dependencies (in GOPATH/pkg/mod) and installed commands (in GOPATH/bin, unless GOBIN is set).\n\n\nCheck below how we use the command:\n```bash\n$ GO111MODULE=on go run myprogram.go\n$ GO111MODULE=on go build myprogram.go\n```\nWhen our project is not in our **$GOPATH** it is not necessary to use **GO111MODULE**, but when our project is in **$GOPATH** and we want to use **\"go mod\"** we need to inform this to the compiler using **GO111MODULE**...\n\n\n### Go Test\n---\n\nTest packages\n\nUsage:\n\n```go\n$ go test [build/test flags] [packages] [build/test flags \u0026 test binary flags]\n```\n\nGo **test** automates testing the packages named by the import paths. It prints a summary of the test results in the format: \n\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nThe test package runs side-by-side with the go test command. The package test should have the suffix \"\\_test.go\".\nWe can split the tests into several files following this convention. For example: \"myprog1_test.go\" and \"myprog2_test.go\".\n\nWe should put our test functions in these test files.\n\nEach test function is an exported public function whose name begins with **\"Test\"**, accepts a pointer to a **testing.T** object, and returns nothing. Like this:\n\nExample one / myprog1_test:\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestWhatever(t *testing.T) {\n    // Your test code goes here\n}\n```\n\n```bash\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestWhatever\n--- PASS: TestWhatever (0.00s)\nPASS\nok    command-line-arguments  0.001s\n```\n\nThe T object provides several methods that we can use to indicate failures or log errors.\n\nExample two / myprog2_test:\n```go\npackage main\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  x := 1 + 1\n  if x != 11 { // forcing the error\n    t.Error(\"Error! 1 + 1 is not equal to 2, I got\", x)\n  }\n}\n```\n\n```bash\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestSum\n-- FAIL: TestSum (0.00s)\n    myprog1_test.go:12: Error! 1 + 1 is not equal to 2, I got 2\nFAIL\nFAIL  command-line-arguments  0.001s\n```\n\nIn this example we will make an examination as it would be in our projects.\n\nIn this program I will pass parameter at compile time or in our execution to facilitate and also serve as an example the use of **\"ldflags\"** that we can use in both **go run -ldflags ** and **go build -ldflags**\n\nFrom a check in our code below / main.go:\n```go\nimport \"strconv\"\n\nimport (\n  \"github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math\"\n)\n\nvar (\n  x, y   string\n  xi, yi int\n)\n\nfunc init() {\n  xi, _ = strconv.Atoi(x)\n  yi, _ = strconv.Atoi(y)\n}\n\nfunc main() {\n  println(math.Sum(xi, yi))\n}\n```\n\nNow we have a Sum function in a pkg that we create in **pkg/math/sum.go**\n\n```go\npackage math\n\nfunc Sum(x, y int) int {\n  return x + y\n}\n```\n\nWe created our test file in **pkg/math/sum_test.go**\n\n```go\npackage math\n\nimport \"testing\"\n\nfunc TestSum(t *testing.T) {\n  type args struct {\n    x int\n    y int\n  }\n  tests := []struct {\n    name string\n    args args\n    want int\n  }{\n    // TODO: Add test cases.\n    {\"test_1: \", args{2, 2}, 4},\n    {\"test_2: \", args{-2, 6}, 4},\n    {\"test_3: \", args{-4, 8}, 4},\n    {\"test_4: \", args{5, 7}, 12},\n    {\"test_5: \", args{8, 8}, 15}, // forcing the error\n  }\n  for _, tt := range tests {\n    t.Run(tt.name, func(t *testing.T) {\n      if got := Sum(tt.args.x, tt.args.y); got != tt.want {\n        t.Errorf(\"Sum() = %v, want %v\", got, tt.want)\n      }\n    })\n  }\n}\n```\n\n```bash\n$ cd pkg/math/\n$ go test -v\n```\n\nOutput:\n```bash\n=== RUN   TestSum\n=== RUN   TestSum/test_1:_\n=== RUN   TestSum/test_2:_\n=== RUN   TestSum/test_3:_\n=== RUN   TestSum/test_4:_\n=== RUN   TestSum/test_5:_\n--- FAIL: TestSum (0.00s)\n    --- PASS: TestSum/test_1:_ (0.00s)\n    --- PASS: TestSum/test_2:_ (0.00s)\n    --- PASS: TestSum/test_3:_ (0.00s)\n    --- PASS: TestSum/test_4:_ (0.00s)\n    --- FAIL: TestSum/test_5:_ (0.00s)\n        sum_test.go:29: Sum() = 16, want 15\nFAIL\nexit status 1\nFAIL  github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/pkg/math  0.001s\n```\n\nIt converts to json the output of the tests\n\n```bash\n$ go test -v -json\n```\n\ncheck your output on your terminal screen to view json output.\n\n---\n\nNow that we've saved our pkg / math / sum.go let's do a main.go by making the call in this packet.\nBut first let's run go mod to manage our packages and versions correctly.\n\nCheck the command below:\n```bash\n$ go mod init github.com/jeffotoni/goworkshopdevops/examples/tests/pkg\n```\n\nOutput:\n```bash\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests/pkg/math latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples/tests latest\ngo: finding github.com/jeffotoni/goworkshopdevops/examples latest\ngo: finding github.com/jeffotoni/goworkshopdevops latest\ngo: downloading github.com/jeffotoni/goworkshopdevops v0.0.0-20190127023912-a2fa53299867\n0\n```\n\nNow we can do **build** or **run** in our **main.go**.\nLet's run go run using the **\"-ldflags\"** flag to pass parameter to our code at compile time.\n\n```bash\n$ go run -ldflags \"-X main.x=2 -X main.y=3\" main.go\n```\n\nOutput:\n```bash\n5\n```\n\n```bash\n$ go run -ldflags \"-X main.x=7 -X main.y=3\" main.go\n```\n\nOutput:\n```bash\n10\n```\n\n## Lab 02 Types with Golang\n---\n\n### Types\n---\n\nA type determines a set of values together with operations and methods specific to those values. A type may be denoted by a type name, if it has one, or specified using a type literal, which composes a type from existing types. \n\nThe language predeclares certain type names. Others are introduced with type declarations. Composite types—array, struct, pointer, function, interface, slice, map, and channel types—may be constructed using type literals.\n\nEach type T has an underlying type: If T is one of the predeclared boolean, numeric, or string types, or a type literal, the corresponding underlying type is T itself. Otherwise, T's underlying type is the underlying type of the type to which T refers in its type declaration. \n\nExample:\n```bash\ntype (\n    A1 = string\n    A2 = A1\n)\n\ntype (\n    B1 string\n    B2 B1\n    B3 []B1\n    B4 B3\n)\n```\n\nThe underlying type of string, A1, A2, B1, and B2 is string. The underlying type of []B1, B3, and B4 is []B1. \n\n\n### Numeric Types\n\nA numeric type represents sets of integer or floating-point values. The predeclared architecture-independent numeric types are: \n\n```bash\nuint8       the set of all unsigned  8-bit integers (0 to 255)\nuint16      the set of all unsigned 16-bit integers (0 to 65535)\nuint32      the set of all unsigned 32-bit integers (0 to 4294967295)\nuint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)\n\nint8        the set of all signed  8-bit integers (-128 to 127)\nint16       the set of all signed 16-bit integers (-32768 to 32767)\nint32       the set of all signed 32-bit integers (-2147483648 to 2147483647)\nint64       the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807)\n\nfloat32     the set of all IEEE-754 32-bit floating-point numbers\nfloat64     the set of all IEEE-754 64-bit floating-point numbers\n\ncomplex64   the set of all complex numbers with float32 real and imaginary parts\ncomplex128  the set of all complex numbers with float64 real and imaginary parts\n\nbyte        alias for uint8\nrune        alias for int32\n```\nThe value of an n-bit integer is n bits wide and represented using two's complement arithmetic.\n\nThere is also a set of predeclared numeric types with implementation-specific sizes:\n\n```bash\nuint     either 32 or 64 bits\nint      same size as uint\nuintptr  an unsigned integer large enough to store the uninterpreted bits of a pointer value\n```\n\nTo avoid portability issues all numeric types are defined types and thus distinct except byte, which is an alias for uint8, and rune, which is an alias for int32. Conversions are required when different numeric types are mixed in an expression or assignment. For instance, int32 and int are not the same type even though they may have the same size on a particular architecture. \n\n### String Types\n\nA string type represents the set of string values. A string value is a (possibly empty) sequence of bytes. Strings are immutable: once created, it is impossible to change the contents of a string. The predeclared string type is string; it is a defined type.\n\nThe length of a string s (its size in bytes) can be discovered using the built-in function len. The length is a compile-time constant if the string is a constant. A string's bytes can be accessed by integer indices 0 through len(s)-1. It is illegal to take the address of such an element; if s[i] is the i'th byte of a string, \u0026s[i] is invalid. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype S string\n\nvar (\n  String = \"@jeffotoni\"\n)\n\nfunc main() {\n  var text string\n  var str S\n\n  mypicture := \"@Photograph-jeffotoni\"\n  str = \"@workshop-devOpsBh\"\n  text = \"@jeffotoni-golang\"\n\n  fmt.Println(str)\n  fmt.Println(String)\n  fmt.Println(text)\n  fmt.Println(mypicture)\n\n  // example string\n  s := \"日本語\"\n  fmt.Printf(\"Glyph:             %q\\n\", s)\n  fmt.Printf(\"UTF-8:             [% x]\\n\", []byte(s))\n  fmt.Printf(\"Unicode codepoint: %U\\n\", []rune(s))\n}\n```\nOutput:\n\n```go\n@workshop-devOpsBh\n@jeffotoni\n@jeffotoni-golang\n@Photograph-jeffotoni\nGlyph:             \"日本語\"\nUTF-8:             [e6 97 a5 e6 9c ac e8 aa 9e]\nUnicode codepoint: [U+65E5 U+672C U+8A9E]\n```\n### Pointer Types\n\nStruct fields can be accessed through a struct pointer.\n\nTo access the field X of a struct when we have the struct pointer p we could write (*p).X. However, that notation is cumbersome, so the language permits us instead to write just p.X, without the explicit dereference.\n\nA pointer type denotes the set of all pointers to variables of a given type, called the base type of the pointer. The value of an uninitialized pointer is nil.\n\n```bash\nPointerType = \"*\" BaseType .\nBaseType    = Type .\n```\n\n```bash\n*Point\n*[4]int\n```\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{1, 2}\n  p := \u0026v\n  p.X = 1e9\n  fmt.Println(v)\n  fmt.Println(p.Y)\n}\n```\nOutput:\n```bash\n{1000000000 2}\n2\n```\nFor every type that is declared, either by you or the language itself, you get for free a complement pointer type you can use for sharing. There already exists a built-in type named int so there is a complement pointer type called *int.\n\nAll pointer types have the same two characteristics. First, they start with the character *. Second, they all have the same memory size and representation, which is a 4 or 8 bytes that represent an address. On 32bit architectures (like the playground), pointers require 4 bytes of memory and on 64bit architectures (like your machine), they require 8 bytes of memory.\n\nExample:\n```go\npackage main\n\nfunc main() {\n\n  var a int\n  inc := \u0026a\n  *inc = 2\n  *inc++\n  println(\"inc:\\tValue Of[\", inc, \"]\\tAddr Of[\", \u0026inc, \"]\\tValue Points To[\", *inc, \"]\")\n}\n```\n\nOutput:\n```bash\ninc:  Value Of[ 0xc000036778 ]  Addr Of[ 0xc000036780 ]  Value Points To[ 3 ]\n```\n\nFor an operand x of type T, the address operation \u0026x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal. If the evaluation of x would cause a run-time panic, then the evaluation of \u0026x does too.\n\nFor an operand x of pointer type *T, the pointer indirection *x denotes the variable of type T pointed to by x. If x is nil, an attempt to evaluate *x will cause a run-time panic.\n\n```bash\n\u0026x\n\u0026a[f(2)]\n\u0026Point{2, 3}\n*p\n*pf(x)\n\nvar x *int = nil\n*x   // causes a run-time panic\n\u0026*x  // causes a run-time panic\n```\n\nSee the example below:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  var a int = 100  /* actual variable declaration */\n  var pa *int      /* pointer variable declaration */\n  var pointer *int /* pointer variable declaration */\n\n  pa = \u0026a /* store address of a in pointer variable*/\n\n  fmt.Printf(\"Address of a variable: %x\\n\", \u0026a)\n\n  /* address stored in pointer variable */\n  fmt.Printf(\"Address stored in ip variable: %x\\n\", pa)\n\n  /* access the value using the pointer */\n  fmt.Printf(\"Value of *ip variable: %d\\n\", *pa)\n\n  /* succeeds if p is not nil */\n  if pa != nil {\n    fmt.Println(\"success is not nil\")\n  }\n\n  /* succeeds if p is null */\n  if (pointer) == nil {\n    fmt.Println(\"success pointer is nil\")\n  }\n}\n```\n\nOutput:\n```bash\nAddress of a variable: c0000160c8\nAddress stored in ip variable: c0000160c8\nValue of *ip variable: 100\nsuccess is not nil\nsuccess pointer is nil\n```\n\n### Array Types\n\nAn array is a numbered sequence of elements of a single type, called the element type. The number of elements is called the length and is never negative.\n\n```bash\nArrayType   = \"[\" ArrayLength \"]\" ElementType .\nArrayLength = Expression .\nElementType = Type .\n```\n\nThe length is part of the array's type; it must evaluate to a non-negative constant representable by a value of type int. The length of array a can be discovered using the built-in function len. The elements can be addressed by integer indices 0 through len(a)-1. Array types are always one-dimensional but may be composed to form multi-dimensional types.\n\n```\n[32]byte\n[2*N] struct { x, y int32 }\n[1000]*float64\n[3][5]int\n[2][2][2]float64  // same as [2]([2]([2]float64))\n```\n\nAn array's length is part of its type, so arrays cannot be resized. This seems limiting, but don't worry; Go provides a convenient way of working with arrays. \n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n  // var a []string // wrong\n\n  // An array of 10 integers\n  var a1 [5]int\n  a1[0] = 5\n  a1[1] = 4\n  a1[2] = 3\n  a1[3] = 2\n  a1[4] = 1\n  fmt.Println(a1)\n}\n```\n\nOutput:\n```bash\n[5 4 3 2 1]\n```\n\n### Slice Types\n\nA slice is a descriptor for a contiguous segment of an underlying array and provides access to a numbered sequence of elements from that array. A slice type denotes the set of all slices of arrays of its element type. The value of an uninitialized slice is nil. \n\nAn array has a fixed size. A slice, on the other hand, is a dynamically-sized, flexible view into the elements of an array. In practice, slices are much more common than arrays.\n\nThe type **[]T** is a slice with elements of **type T**.\n\nA slice is formed by specifying two indices, a low and high bound, separated by a colon:\n\n```bash\na[low : high]\n```\n\nThis selects a half-open range which includes the first element, but excludes the last one.\n\nThe following expression creates a slice which includes elements 1 through 3 of a: \n\n```bash\na[1:4]\n```\n\nExample:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  primes := [7]int{2, 3, 5, 7, 11, 13, 14}\n  \n  var p []int = primes[2:5]\n  fmt.Println(p)\n}\n```\nOutput:\n```bash\n[5 7 11]\n```\n\nA new, initialized slice value for a given element type T is made using the built-in function make, which takes a slice type and parameters specifying the length and optionally the capacity. A slice created with make always allocates a new, hidden array to which the returned slice value refers. That is, executing.\n\n```bash\nmake([]T, length, capacity)\n```\n\nProduces the same slice as allocating an array and slicing it, so these two expressions are equivalent:\n\n```bash\nmake([]int, 50, 100)\nnew([100]int)[0:50]\n```\n\nLike arrays, slices are always one-dimensional but may be composed to construct higher-dimensional objects. With arrays of arrays, the inner arrays are, by construction, always the same length; however with slices of slices (or arrays of slices), the inner lengths may vary dynamically. Moreover, the inner slices must be initialized individually.\n\n Slices can be created with the built-in make function; this is how you create dynamically-sized arrays.\n\nThe make function allocates a zeroed array and returns a slice that refers to that array: \n\n```go\na := make([]int, 4)  // len(a)=4\n```\nExample:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  a := make([]int,4)\n  a[0]=12\n  fmt.Println(\"a\", a)\n\n  b := make([]int, 0, 5)\n  fmt.Println(\"b\", b)\n  \n  c := b[:2]\n  fmt.Println(\"c\", c)\n}\n```\nOutput:\n```bash\na [12 0 0 0]\nb []\nc [0 0]\n```\n\nA slice of type T is declared using []T. For example, Here is how you can declare a slice of type int -\n\n```go\n// Slice of type `int`\nvar slice []int\n\n// Slice of type `string`\nvar slice []string\n\n// Slice of type `string` with parameter variadic\nvar lang = [...]string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n```\n\nYou can create a slice using a slice literal like this -\n\n```go\n// Creating a slice using a slice literal\nvar s = []int{3, 5, 7, 9, 11, 13, 17}\n```\n\nThe expression on the right-hand side of the above statement is a slice literal. The slice literal is declared just like an array literal, except that you do not specify any size in the square brackets [].\n\nWhen you create a slice using a slice literal, it first creates an array and then returns a slice reference to it.\n\nLet’s see:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar s = []string{\"@jeffotoni\", \"@awsbrasil\", \"@devopsbh\", \"@go_br\"}\n\n\t// Short hand declaration\n\tt := []int{2, 4, 8, 16, 32, 64}\n\n\tfmt.Println(\"s = \", s, len(s))\n\tfmt.Println(\"t = \", t, len(t))\n}\n```\nOutput:\n```bash\ns =  [@jeffotoni @awsbrasil @devopsbh @go_br] 4\nt =  [2 4 8 16 32 64] 6\n```\n\nSince a slice is a segment of an array, we can create a slice from an array.\n\nTo create a slice from an array a, we specify two indices low (lower bound) and high (upper bound) separated by a colon\n\n```bash\n// Obtaining a slice from an array `a`\na[low:high]\n```\n\nThe above expression selects a slice from the array a. The resulting slice includes all the elements starting from index low to high, but excluding the element at index high.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\t// Creating a slice using a slice literal\n\tvar groups = [5]string{\"@awsbrasil\", \"@devopsbh\", \"@go_br\", \"@devopsbr\", \"@docker\"}\n\n\t// Creating a slice from the array\n\tvar s []string = groups[2:5]\n\n\ts2 := s[1:3]\n\ts3 := s[:3]\n\ts4 := s[2:]\n\ts5 := s[:]\n\n\tfmt.Println(\"Array groups = \", groups, \"len:\", len(groups), \"cap:\", cap(groups))\n\tfmt.Println(\"Slice s = \", s, \"len:\", len(s), \"cap:\", cap(s))\n\tfmt.Println(\"Slice s = \", s2, \"len:\", len(s2), \"cap:\", cap(s2))\n\tfmt.Println(\"Slice s = \", s3, \"len:\", len(s3), \"cap:\", cap(s3))\n\tfmt.Println(\"Slice s = \", s4, \"len:\", len(s4), \"cap:\", cap(s4))\n\tfmt.Println(\"Slice s = \", s5, \"len:\", len(s5), \"cap:\", cap(s5))\n}\n```\n\nOutput:\n```bash\nArray groups =  [@awsbrasil @devopsbh @go_br @devopsbr @docker] len: 5 cap: 5\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@devopsbr @docker] len: 2 cap: 2\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\nSlice s =  [@docker] len: 1 cap: 1\nSlice s =  [@go_br @devopsbr @docker] len: 3 cap: 3\n```\n\nThe copy() function copies elements from one slice to another. Its signature looks like this\n\n```go\nfunc copy(dst, src []T) int\n```\n\nIt takes two slices - a destination slice, and a source slice. It then copies elements from the source to the destination and returns the number of elements that are copied.\n\nNote that the elements are copied only if the destination slice has sufficient capacity.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\tsrc := []string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n\tdest := make([]string, 2)\n\n\tnumElementsCopied := copy(dest, src)\n\n\tfmt.Println(\"src = \", src)\n\tfmt.Println(\"dest = \", dest)\n\tfmt.Println(\"Number of elements copied from src to dest = \", numElementsCopied)\n}\n```\n\nOutput:\n```bash\nsrc =  [Erlang Elixir Haskell Clojure Scala]\ndest =  [Erlang Elixir]\nNumber of elements copied from src to dest =  2\n```\nThe append() function appends new elements at the end of a given slice. Following is the signature of append function.\n\n```go\nfunc append(s []T, x ...T) []T\n```\n\nIt takes a slice and a variable number of arguments x …T. It then returns a new slice containing all the elements from the given slice as well as the new elements.\n\nIf the given slice doesn’t have sufficient capacity to accommodate new elements then a new underlying array is allocated with bigger capacity. All the elements from the underlying array of the existing slice are copied to this new array, and then the new elements are appended.\n\nHowever, if the slice has enough capacity to accommodate new elements, then the append() function re-uses its underlying array and appends new elements to the same array.\n\nLet’s see an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tslice1 := []string{\"Clojure\", \"Scala\", \"Elixir\"}\n\tslice2 := append(slice1, \"Assembly\", \"Rust\", \"Go\")\n\tfmt.Printf(\"slice1 = %v, len = %d, cap = %d\\n\", slice1, len(slice1), cap(slice1))\n\tfmt.Printf(\"slice2 = %v, len = %d, cap = %d\\n\", slice2, len(slice2), cap(slice2))\n\tslice1[0] = \"C++\"\n\tfmt.Println(\"\\nslice1 = \", slice1)\n\tfmt.Println(\"slice2 = \", slice2)\n\t\n\t// slice nil\n\tvar s []string\n\n\t// Appending to a nil slice\n\ts = append(s, \"Java\", \"C\", \"Lisp\", \"Haskell\")\n\tfmt.Printf(\"\\ns = %v, len = %d, cap = %d\\n\", s, len(s), cap(s))\n}\n```\n\nOutput:\n```bash\nslice1 = [Clojure Scala Elixir], len = 3, cap = 3\nslice2 = [Clojure Scala Elixir Assembly Rust Go], len = 6, cap = 6\n\nslice1 =  [C++ Scala Elixir]\nslice2 =  [Clojure Scala Elixir Assembly Rust Go]\n\ns = [Java C Lisp Haskell], len = 4, cap = 4\n```\n\n### Struct Types\n\nA struct is a sequence of named elements, called fields, each of which has a name and a type. Field names may be specified explicitly (IdentifierList) or implicitly (EmbeddedField). Within a struct, non-blank field names must be unique.\n\n```go\nStructType    = \"struct\" \"{\" { FieldDecl \";\" } \"}\" .\nFieldDecl     = (IdentifierList Type | EmbeddedField) [ Tag ] .\nEmbeddedField = [ \"*\" ] TypeName .\nTag           = string_lit .\n\n// An empty struct.\nstruct{}\n\n// A struct with 6 fields.\nstruct {\n  x, y int\n  u float32\n  _ float32  // padding\n  A *[]int\n  F func()\n}\n```\n\nA field declared with a type but no explicit field name is called an embedded field. An embedded field must be specified as a type name T or as a pointer to a non-interface type name *T, and T itself may not be a pointer type. The unqualified type name acts as the field name.\n\n```go\n// A struct with four embedded fields of types T1, *T2, P.T3 and *P.T4\nstruct {\n  T1        // field name is T1\n  *T2       // field name is T2\n  P.T3      // field name is T3\n  *P.T4     // field name is T4\n  x, y int  // field names are x and y\n}\n```\n\nThe following declaration is illegal because field names must be unique in a struct type:\n\n```go\nstruct {\n  T     // conflicts with embedded field *T and *P.T\n  *T    // conflicts with embedded field T and *P.T\n  *P.T  // conflicts with embedded field T and *T\n}\n```\nA struct is a collection of fields. \n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Vertex struct {\n  X int\n  Y int\n}\n\nfunc main() {\n  v := Vertex{10, 201}\n  v.X = 4\n  fmt.Println(v)\n}\n```\n\nOutput:\n```bash\n{4 201}\n```\n\n### Struct in C \n\nBefore we will see the origin of everything in C, let's see the code written in C and the comments of how it would be in Golang.\nAnd we have it written in Golang, so that you can see how dynamic you were in Go, the C inheritance was simply fantastic and light.\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\nstruct Login {\n    char *User;\n    char *Email;\n};\n\n/**\n  // In Go would look like this\n  type Login struct {\n    User string\n    Email string\n  }\n */\n\nint main() {\n/** \n // In Go \nfunc main() {\n*/\n    \n    struct Login login, *pointerToLogin;\n\n    /**\n    // In Go\n    login := Login{User:\"jeffotoni\", Email:\"jef@m.com\"}\n    */\n\n    login.User = \"jeffotoni\";\n    login.Email = \"jef@m.com\";\n\n    pointerToLogin = malloc(sizeof(struct Login));\n    pointerToLogin-\u003eUser = \"pike\";\n    pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    /**\n    var pointerToLogin  = new(Login)\n    pointerToLogin.User  = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n    */\n    printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    /**\n     fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n     fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email);\n    */\n\n    free(pointerToLogin);\n    return 0;\n}\n```\n\nCompile the program in C:\n```\n$ gcc -o struct-1-c struct-1-c.c\n```\n\nOutput:\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: 0x5627788a0260 pike pike@g.com\n```\n\nConfira agora o Código em Go abaixo:\n\n```go\npackage main\n\nimport \"fmt\"\n// #include \u003cstdio.h\u003e\n// #include \u003cstdlib.h\u003e\n\n// struct Login {\n//     char *User;\n//     char *Email;\n// };\n\n//In Go would look like this\ntype Login struct {\n    User  string\n    Email string\n}\n\n// int main() {\n\n// In Go\nfunc main() {\n\n    //struct Login login, *pointerToLogin;\n\n    // In Go\n    login := Login{User: \"jeffotoni\", Email: \"jef@m.com\"}\n\n    login.User = \"jeffotoni\"\n    login.Email = \"jef@m.com\"\n\n    // pointerToLogin = malloc(sizeof(struct Login));\n    // pointerToLogin-\u003eUser = \"pike\";\n    // pointerToLogin-\u003eEmail = \"pike@g.com\";\n\n    var pointerToLogin = new(Login)\n    pointerToLogin.User = \"pike\"\n    pointerToLogin.Email = \"pike@g.com\"\n\n    //printf(\"login vals: %s %s\\n\", login.User, login.Email);\n    //printf(\"pointerToLogin: %p %s %s\\n\", pointerToLogin, pointerToLogin-\u003eUser, pointerToLogin-\u003eEmail);\n\n    fmt.Printf(\"login vals: %s %s\\n\", login.User, login.Email)\n    fmt.Printf(\"pointerToLogin: %v %s %s\\n\", pointerToLogin, pointerToLogin.User, pointerToLogin.Email)\n\n    //free(pointerToLogin);\n    return\n}\n```\n\n```bash\nlogin vals: jeffotoni jef@m.com\npointerToLogin: \u0026{pike pike@g.com} pike pike@g.com\n```\n\n### Struct Type Tags Json\n\nWe use json tags with omitempty or not to represent our json string, when generated by **json.Marshal** which we will see soon below.\n\nExample:\n```go\nimport (\n\t//\"encoding/json\"\n\t\"fmt\"\n)\n\n// We use the omitempty tag in 'json: field, omitempty'\n// when we want the field not to appear after\n// making the marshal if it is empty.\ntype D struct {\n\tHeight int\n\tWidth  int `json:\"width,omitempty\"`\n}\n\n// Fields that do not have the \"omitempty\" tag will display \n// the same field being empty when generating \n// json through marshal.\ntype Cat struct {\n\tBreed    string `json:\"breed,omitempty\"`\n\tWeightKg int    `json:WeightKg`\n\tSize     D      `json:\"size,omitempty\"`\n}\n\nfunc main() {\n\td := Cat{\n\t\t//Breed:    \"Persa\",\n\t\tWeightKg: 23,\n\t\t//Size:     D{20, 60},\n\t}\n\t//b, _ := json.Marshal(d)\n\t//fmt.Println(string(b))\n\tfmt.Println(d)\n}\n```\n\nOutput:\n```bash\n{ 23 {20 60}}\n```\n\nIn this example we have a struct \"ApiLogin\" and inside it we have And1 \\*struct\", ie, referencing a pointer from another struct, beautiful is not.\nTo initialize and access the \"And1\" field, we have to use the \"\u0026\" operator and create the struct at its initialization because it has not been defined yet so it would look like this: **\"And1: \u0026 struct {City string} {City: \"BH\"}\"**\n```go\ntype ApiLogin struct {\n\tAnd1  *struct {\n\t\tCity string\n\t}\n}\n```\n\nIn this example we only time the pointer of a struct already defined above.\nTo access it we do not need to create it again, just refer to it with \"\u0026\" and this way \"And2: \u0026Address{}\", very nice, right?\n```go\ntype ApiLogin struct {\n\tAnd2 *Address\n}\n```\n\nThe example below is a way to display various forms of initialization using struct.\n```go\npackage main\n\nimport \"fmt\"\n\ntype Address struct {\n\tCity         string `json:\"city\"`\n\tNeighborhood string `json:\"neighborhood\"`\n\tZipcode      string `json:\"zipcode\"`\n}\n\ntype ApiLogin struct {\n\tName  string `json:\"name\"`\n\tCpf   string `json:\"cpf\"`\n\tLogin string `json:\"login\"`\n\tEmail string `json:\"email\"`\n\n\t// anonymous\n\tAnd1 *struct {\n\t\tCity string\n\t}\n\n\t// pointer\n\tAnd2 *Address\n\n\t// list Address\n\tAnd3 []Address\n}\n\nfunc main() {\n\n\t// different ways to inizialize a struct\n\t//\n\t//\n\n\tapilogin1 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}}\n\tfmt.Println(apilogin1)\n\tfmt.Println(apilogin1.Name)\n\tfmt.Println(apilogin1.And1)\n\tfmt.Println(apilogin1.And1.City)\n\n\tapilogin2 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin2)\n\tfmt.Println(apilogin2.Name)\n\tfmt.Println(apilogin2.And2)\n\tfmt.Println(apilogin2.And2.City)\n\n\tapilogin3 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\", And1: \u0026struct{ City string }{City: \"BH\"}, And2: \u0026Address{City: \"BH\"}}\n\tfmt.Println(apilogin3)\n\tfmt.Println(apilogin3.Name)\n\tfmt.Println(apilogin3.And1)\n\tfmt.Println(apilogin3.And1.City)\n\tfmt.Println(apilogin3.And2)\n\tfmt.Println(apilogin3.And2.City)\n\n\tvar apilogin4 ApiLogin\n\tfmt.Println(apilogin4)\n\n\tapilogin5 := ApiLogin{}\n\tfmt.Println(apilogin5)\n\n\tapilogin6 := \u0026ApiLogin{}\n\tfmt.Println(apilogin6)\n\n\tapilogin7 := new(ApiLogin)\n\tfmt.Println(apilogin7)\n\n\t// another way to feed the struct\n\tg1add := Address{City: \"Belo Horizonte\"}\n\tg2add := Address{City: \"Curitiba\"}\n\n\t// declaring as list\n\tgall := []Address{}\n\n\t// add items\n\tgall = append(gall, g1add)\n\tgall = append(gall, g2add)\n\n\tfmt.Println(gall)\n\n\t// initializes Struct\n\tapil3 := ApiLogin{}\n\n\t// recive same type\n\tapil3.And3 = gall\n\n\t// show struct\n\tfmt.Println(apil3)\n\n\t// another way to initialize and feed the struct list\n\tapil3.And3 = []Address{{City: \"Sao Paulo\"}, {City: \"Brasilia\"}}\n\n\t// show struct\n\tfmt.Println(apil3)\n}\n```\n\nOutput:\n```bash\n\u0026{@jeffotoni 093.393.334-34   0xc00000e1e0 \u003cnil\u003e []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{@jeffotoni 093.393.334-34   \u003cnil\u003e 0xc000060150 []}\n@jeffotoni\n\u0026{BH  }\nBH\n\u0026{@jeffotoni 093.393.334-34   0xc00000e300 0xc0000601b0 []}\n@jeffotoni\n\u0026{BH}\nBH\n\u0026{BH  }\nBH\n{    \u003cnil\u003e \u003cnil\u003e []}\n{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n\u0026{    \u003cnil\u003e \u003cnil\u003e []}\n[{Belo Horizonte  } {Curitiba  }]\n{    \u003cnil\u003e \u003cnil\u003e [{Belo Horizonte  } {Curitiba  }]}\n{    \u003cnil\u003e \u003cnil\u003e [{Sao Paulo  } {Brasilia  }]}\n```\n\nThe example below is to demonstrate the ease we have when we manipulate structs in Golang.\nWe are initializing the struct with values and displaying on the screen.\n\nTake a look:\n```go\npackage main\n\nimport \"fmt\"\n\ntype jsoninput []struct {\n\tData string `json:\"data\"`\n}\n\nfunc main() {\n\n\tdata := \u0026jsoninput{{Data: \"some data\"}, {Data: \"some more data\"},\n\t\t{Data: \"some more data\"}}\n\tfmt.Println(data)\n\n\t// output:\n\t//  \u0026[{some data} {some more data} {some more data}]\n}\n```\n\n```bash\n\u0026[{some data} {some more data} {some more data}]\n```\n\nIn our example below is another way to make array of struct, we made the statement at the time of initializing our struct, this causes that the struct does not get caught in only accepting array of struct.\nWe did append in the fields and the magic happens.\n\nLet's take a look at the complete code:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n)\n\ntype User struct {\n\tFirstName string `tag_name:\"firstname\"`\n\tLastName  string `tag_name:\"lastname\"`\n\tAge       int    `tag_name:\"age\"`\n}\n\nfunc main() {\n\t// create instance\n\t// slice struct\n\tusers := []*User{}\n\n\tuser := new(User)\n\tuser.FirstName = \"Jefferson\"\n\tuser.LastName = \"otoni\"\n\tuser.Age = 350\n\tusers = append(users, user)\n\n\tuser = new(User)\n\tuser.FirstName = \"Pike\"\n\tuser.LastName = \"Hob\"\n\tuser.Age = 55\n\tusers = append(users, user)\n\n\tfmt.Println(users)\n\n\tfor k, v := range users {\n\t\tfmt.Println(k, v)\n\t\tfmt.Println(v.FirstName)\n\t\tfmt.Println(v.LastName)\n\t\tfmt.Println(v.Age)\n\t}\n}\n```\n\nOutput:\n```bash\n[0xc000060150 0xc000060180]\n0 \u0026{Jefferson otoni 350}\nJefferson\notoni\n350\n1 \u0026{Pike Hob 55}\nPike\nHob\n55\n```\n\nExample Struct AWS Sqs Json\n```go\ntype SqsJson struct {\n\tType      string `json:\"type\"`\n\tMessageId string `json:\"messageid\"`\n\tTopicArn  string `json:\"topicarn\"`\n\tMessage   string `json:\"message\"`\n\t//Message          JsonMessage\n\tTimestamp        string `json:\"timestamp\"`\n\tSignatureVersion string `json:\"signatureversion\"`\n\tSignature        string `json:\"signature\"`\n\tSigningCertURL   string `json:\"signingcerturl\"`\n\tUnsubscribeURL   string `json:\"unsubscribeurl\"`\n}\n\ntype JsonMessage struct {\n\tNotificationType string `json:\"notificationType\"`\n\tBounce           struct {\n\t\tBounceType        string `json:\"bounceType\"`\n\t\tBounceSubType     string `json:\"bounceSubType\"`\n\t\tBouncedRecipients []struct {\n\t\t\tEmailAddress   string `json:\"emailAddress\"`\n\t\t\tAction         string `json:\"action\"`\n\t\t\tStatus         string `json:\"status\"`\n\t\t\tDiagnosticCode string `json:\"diagnosticCode\"`\n\t\t} `json:\"bouncedRecipients\"`\n\t\tTimestamp    time.Time `json:\"timestamp\"`\n\t\tFeedbackID   string    `json:\"feedbackId\"`\n\t\tRemoteMtaIP  string    `json:\"remoteMtaIp\"`\n\t\tReportingMTA string    `json:\"reportingMTA\"`\n\t} `json:\"bounce\"`\n\n\tMail struct {\n\t\tTimestamp        time.Time `json:\"timestamp\"`\n\t\tSource           string    `json:\"source\"`\n\t\tSourceArn        string    `json:\"sourceArn\"`\n\t\tSourceIP         string    `json:\"sourceIp\"`\n\t\tSendingAccountID string    `json:\"sendingAccountId\"`\n\t\tMessageID        string    `json:\"messageId\"`\n\t\tDestination      []string  `json:\"destination\"`\n\t\tHeadersTruncated bool      `json:\"headersTruncated\"`\n\t\tHeaders          []struct {\n\t\t\tName  string `json:\"name\"`\n\t\t\tValue string `json:\"value\"`\n\t\t} `json:\"headers\"`\n\n\t\tCommonHeaders struct {\n\t\t\tFrom    []string `json:\"from\"`\n\t\t\tReplyTo []string `json:\"replyTo\"`\n\t\t\tTo      []string `json:\"to\"`\n\t\t\tSubject string   `json:\"subject\"`\n\t\t} `json:\"commonHeaders\"`\n\t} `json:\"mail\"`\n}\n```\n\nWhen the subject is struct we have several possibilities to deal with and work with this feature in Golang, it is practically embedded in everything we will build in Golang, Structs is something powerful in Go to manipulate data and send data all the time between channels using goroutine, be it in queues, database recordings, json and database reads, GraphQL, REST API, SOAP etc ...\n\n\n### Fatih Structs to Map\n\nBelow is a lib that works directly with struct, converting to Maps.\nI do not use it in production but for our course it is interesting to analyze.\nWe know that the more native we are in Golang it will be a good option, but at times we will need some libs to help us.\nThis project is not maintained anymore and is archived. Feel free to fork and make your own changes if needed.\n\nStructs contains various utilities to work with Go (Golang) structs. It was initially used by me to convert a struct into a map[string]interface{}. With time I've added other utilities for structs. It's basically a high level package based on primitives from the reflect package. Feel free to add new functions or improve the existing code.\n\nInstall\n```go\ngo get github.com/fatih/structs\n```\n\nTo test low rotate the code below:\n```go\n\ntype Server struct {\n\tName        string `json:\"name,omitempty\"`\n\tID          int\n\tEnabled     bool\n\tUsers       []string // not exported\n\thttp.Server          // embedded\n}\n\nfunc main() {\n\n\t// Create a new struct type:\n\n\tserver := \u0026Server{\n\t\tName:    \"gopher\",\n\t\tID:      12345678,\n\t\tUsers:   []string{\"jeffotoni\", \"pike\", \"dennis\", \"ken\"},\n\t\tEnabled: true,\n\t}\n\n\t// struct\n\tfmt.Println(server)\n\n\t// create struct fatih\n\ts := structs.New(server)\n\tm := s.Map() // Get a map[string]interface{}\n\tfmt.Println(m)\n\n\tv := s.Values() // Get a []interface{}\n\tfmt.Println(v)\n\n\tf := s.Fields() // Get a []*Field\n\tfmt.Println(f)\n\n\tn := s.Names() // Get a []string\n\tfmt.Println(n)\n\n\tname := s.Field(\"Name\") // Get a *Field based on the given field name\n\n\t// Get the underlying value,  value =\u003e \"gopher\"\n\tvalue := name.Value().(string)\n\tfmt.Println(value)\n\n\ttagValue := name.Tag(\"json\")\n\tfmt.Println(tagValue)\n\n\tf1, ok := s.FieldOk(\"Name\") // Get a *Field based on the given field name\n\tfmt.Println(f1, ok)\n\n\tn2 := s.Name() // Get the struct name\n\tfmt.Println(n2)\n\n\th := s.HasZero() // Check if any field is uninitialized\n\tfmt.Println(h)\n}\n```\n\nOutput:\n```bash\n\u0026{gopher 12345678 true [jeffotoni pike dennis ken] \n{ \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e 0 0 {{0 0} 0} \u003cnil\u003e {0 0} map[] map[] \u003cnil\u003e []}}\nmap[Server:map[TLSConfig:\u003cnil\u003e ReadHeaderTimeout:0s IdleTimeout:0s Addr: Handler:\u003cnil\u003e \n]MaxHeaderBytes:0 TLSNextProto:map[] ConnState:\u003cnil\u003e ErrorLog:\u003cnil\u003e ReadTimeout:0s WriteTimeout:0s] \nName:gopher ID:12345678 Enabled:true Users:[jeffotoni pike dennis ken]]\n[gopher 12345678 true [jeffotoni pike dennis ken]  \u003cnil\u003e \u003cnil\u003e 0s 0s 0s 0s 0 map[] \u003cnil\u003e \u003cnil\u003e]\n[0xc000106000 0xc000106090 0xc000106120 0xc0001061b0 0xc000106240]\n[Name ID Enabled Users Server]\ngopher\nname,omitempty\n\u0026{{0x626180 0xc0000f6000 408} {Name  0x626180 json:\"name,omitempty\" 0 [0] false} structs} true\nServer\ntrue\n```\n\n### Map Types\n\nA map is an unordered group of elements of one type, called the element type, indexed by a set of unique keys of another type, called the key type. The value of an uninitialized map is nil.\n\n```bash\nMapType     = \"map\" \"[\" KeyType \"]\" ElementType .\nKeyType     = Type .\n```\n\nThe comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice. If the key type is an interface type, these comparison operators must be defined for the dynamic key values; failure will cause a run-time panic.\n\n```bash\nmap[string]int\nmap[*T]struct{ x, y float64 }\nmap[string]interface{}\n```\n\nThe number of map elements is called its length. For a map m, it can be discovered using the built-in function len and may change during execution. Elements may be added during execution using assignments and retrieved with index expressions; they may be removed with the delete built-in function.\n\nA new, empty map value is made using the built-in function make, which takes the map type and an optional capacity hint as arguments:\n\n```bash\nmake(map[string]int)\nmake(map[string]int, 100)\n```\n\nThe initial capacity does not bound its size: maps grow to accommodate the number of items stored in them, with the exception of nil maps. A nil map is equivalent to an empty map except that no elements may be added.\n\nSome examples of map initialization:\n```go\npackage main\n\nimport \"fmt\"\n\ntype linkResult struct {\n\tbody string\n\turls []string\n}\n\ntype linkFetcher map[string]*linkResult\n\nfunc main() {\n\t// Required to initialize\n\t// the map with values\n\tvar m1 map[string]int\n\tvar m2 = make(map[string]int)\n\tvar m3 = map[string]int{\"population\": 500000}\n\tvar m4 = m3\n\tvar m5 map[string]string\n\t/* create a map*/\n\tm5 = make(map[string]string)\n\tfmt.Println(m1, m2, m3, m4, m5)\n\n\tvar l = linkFetcher{\n\t\t\"https://golang.org/\": \u0026linkResult{\n\t\t\t\"The Go Programming Language\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/pkg/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t},\n\t\t},\n\t\t\"https://golang.org/pkg/\": \u0026linkResult{\n\t\t\t\"Packages\",\n\t\t\t[]string{\n\t\t\t\t\"https://golang.org/\",\n\t\t\t\t\"https://golang.org/cmd/\",\n\t\t\t\t\"https://golang.org/pkg/fmt/\",\n\t\t\t\t\"https://golang.org/pkg/os/\",\n\t\t\t},\n\t\t}}\n\n\tfmt.Println(l)\n}\n```\nOutput:\n```bash\nmap[] map[] map[population:500000] map[population:500000] map[]\n```\n\nA map is declared using the following syntax:\n```go\nvar m map[KeyType]ValueType\n\n// For example, Here is how you can declare a map of string keys to int values\nvar m map[string]int\n```\n\nThe zero value of a map is nil. A nil map has no keys. Moreover, any attempt to add keys to a nil map will result in a runtime error.\n\nLet’s see an example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m map[string]int\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\t// Attempting to add keys\n\t// to a nil map will result in a runtime error\n\t//m[\"population\"] = 500000\n\t//fmt.Println(m)\n}\n```\n\nOutput:\n```bash\nmap[]\nis nil\n```\n\nYou can initialize a map using the built-in make() function. You just need to pass the type of the map to the make() function as in the example below. The function will return an initialized and ready to use map.\n\n```go\n// Initializing a map using the built-in make() function\nvar m = make(map[string]int)\n```\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n\t// Required to initialize\n\t// the map with values\n\tvar m = make(map[string]int)\n\tfmt.Println(m)\n\tif m == nil {\n\t\tfmt.Println(\"is nil\")\n\t}\n\tm[\"population\"] = 500000\n\tfmt.Println(m)\n}\n```\nOutput:\n```bash\nmap[]\nmap[population:500000]\n```\n\nThe example below introduces the creation of a map getting a struct done.\nWhen do we use an empty struct?\nThere are some scenarios when we have a large amount of access in our API, but when I say large is\u003e 10k = 10k of requests per second, in this scenario when we do our handler, we can implement a channel receiving an empty struct {} so that we can get put on a channel and process everything in with more security.\nWe will show more ahead this very legal approach.\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\ts := \"key\"\n\tseen := make(map[string]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nOutput:\n```go\nmap[key:{}]\n```\n\nwe can also make our map key receive an empty struct.\nWell we know that it gets any type ie the struct can be complete without it's done too.\n\nExample:\n```go\ntype T struct{}\n\nfunc main() {\n\ts := T{}\n\tseen := make(map[struct{}]struct{}) // set of strings\n\t// ...\n\tif _, ok := seen[s]; !ok {\n\t\tseen[s] = struct{}{}\n\t\t// ...first time seeing s...\n\t}\n\tfmt.Println(seen)\n}\n```\n\nOutput:\n```go\nmap[{}:{}]\n```\n\n### Map Literals Continued\n\nA map literal is a very convenient way to initialize a map with some data. You just need to pass the key-value pairs separated by colon inside curly braces.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar m = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\n\tfmt.Println(m)\n}\n```\n\nOutput:\n```bash\nmap[Italy:Roma France:Paris Japan:Toquio Brasil:Brasilia EUA:Washington, D.c]\n```\n\nSo you can check for the existence of a key in a map by using the following two-value assignment.\nThe boolean variable ok will be true if the key exists, and false otherwise.\n\n```go\nvalue, ok := m[key]\n```\n\nConsider the following map for example:\n```go\nvar C = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n```\n\n```go\ncapital, ok := C[\"EUA\"]  // \"Washington, D.c\", true\n```\n\nHowever, If you try to access a key that doesn’t exist, then the map will return an empty string \"\" (zero value of strings), and false\n\n```go\ncapital, ok := C[\"África do Sul\"]  // \"\", false\n```\n\nYou can delete a key from a map using the built-in delete() function. The syntax looks like this.\n\n```go\n// Delete the `key` from the `map`\ndelete(map, key)\n```\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar country = map[string]string{\n\t\t\"Brasil\": \"Brasilia\",\n\t\t\"EUA\":    \"Washington, D.c\",\n\t\t\"Italy\":  \"Roma\",\n\t\t\"France\": \"Paris\",\n\t\t\"Japan\":  \"Toquio\",\n\t}\n\tdelete(country, \"Japan\")\n\tdelete(country, \"Italy\")\n\tfmt.Println(country)\n}\n```\n\nOutput:\n```bash\nmap[Brasil:Brasilia EUA:Washington, D.c France:Paris]\n```\n \nIf the top-level type is just a type name, you can omit it from the elements of the literal. \n```go\npackage main\n\nimport \"fmt\"\n\ntype Login struct {\n\tUser, Login, Email string\n}\n\n// passing a struct as parameter\n// for our struct map\nvar m = map[string]Login{\n\t\"jeffotoni\": {\"jeffotoni\", \"jeff\", \"jeff@gm.com\"},\n\t\"Google\":    {\"root\", \"super\", \"google@gm.com\"},\n}\n\nfunc main() {\n\tfmt.Println(m)\n}\n```go\n\n```bash\nmap[jeffotoni:{jeffotoni jeff jeff@gm.com} Google:{root super google@gm.com}]\n```\n\n### Channel Types\n\nA channel provides a mechanism for concurrently executing functions to communicate by sending and receiving values of a specified element type. The value of an uninitialized channel is nil.\n\n```bash\nChannelType = ( \"chan\" | \"chan\" \"\u003c-\" | \"\u003c-\" \"chan\" ) ElementType .\n```\n\nThe optional \u003c- operator specifies the channel direction, send or receive. If no direction is given, the channel is bidirectional. A channel may be constrained only to send or only to receive by conversion or assignment.\n\n```bash\nchan T          // can be used to send and receive values of type T\nchan\u003c- float64  // can only be used to send float64s\n\u003c-chan int      // can only be used to receive ints\n```\n\nThe \u003c- operator associates with the leftmost chan possible:\n\n```bash\nchan\u003c- chan int    // same as chan\u003c- (chan int)\nchan\u003c- \u003c-chan int  // same as chan\u003c- (\u003c-chan int)\n\u003c-chan \u003c-chan int  // same as \u003c-chan (\u003c-chan int)\nchan (\u003c-chan int)\n```\n\nA new, initialized channel value can be made using the built-in function make, which takes the channel type and an optional capacity as arguments:\n\n```bash\nmake(chan int, 100)\n```\n\nThe capacity, in number of elements, sets the size of the buffer in the channel. If the capacity is zero or absent, the channel is unbuffered and communication succeeds only when both a sender and receiver are ready. Otherwise, the channel is buffered and communication succeeds without blocking if the buffer is not full (sends) or not empty (receives). A nil channel is never ready for communication.\n\nA channel may be closed with the built-in function close. The multi-valued assignment form of the receive operator reports whether a received value was sent before the channel was closed.\n\nA single channel may be used in send statements, receive operations, and calls to the built-in functions cap and len by any number of goroutines without further synchronization. Channels act as first-in-first-out queues. For example, if one goroutine sends values on a channel and a second goroutine receives them, the values are received in the order sent.\n\nLet me show you an example:\n```go\n\npackage main\n\nimport (\n  \"fmt\"\n  \"os\"\n  \"time\"\n)\n\ntype Promise struct {\n  Result chan string\n  Error  chan error\n}\n\nvar (\n  ch1  = make(chan *Promise)  // received a pointer from the structure\n  ch2  = make(chan string, 1) // allows only 1 channels\n  ch3  = make(chan int, 2)    // allows only 2 channels\n  ch4  = make(chan float64)   // has not been set can freely receive\n  ch5  = make(chan []byte)    // by default the capacity is 0\n  ch6  = make(chan bool, 1)   // non-zero capacity\n  ch7  = make(chan time.Time, 2)\n  ch8  = make(chan struct{}, 2)\n  ch9  = make(chan struct{})\n  ch10 = make(map[string](chan int)) // map channel\n  ch11 = make(chan error)\n  ch12 = make(chan error, 2)\n  // receives a zero struct\n  ch14 \u003c-chan struct{}\n  ch15 = make(\u003c-chan bool)          // can only read from\n  ch16 = make(chan\u003c- []os.FileInfo) // // can only write to\n  // holds another channel as its value\n  ch17 = make(chan\u003c- chan bool) // // can read and write to\n)\n\n// Parameters of Func\n// (jobs \u003c-chan int, results chan\u003c- int)\n\n// Receives Value, only read\n// jobs \u003c-chan int //receives the value\n\n// Receives Channel, only write\n// results chan\u003c- int // receive channel\n// or\n// results chan int // receive channel\n\n// Receives Channel variadic\n// results ...\u003c-chan int\n\nfunc main() {\n\n  ch2 \u003c- \"okay\"\n  defer close(ch2)\n  fmt.Println(ch2, \u0026ch2, \u003c-ch2)\n\n  ch7 \u003c- time.Now()\n  ch7 \u003c- time.Now()\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  fmt.Println(ch7, \u0026ch7, \u003c-ch7)\n  defer close(ch7)\n\n  ch3 \u003c- 1 // okay\n  ch3 \u003c- 2 // okay\n  // deadlock\n  // ch3 \u003c- 3 // does not accept any more values, if you do it will error : deadlock\n  defer close(ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n  fmt.Println(ch3, \u0026ch3, \u003c-ch3)\n\n  ch10[\"lambda\"] = make(chan int, 2)\n  ch10[\"lambda\"] \u003c- 100\n  defer close(ch10[\"lambda\"])\n  fmt.Println(\u003c-ch10[\"lambda\"])\n}\n```\n\nOutput:\n```bash\n0xc000056180 0x55bb00 okay\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906669 -0200 -02 m=+0.000147197\n0xc0000561e0 0x55bb28 2019-01-25 15:11:41.982906922 -0200 -02 m=+0.000147409\n0xc00001e0e0 0x55bb08 1\n0xc00001e0e0 0x55bb08 2\n100\n```\n\n### Blank Identifier\n\nThe blank identifier is represented by the underscore character **_**. It serves as an anonymous placeholder instead of a regular (non-blank) identifier and has special meaning in declarations, as an operand, and in assignments.\n\nExample:\n```bash\n// function statement\nfunc f() (int, string, error)\n\n// function return\n_, _, _ := f()\n```\n\n### Interface Types\n\n**An interface is two things:**\n - it is a set of methods\n - but it is also a type\n\nThe __interface{} type__, the empty interface is the interface that has __no methods__\n\nSince there is no implements keyword, all types implement at least zero methods, and satisfying an interface is done automatically, all types satisfy the empty interface.\nThat means that if you write a function that takes an interface{} value as a parameter, you can supply that function with any value.\n\nExample:\n```go\nfunc DoSomething(v interface{}) {\n   // ...\n}\n\nvar Msg interface{}\n\ntype Stringer interface {\n    String() string\n}\n```\n\n### Here's an interface as a method\n\nAn interface type specifies a method set called its interface. A variable of interface type can store a value of any type with a method set that is any superset of the interface. Such a type is said to implement the interface. The value of an uninitialized variable of interface type is nil.\n\n\n```bash\nInterfaceType      = \"interface\" \"{\" { MethodSpec \";\" } \"}\" .\nMethodSpec         = MethodName Signature | InterfaceTypeName .\nMethodName         = identifier .\nInterfaceTypeName  = TypeName .\n```\n\nAs with all method sets, in an interface type, each method must have a unique non-blank name.\n\n```go\n// A simple File interface\ninterface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n  Close()\n}\n```\n\nMore than one type may implement an interface. For instance, if two types S1 and S2 have the method set\n\n```bash\nfunc (p T) Read(b Buffer) bool { return … }\nfunc (p T) Write(b Buffer) bool { return … }\nfunc (p T) Close() { … }\n```\n\n(where T stands for either S1 or S2) then the File interface is implemented by both S1 and S2, regardless of what other methods S1 and S2 may have or share.\n\nA type implements any interface comprising any subset of its methods and may therefore implement several distinct interfaces. For instance, all types implement the empty interface:\n\n```bash\ninterface{}\n```\n\nSimilarly, consider this interface specification, which appears within a type declaration to define an interface called Locker:\n\n```go\ntype Locker interface {\n  Lock()\n  Unlock()\n}\n```\n\nIf S1 and S2 also implement\n\n```bash\nfunc (p T) Lock() { … }\nfunc (p T) Unlock() { … }\n```\n\nthey implement the Locker interface as well as the File interface.\n\nAn interface T may use a (possibly qualified) interface type name E in place of a method specification. This is called embedding interface E in T; it adds all (exported and non-exported) methods of E to the interface T.\n\n```go\ntype ReadWriter interface {\n  Read(b Buffer) bool\n  Write(b Buffer) bool\n}\n\ntype File interface {\n  ReadWriter  // same as adding the methods of ReadWriter\n  Locker      // same as adding the methods of Locker\n  Close()\n}\n\ntype LockedFile interface {\n  Locker\n  File        // illegal: Lock, Unlock not unique\n  Lock()      // illegal: Lock not unique\n}\n```\n\nAn interface type T may not embed itself or any interface type that embeds T, recursively.\n```go\n// illegal: Bad cannot embed itself\ntype Bad interface {\n  Bad\n}\n\n// illegal: Bad1 cannot embed itself using Bad2\ntype Bad1 interface {\n  Bad2\n}\ntype Bad2 interface {\n  Bad1\n}\n```\n\nExample: \n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype R struct {\n  R string\n}\n\ntype Iread interface {\n  Read() string\n}\n\nfunc (r *R) Read() string {\n  return fmt.Sprintf(\"Only: call Read\")\n}\n\nfunc Call(ir Iread) string {\n  return fmt.Sprintf(\"Read: %s\", ir.Read())\n}\n\nfunc main() {\n  var iread Iread\n  r := R{\"hello interface\"}\n  // A way to use Interface\n  iread = \u0026r\n  fmt.Println(iread, r)\n  fmt.Println(iread.Read())\n\n  // Second way to access interface\n  r2 := R{\"hello interface call\"}\n  fmt.Println(Call(\u0026r2))\n}\n```\n\nOutput:\n```bash\n\u0026{hello interface} {hello interface}\nOnly: call Read\nRead: Only: call Read\n```\n\n###  Interface as type\n\nInterfaces as type __interface{}__ means you can put value of any type, including your own custom type. All types in Go satisfy an empty interface (interface{} is an empty interface).\nIn your example, Msg field can have value of any type. \n\n\n```go\nvar val interface{} // element type of m is assignable to val\n``` \n\n```go\ntype Empty interface {\n    /* it has no methods */\n}\n\n// Because, Empty interface has no methods, \n// following types satisfy the Empty interface\nvar a Empty\n\na = 60\na = 10.5\na = \"Lambda Man\"\n```\n\nInterfaces as types looks at another example below:\n```go\npackage main\n\nimport (\n  \"fmt\"\n)\n\ntype MyStruct struct {\n  Msg interface{}\n}\n\nfunc main() {\n  b := MyStruct{}\n  // string\n  b.Msg = \"5\"\n  fmt.Printf(\"%#v %T \\n\", b.Msg, b.Msg) // Output: \"5\" string\n\n  // int\n  b.Msg = 5\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n\n  // map\n  b.Msg = map[string]string{\"population\": \"500000\", \"language\": \"sueco\"}\n  fmt.Printf(\"%#v %T\", b.Msg, b.Msg) //Output:  5 int\n}\n```\n\n### Exercise One\nExercise:\nFill in the struct JsonMessage AWS above, initialize the struct and fill in the fields, and make a fmt.Println to display the filled fields.\nTo be more readable you can separate into each struct type struct.\n\n### Control Structures\n---\n\n### Control\n\nThe control structures are:\n\n__For, If, else, else if__\n\nAnd some statments between them: __break, continue, switch, case and goto__.\n\n### Control Return\n\nStatements control execution.\n\n```bash\nStatement =\n  Declaration | LabeledStmt | SimpleStmt |\n  GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |\n  FallthroughStmt | Block | IfStmt | SwitchStmt | SelectStmt | ForStmt |\n  DeferStmt .\n\nSimpleStmt = EmptyStmt | ExpressionStmt | SendStmt | IncDecStmt | Assignment | ShortVarDecl .\n```\n\nA terminating statement prevents execution of all statements that lexically appear after it in the same block. The following statements are terminating:\n\n1. A \"return\" or \"goto\" statement.\n\nReturn:\n```go\npackage main\n\nfunc main() {\n  println(Lambda())\n  return\n}\n\nfunc Lambda() string {\n\n  return \"Lambda\"\n}\n```\n\nOutput:\n```bash\nLambda\n```\n\n### Control Goto\n\nGoto:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  n := 0\n\nLOOP1:\n  n++\n  if n == 10 {\n    println(\"fim\")\n    return\n  }\n\n  if n%2 == 0 {\n    goto LOOP2\n  } else {\n\n    fmt.Println(\"n\", n, \"LOOP1 here...\")\n    goto LOOP1\n  }\n\nLOOP2:\n  fmt.Println(\"n\", n, \"LOOP2 here...\")\n  goto LOOP1\n\n}\n```\n\nOutput:\n```bash\nn 1 LOOP1 here...\nn 2 LOOP2 here...\nn 3 LOOP1 here...\nn 4 LOOP2 here...\nn 5 LOOP1 here...\nn 6 LOOP2 here...\nn 7 LOOP1 here...\nn 8 LOOP2 here...\nn 9 LOOP1 here...\nfim\n```\n\n### Control if Else\n\n2. An \"if\" statement in which:\n      - the \"else\" branch is present, and\n      - both branches are terminating statements.\n```go\npackage main\n\nfunc main() {\n  n := 100\n  if n \u003e 0 \u0026\u0026 n \u003c= 55 {\n    println(\"n \u003e 0 or n \u003c= 55\")\n  } else if n \u003e 56 \u0026\u0026 n \u003c 70 {\n    println(\"n \u003e 56 and n \u003c 70\")\n  } else {\n\n    if n \u003e= 100 {\n      println(\" else here.. n \u003e 100\")\n    } else {\n      println(\" else here.. n \u003e 70\")\n    }\n  }\n}\n```\n\nOutput:\n```bash\nelse here.. n \u003e 100\n```\n\n### Control For Break Continue\n\n3. A \"for\" statement in which:\n      - there are no \"break\" statements referring to the \"for\" statement, and\n      - the loop condition is absent.\n      - there are \"continue\"\n      - A \"break\" statement terminates execution of the innermost \"for\", \"switch\", or \"select\" statement within the same \n\n```go\npackage main\n\nfunc main() {\n  // will be looping infinitely\n  // for {\n  // }\n\n  // will run only once and exit\n  for {\n    break\n  }\n\n  n := 5\n  for n \u003e 0 {\n    n--\n    println(n)\n  }\n  // Output:\n  // 4\n  // 3\n  // 2\n  // 1\n  // 0\n\n  // declaring i no and increasing i\n  for i := 0; i \u003c 5; i++ {\n    println(i)\n  }\n  // Output:\n  // 0\n  // 1\n  // 2\n  // 3\n  // 4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i \u003c= 2 {\n      continue\n    } else {\n      println(\"i \u003e 2 = \", i)\n    }\n  }\n\n  // Output:\n  // i \u003e 2 =  3\n  // i \u003e 2 =  4\n\n  n = 5\n  for i := 0; i \u003c n; i++ {\n    if i == 2 {\n      break\n    } else {\n      println(\"i: \", i)\n    }\n  }\n  // Output:\n  // i:  0\n  // i:  1\n  \n  // infinitely\n  for ; ; i++ {\n    println(\"i: \", i)\n  }\n  // Output:\n  // i:  1\n  // i:  2\n  // ..\n  // ..\n}\n```\n\n### Control Switch Case Break\n\n4. A \"switch\" statement in which:\n      - there are no \"break\" statements referring to the \"switch\" statement,\n      - there is a default \"case\", and\n      - the statement lists in each case, including the default, end in a terminating statement, or a possibly labeled \"fallthrough\" statement.\n\n```go\npackage main\n\nfunc main() {\n  j := 10\n  i := 0\n  switch j {\n  case 11:\n    println(\"here: 11\")\n    break\n  default:\n    println(\"here default\")\n    break\n  }\n\n  // infinitely\n  for ; ; i++ {\n\n    switch i {\n    case 5:\n      goto LABELS\n    case i:\n      println(\"i: \", i)\n      break\n    default:\n      println(\"default: \", i)\n    }\n  }\n\nLABELS:\n  f()\n\n}\n\nfunc f() {\n  println(\"goto fim\")\n}\n```\n\nOutput:\n```bash\nhere default\ni:  0\ni:  1\ni:  2\ni:  3\ni:  4\ngoto fim\n```\n\n### Control Label\n\n5. A labeled statement labeling a terminating statement.\n\n```go\npackage main\n\nfunc main() {\n  i := 0\n  // infinitely\n  for ; ; i++ {\n    for {\n      if i == 10 {\n        goto LABEL\n      }\n      i++\n    }\n  }\n\nLABEL:\n  f(i)\n\n}\n\nfunc f(i int) {\n  println(\"label fim i:\", i)\n}\n```\n\nOutput:\n```bash\nlabel fim i: 10\n```\n\nAll other statements are not terminating.\n\nA statement list ends in a terminating statement if the list is not empty and its final non-empty statement is terminating. \n\nA \"for\" statement with a \"range\" clause iterates through all entries of an array, slice, string or map, or values received on a channel. For each entry it assigns iteration values to corresponding iteration variables if present and then executes the block. \n\n```bash\nRangeClause = [ ExpressionList \"=\" | IdentifierList \":=\" ] \"range\" Expression .\n```\n\n### Control Range\n\nThe expression on the right in the \"range\" clause is called the range expression, which may be an array, pointer to an array, slice, string, map, or channel permitting receive operations. As with an assignment, if present the operands on the left must be addressable or map index expressions; they denote the iteration variables. If the range expression is a channel, at most one iteration variable is permitted, otherwise there may be up to two. If the last iteration variable is the blank identifier, the range clause is equivalent to the same clause without that identifier. \n\n```bash\nRange expression                          1st value          2nd value\n\narray or slice  a  [n]E, *[n]E, or []E    index    i  int    a[i]       E\nstring          s  string type            index    i  int    see below  rune\nmap             m  map[K]V                key      k  K      m[k]       V\nchannel         c  chan E, \u003c-chan E       element  e  E\n```\n\nSee an example below, with various uses using Range:\n```go\n\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\n  // string arrays / slice\n  var lang = [...]string{\"Erlang\", \"Elixir\", \"Haskell\", \"Clojure\", \"Scala\"}\n\n  // screen list\n  fmt.Println(lang)\n\n  // list the positions srtring arrays\n  for k, v := range lang {\n    fmt.Println(k, v)\n  }\n\n  /* create a map*/\n  countryCapitalMap := map[string]string{\"Brasil\": \"Brasilia\", \"EUA AMERICA\": \"Washington, D.C.\", \"France\": \"Paris\", \"Italy\": \"Roma\", \"Japan\": \"Tokyo\"}\n\n  /* print map using key-value*/\n  for country, capital := range countryCapitalMap {\n    fmt.Println(\"Capital of\", country, \"is\", capital)\n  }\n\n  // channel\n  jobs := make(chan int, 3)\n\n  // for channel\n  for j := 1; j \u003c= 3; j++ {\n    jobs \u003c- j\n  }\n  // println(\u003c-jobs)\n  // println(\u003c-jobs)\n  // println(\u003c-jobs)\n\n  // close\n  /* date is required for range to work*/\n  close(jobs)\n\n  /* This syntax is valid too. */\n  for range jobs {\n  }\n\n  /* it is mandatory to close the channels to be able to scroll */\n  for ch := range jobs {\n    println(ch)\n  }\n\n  // it is not an array struct, it will range from error.\n  sa := struct{ nick string }{\"@jeffotoni\"}\n  fmt.Println(sa.nick)\n\n  // here the range will be able to list all struct\n  a := []struct{ nick string }{{\"@devopsbr\"}, {\"@go_br\"}, {\"@awsbrasil\"}, {\"@go_br\"}, {\"@devopsbh\"}}\n  for i, v := range a {\n    fmt.Println(i, v.nick)\n  }\n\n  // struct pointer\n  var testdata *struct {\n    a *[3]int\n  }\n  for i := range testdata.a {\n    // testdata.a is never evaluated; len(testdata.a) is constant\n    // i ranges from 0 to 2\n    fmt.Println(i)\n  }\n\n  // new example interface and range\n  var key string\n  var val interface{} // element type of m is assignable to val\n  m := map[string]int{\"mon\": 0, \"tue\": 1, \"wed\": 2, \"thu\": 3, \"fri\": 4, \"sat\": 5, \"sun\": 6}\n  for key, val = range m {\n    fmt.Println(key, val)\n  }\n}\n```\n\nOutput:\n```bash\n[Erlang Elixir Haskell Clojure Scala]\n0 Erlang\n1 Elixir\n2 Haskell\n3 Clojure\n4 Scala\nCapital of Brasil is Brasilia\nCapital of EUA AMERICA is Washington, D.C.\nCapital of France is Paris\nCapital of Italy is Roma\nCapital of Japan is Tokyo\n@jeffotoni\n0 @devopsbr\n1 @go_br\n2 @awsbrasil\n3 @go_br\n4 @devopsbh\n0\n1\n2\nsat 5\nsun 6\nmon 0\ntue 1\nwed 2\nthu 3\nfri 4\n```\n### Errors\n---\n \n The predeclared type error is defined as \n\n ```bash\n type error interface {\n\tError() string\n}\n ```\nIt is the conventional interface for representing an error condition, with the nil value representing no error. For instance, a function to read data from a file might be defined: \n\n```bash\nfunc Read(f *File, b []byte) (n int, err error)\n```\n\n### Introduction Errors\n\nError handling in Golang is very simple to deal with. There is no try, catch or exceptions.\nThe error is handled with every call of some function.\nAs we show \"error\" is an interface, and much used.\n\nWhen we talk about handling errors in Golang everything is very simple, a good practice is to return an error in the functions that we created and treat them.\n\nLet's see in practice how it works.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar error error\n\tfmt.Println(error)\n}\n```\n\nOutput:\n```bash\n\u003cnil\u003e\n```\n### How Error Control Works\n\nExample:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nvar Error error\nvar b []byte\n\nfunc main() {\n\tfmt.Println(Error)\n\tcpu := make(chan int)\n\t// Create JSON from the instance data.\n\tb, Error = json.Marshal(cpu)\n\tif Error != nil {\n\t\tfmt.Println(Error)\n\t} else {\n\t\tfmt.Println(string(b))\n\t}\n}\n```\n\nOutput:\n```bash\n\u003cnil\u003e\njson: unsupported type: chan int\n```\n\n### Errors New\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\t\"math\"\n)\n\nfunc Sqrt(fvalue float64) (float64, error) {\n\tif fvalue \u003c 0 {\n\t\treturn 0, errors.New(\"Math: negative number passed to Sqrt [\" + fmt.Sprintf(\"%.2f\", fvalue) + \"]\")\n\t}\n\treturn math.Sqrt(fvalue), nil\n}\n\nfunc main() {\n\tresult, err := Sqrt(-33)\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(\"Sqrt (-33) = [\", result, \"]\")\n\t}\n\n\tresult, err = Sqrt(81)\n\n\tif err != nil {\n\t\tfmt.Println(err)\n\t} else {\n\t\tfmt.Println(\"Sqrt(81) = [\", result, \"]\")\n\t}\n}\n```\nOutput:\n```bash\nMath: negative number passed to Sqrt [-33.00]\nSqrt(81) = [ 9 ]\n```\n\n### Custom Errors\n\n```go\npackage main\n\nimport \"fmt\"\n\n// It's possible to use custom types as `error`s by\n// implementing the `Error()` method on them.\ntype MyError struct {\n    line int\n    msg  string\n}\n\nfunc (e *MyError) Error() string {\n    return fmt.Sprintf(\"%d - %s\", e.line, e.msg)\n}\n\nfunc MyFunc(line int) (int, error) {\n    if line \u003c 100 {\n\n        // In this case we use `\u0026MyError` syntax to build\n        // a new struct, supplying values for the two\n        // fields `arg` and `prob`.\n        return -1, \u0026MyError{line, \"can't work with it\"}\n    }\n    return line, nil\n}\n\nfunc main() {\n\n    // The one loops below test out each of our\n    // error-returning functions.\n    for _, i := range []int{200, 99} {\n        if r, e := MyFunc(i); e != nil {\n            fmt.Println(\"MyFunc failed:\", e)\n        } else {\n            fmt.Println(\"MyFunc worked in line: \", r)\n        }\n    }\n}\n```\n\nOutput:\n```bash\nMyFunc worked in line:  200\nMyFunc failed: 99 - can't work with it\n```\n\n### fmt Errorf\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"math\"\n)\n\nfunc circleArea(radius float64) (float64, error) {\n    if radius \u003c 0 {\n        return 0, fmt.Errorf(\"Failed, radius %0.2f is less than zero\", radius)\n    }\n    return math.Pi * radius * radius, nil\n}\n\nfunc main() {\n    radius := -80.0\n    area, err := circleArea(radius)\n    if err != nil {\n        fmt.Println(err)\n        return\n    }\n    fmt.Printf(\"Area of circle: %0.2f\", area)\n}\n```\nOutput:\n```bash\nArea calculation failed, radius -80.00 is less than zero\n```\n\n### Functions \n---\n\nDeclaring and Calling Functions in Golang. \nIn Golang, we declare a function using the func keyword. \nA function has a name, a list of comma-separated input parameters along with their types, the result type(s), and a body. \nThe input parameters and return type(s) are optional for a function.\n\nExample of declaring and Calling Functions in Golang:\n```go\nfunc Sum(x float64, y float64) float64 {\n\treturn (x + y) / 2\n}\n```\n\n### Introduction Function\n\nGo requires explicit returns, i.e. it won’t automatically return the value of the last expression.\nWhen you have multiple consecutive parameters of the same type, you may omit the type name for the like-typed parameters up to the final parameter that declares the type.\nA function type denotes the set of all functions with the same parameter and result types. The value of an uninitialized variable of function type is nil. \n\nSome possibilities:\n```bash\nfunc()\nfunc(x int) int\nfunc(a, _ int, z float32) bool\nfunc(a, b int, z float32) (bool)\nfunc(prefix string, values ...int)\nfunc(a, b int, z float64, opt ...interface{}) (success bool)\nfunc(int, int, float64) (float64, *[]int)\nfunc(n int) func(p *T)\n```\n\n```go\npackage main\n\nfunc F1(name string) string {\n    return \"Hello, \" + name\n}\n\nfunc main() {\n\n    println(F1(\"@go_br\"))\n}\n```\n\nOutput:\n```bash\nHello, @go_br\n```\n\n### Return Multiple Values\n\nGo has built-in support for multiple return values. This feature is used often in idiomatic Go, for example to return both result and error values from a function.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// The `(int, int)` in this function signature shows that\n// the function returns 2 `int`s.\nfunc F1() (string, int, error) {\n    return \"@go_br\", 100, nil\n}\n\nfunc main() {\n\n    // Here we use the 2 different return values from the\n    // call with _multiple assignment_.\n    a, b, err := F1()\n    fmt.Println(a)\n    fmt.Println(b)\n    fmt.Println(err)\n\n    // If you only want a subset of the returned values,\n    // use the blank identifier `_`.\n    a, _, err = F1()\n    fmt.Println(a)\n    fmt.Println(err)\n}\n```\n\nOutput:\n```bash\n@go_br\n100\n\u003cnil\u003e\n@go_br\n\u003cnil\u003e\n```\n\n### Variadic Functions\n\nVariadic functions can be called with any number of trailing arguments. For example, fmt.Println is a common variadic function.\nHere’s a function that will take an arbitrary number of ints as arguments.\nVariadic functions can be called in the usual way with individual arguments.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\n// This variadic function takes an arbitrary number of ints as arguments.\nfunc Show(names ...string) {\n\tfmt.Print(\"The Len of \", len(names)) // Also a variadic function.\n\tappends := \"\"\n\tfor _, name := range names {\n\t\tappends += name + \",\"\n\t}\n\tappends = strings.Trim(appends, \",\")\n\tfmt.Println(\" is: [\", appends, \"]\") // Also a variadic function.\n}\n\nfunc main() {\n\n\t// Variadic functions can be called in the usual way with individual\n\t// arguments.\n\tShow(\"C\", \"C++\")\n\tShow(\"Clojure\", \"Elixir\", \"Scala\")\n\n\t// If you already have multiple args in a slice, apply them to a variadic\n\t// function using func(slice...) like this.\n\tnums := []string{\"Algol\", \"C\", \"C++\", \"Golang\"}\n\tShow(nums...)\n}\n```\n\nOutput:\n```bash\nThe Len of 2 is: [ C,C++ ]\nThe Len of 3 is: [ Clojure,Elixir,Scala ]\nThe Len of 4 is: [ Algol,C,C++,Golang ]\n```\n\n### Functions as a Parameter\n\nYou can pass function as parameter to a Go function. Here is an example of passing function as parameter to another Go function.\n\n```go\npackage main\n\nimport \"fmt\"\n\n// convert types take an int\n// and return a string value.\ntype fn func(int) string\n\nfunc f1(param int) string {\n\treturn fmt.Sprintf(\"param is %v\", param)\n}\n\nfunc f2(param int) string {\n\treturn fmt.Sprintf(\"param is %v\", param)\n}\n\nfunc test(f fn, val int) {\n\tfmt.Println(f(val))\n}\n\nfunc main() {\n\ttest(f1, 432)\n\ttest(f2, 874)\n}\n```\n\nOutput:\n```bash\nparam is 432\nparam is 874\n```\n\n```go\npackage main\n\nimport \"fmt\"\n\n// --------------------------------\nfunc Square(num int) int {\n\treturn num * num\n}\n\nfunc Mapp(f func(int) int, List []int) []int {\n\tvar a = make([]int, len(List), len(List))\n\tfor index, val := range List {\n\n\t\ta[index] = f(val)\n\t}\n\treturn a\n}\n\nfunc main() {\n\tlist := []int{454, 455, 86, 988}\n\tresult := Mapp(Square, list)\n\tfmt.Println(result)\n}\n```\n\nOutput:\n```bash\n[206116 207025 7396 976144]\n```\n\n### Closures\n\nGo supports anonymous functions, which can form closures. Anonymous functions are useful when you want to define a function inline without having to name it.\nThis function intSeq returns another function, which we define anonymously in the body of intSeq. The returned function closes over the variable i to form a closure.\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc PlusX() func(v int) int {\n    return func(v int) int {\n        return v + 5\n    }\n}\n\nfunc plusXandY(x int) func(v int) int {\n    return func(v int) int {\n        return v + x\n    }\n}\n\nfunc main() {\n    p := PlusX()\n    fmt.Printf(\"5+15: %d\\n\", p(15))\n\n    px := plusXandY(6)\n    fmt.Printf(\"6+10: %d\\n\", px(10))\n}\n```\n\nOutput:\n```bash\n5+15: 20\n6+10: 16\n```\n\n### Recursion\n\nGo supports recursive functions. Here’s a classic factorial example.\n\nA simple example:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc fact(n int) int {\n\tif n == 0 {\n\t\treturn 1\n\t}\n\treturn n * fact(n-1)\n}\n\nfunc main() {\n\tfmt.Println(fact(7))\n}\n```\n\nOutput:\n```bash\n5040\n```\n\nListing all subdirectories directories:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"path\"\n\t\"path/filepath\"\n)\n\n// Listing our example directory\n// Listing our example directory recursively\nfunc main() {\n\n\t// Capturing our path that is in the environment\n\tgopath := os.Getenv(\"PWD\")\n\n\t// directory we want to list\n\tgopath += \"/examples\"\n\n\t// Making call in function\n\tlist := ListDir(gopath)\n\n\t// listing the function return\n\tfor i, p := range list {\n\t\tfmt.Printf(\"[%d:%s===%s]\\n\", i, path.Dir(p), path.Base(p))\n\t}\n}\n\n// This function uses pkg filepath.Walk, it is\n// a recursive function, where it will go through\n// our directory and its subfolders.\nfunc ListDir(rootpath string) []string {\n\n\tlist := make([]string, 0)\n\n\t// recursive call\n\t// This function receives a function as parameter and after going through all levels it ends.\n\terr := filepath.Walk(rootpath, func(path string, info os.FileInfo, err error) error {\n\t\tif info.IsDir() {\n\t\t\treturn nil\n\t\t}\n\n\t\tif filepath.Ext(path) != \".git\" \u0026\u0026 filepath.Ext(path) != \".svn\" {\n\t\t\tlist = append(list, path)\n\t\t}\n\t\treturn nil\n\t})\n\tif err != nil {\n\t\tfmt.Printf(\"walk error [%v]\\n\", err)\n\t}\n\treturn list\n}\n```\n\nOutput:\n```bash\n[0:$(pwd)/examples/bufio.writer===main.go]\n[1:$(pwd)/examples/error===error1.go]\n[2:$(pwd)/examples/error===error2.go]\n[3:$(pwd)/examples/error===error3.go]\n[4:$(pwd)/examples/error===error4.go]\n...\n...\n```\n\n### Asynchronous Functions\n\nIn golang to perform asynchronous functions we use the keyword **\"go\"** it is responsible for putting the functions to be executed concurrently.\nA **\"go\"** statement starts the execution of a function call as an independent concurrent thread of control, or goroutine, within the same address space. \n\n```go\nGoStmt = \"go\" Expression .\n```\n\n```go\ngo Server()\ngo func(ch chan\u003c- bool) { for { sleep(10); ch \u003c- true }} (c)\n```\n\nExample:\n```go\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"time\"\n)\n\nvar r = rand.Intn(500)\n\nfunc pinger() {\n\ttime.Sleep(time.Duration(r) * time.Microsecond)\n\tfmt.Println(\"pinger\")\n}\n\nfunc ponger() {\n\ttime.Sleep(time.Duration(r) * time.Microsecond)\n\tfmt.Println(\"ponger\")\n}\n\nfunc printer() {\n\ttime.Sleep(time.Duration(r) * time.Microsecond)\n\tfmt.Println(\"printer\")\n}\n\nfunc main() {\n\t// making functions\n\t// calls asynchronously\n\tgo pinger()\n\tgo ponger()\n\tgo printer()\n\n\t// Waiting to press any key to end\n\tvar input string\n\tfmt.Scanln(\u0026input)\n}\n```\nOutput one:\n```bash\nponger\npinger\nprinter\n```\n\nOutput two:\n```bash\npinger\nponger\nprinter\n```\n\n### Defer\n\nA \"defer\" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking. \n\n```go\nDeferStmt = \"defer\" Expression .\n```\n\nThe expression must be a function or method call; it cannot be parenthesized. Calls of built-in functions are restricted as for expression statements.\n\nEach time a \"defer\" statement executes, the function value and parameters to the call are evaluated as usual and saved anew but the actual function is not invoked. Instead, deferred functions are invoked immediately before the surrounding function returns, in the reverse order they were deferred. If a deferred function value evaluates to nil, execution panics when the function is invoked, not when the \"defer\" statement is executed. \n\nExamples:\n```go\ndefer unlock(l)\ndefer myFunc()\ndefer close(channel)\ndefer fmt.Print(x)\ndefer db.Close()\ndefer f.Close()\ndefer res.Body.Close()\n```\n\n## Lab 03 Json with Golang\n\n### Json\n---\n\nPackage json implements encoding and decoding of JSON as defined in **RFC 7159**. The mapping between JSON and Go values is described in the documentation for the **Marshal** and **Unmarshal** functions.\n\n### Introduction\n\n**JSON** (JavaScript Object Notation) is a simple data interchange format. Syntactically it resembles the objects and lists of JavaScript. It is most commonly used for communication between web back-ends and JavaScript programs running in the browser, but it is used in many other places, too. Its home page, json.org, provides a wonderfully clear and concise definition of the standard. \n\nWith the [json package](https://golang.org/pkg/encoding/json/) it's a snap to read and write **JSON** data from your Go programs.\n\n### Json Marshal Encode\n\nMarshal returns the JSON **encoding** of **v**.\n\nMarshal traverses the value v recursively. If an encountered value implements the Marshaler interface and is not a nil pointer, Marshal calls its MarshalJSON method to produce JSON. If no MarshalJSON method is present but the value implements encoding.TextMarshaler instead, Marshal calls its MarshalText method and encodes the result as a JSON string.\n\n```go\nfunc Marshal(v interface{}) ([]byte, error)\n```\n\nGiven the Go data structure, Message, \n\n```go\ntype ApiLogin struct {\n   Name  string `json:\"name\"`\n   Cpf   string `json:\"cpf\"`\n}\n```\n\nand an instance of Message \n\n```go\nm := ApiLogin{\"Jefferson\", \"033.343.434-89\"}\n```\n\nwe can marshal a JSON-encoded version of m using json.Marshal: \n\n```go\nb, err := json.Marshal(m)\n```\n\nIf all is well, err will be nil and b will be a []byte containing this JSON data: \n\n```go\nb == []byte(`{\"Name\":\"Lambda Man\",\"Cpf\":\"033.343.434-89\"}`)\n```\n\nCheck out the complete code:\n```go\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\ntype ApiLogin struct {\n\tName string `json:\"name\"`\n\tCpf  string `json:\"cpf\"`\n}\n\nfunc main() {\n\n\ta := ApiLogin{\"Jefferson\", \"033.343.434-89\"}\n\tfmt.Println(a)\n\n\tm, err := json.Marshal(a)\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\t// show bytes\n\tfmt.Println(m)\n\n\t// show string json\n\tfmt.Println(string(m))\n}\n```\n\nOutput:\n```bash\n{Jefferson 033.343.434-89}\n[123 34 110 97 109 101 34 58 34 74 101 102 102 \n101 114 115 111 110 34 44 34 99 112 102 34 58 \n34 48 51 51 46 51 52 51 46 52 51 52 45 56 57 34 125]\n{\"name\":\"Jefferson\",\"cpf\":\"033.343.434-89\"}\n```\n\n### Json MarshalIndent\n\nMarshalIndent is like Marshal but applies Indent to format the output. Each JSON element in the output will begin on a new line beginning with prefix followed by one or more copies of indent according to the indentation nesting. \n\n```go\nfunc MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)\n```\n\nExample:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\ntype ApiLogin struct {\n\tName string `json:\"name\"`\n\tCpf  string `json:\"cpf\"`\n}\n\nfunc main() {\n\n\ta := ApiLogin{\"Jefferson\", \"033.343.434-89\"}\n\t// improving output for json format viewing\n\tjson, err := json.MarshalIndent(a, \"\", \"\\t\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tfmt.Println(string(json))\n}\n```\n\nOutput:\n```bash\n{\n\t\"name\": \"Jefferson\",\n\t\"cpf\": \"033.343.434-89\"\n}\n```\n\n### Option Omitempty\n\nThe \"omitempty\" option specifies that the field should be omitted from the encoding if the field has an empty value, defined as false, 0, a nil pointer, a nil interface value, and any empty array, slice, map, or string. \n\n```go\n// Field appears in JSON as key \"login\".\nLogin string `json:\"login\"`\n\n// Field appears in JSON as key \"email\" and\n// the field is omitted from the object if its value is empty,\n// as defined above.\nEmail string `json:\"email,omitempty\"`\n\n// Field appears in JSON as key \"nick\" (the default), but\n// the field is skipped if empty.\n// Note the leading comma.\nNick string `json:\",omitempty\"`\n\n// Field is ignored by this package.\nLevel int `json:\"-\"`\n\n// Field appears in JSON as key \"-\".\nLastEmail string `json:\"-,\"`\n```\nLook at the example below:\n```go\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\ntype Login struct {\n\t// Field appears in JSON as key \"login\".\n\tLogin string `json:\"login\"`\n\n\t// Field appears in JSON as key \"email\" and\n\t// the field is omitted from the object if its value is empty,\n\t// as defined above.\n\tEmail string `json:\"email,omitempty\"`\n\n\t// Field appears in JSON as key \"nick\" (the default), but\n\t// the field is skipped if empty.\n\t// Note the leading comma.\n\tNick string `json:\",omitempty\"`\n\n\t// Field is ignored by this package.\n\tLevel int `json:\"-\"`\n\n\t// Field appears in JSON as key \"-\".\n\tLastEmail string `json:\"-,\"`\n}\n\nfunc main() {\n\n\tl := Login{Login: \"Austin\", Email: \"austin@go.com\", Nick: \n\t \"\", Level: 1000, LastEmail: \"austin@gmail.com\"}\n\tfmt.Println(l)\n\n\tm, err := json.Marshal(l)\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\n\tfmt.Println(string(m))\n}\n```\nOutput:\n```bash\n{Austin austin@go.com Aust 1000 austin@gmail.com}\n{\"login\":\"Austin\",\"email\":\"austin@go.com\",\"-\":\"austin@gmail.com\"}\n```\n\nOnly data structures that can be represented as valid JSON will be encoded:\n\n```bash\n- JSON objects only support strings as keys; to encode a Go map type it must be of \n  the form map[string]T (where T is any Go type supported by the json package).\n- Channel, complex, and function types cannot be encoded.\n- Cyclic data structures are not supported; they will cause Marshal to go into an infinite loop.\n- Pointers will be encoded as the values they point to (or 'null' if the pointer is nil).\n```\n\nThe json package only accesses the exported fields of struct types (those that begin with an uppercase letter). Therefore only the the exported fields of a struct will be present in the JSON output. \n\nIn this example we work with pointers to reference the struct within another struct, and another point is that we declare the struct within the struct itself.\nWith this we have different ways to initialize and fill the fields of our structs.\nLet's see how it works? Check out the example below.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\ntype Address struct {\n\tCity         string `json:\"city\"`\n\tNeighborhood string `json:\"neighborhood\"`\n\tZipcode      string `json:\"zipcode\"`\n}\n\ntype ApiLogin struct {\n\tName  string `json:\"name\"`\n\tCpf   string `json:\"cpf\"`\n\tLogin string `json:\"login\"`\n\tEmail string `json:\"email\"`\n\tAnd1  *struct {\n\t\tCity string\n\t}\n\n\tAnd2 *Address\n}\n\nfunc main() {\n\n\tapilogin1 := \u0026ApiLogin{Name: \"@jeffotoni\", Cpf: \"093.393.334-34\",\n\t\tAnd1: \u0026struct{ City string }{City: \"BH\"}, And2: \u0026Address{City: \"BH\"}}\n\t//m, err := json.Marshal(apilogin1)\n\tm, err := json.MarshalIndent(apilogin1, \"\", \"\\t\")\n\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\t//fmt.Println(\"apilogin1 initialized\")\n\t//fmt.Println(apilogin1)\n\n\t//fmt.Println(\"\\njson.Marshal returning bytes\")\n\t//fmt.Println(m)\n\n\tfmt.Println(\"\\njson.Marshal as string\")\n\tfmt.Println(string(m))\n}\n```\n\n```bash\njson.Marshal as string\n{\n\t\"name\": \"@jeffotoni\",\n\t\"cpf\": \"093.393.334-34\",\n\t\"login\": \"\",\n\t\"email\": \"\",\n\t\"And1\": {\n\t\t\"City\": \"BH\"\n\t},\n\t\"And2\": {\n\t\t\"city\": \"BH\",\n\t\t\"neighborhood\": \"\",\n\t\t\"zipcode\": \"\"\n\t}\n}\n```\n\nIn this other example we take a short excerpt from the json of an AWS SES service, it notifies via Json the Bounces of the sent emails, we are going to check the completion of our fields in the struct and transform them into json.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\nfunc main() {\n\n\ttype BouncedRecipients []struct {\n\t\tEmailAddress string `json:\"emailAddress\"`\n\t\tAction       string `json:\"action\"`\n\t\tStatus       string `json:\"status\"`\n\t\t//DiagnosticCode string `json:\"diagnosticCode\"`\n\t}\n\n\ttype Bounce struct {\n\t\tBounceType string `json:\"bounceType\"`\n\t\t//BounceSubType string    `json:\"bounceSubType\"`\n\t\t//Timestamp     time.Time `json:\"timestamp\"`\n\t\tBR BouncedRecipients\n\t}\n\n\ttype JsonMessage struct {\n\t\tNotificationType string `json:\"notificationType\"`\n\t\tB                Bounce\n\t\tFrom             []string `json:\"from\"`\n\t}\n\n\tl := \u0026JsonMessage{NotificationType: \"38733773737xxxx\",\n\t\tB: Bounce{BounceType: \"bounce type\",\n\t\t\tBR: BouncedRecipients{\n\t\t\t\t{\"devops@g.com\", \"permanet\", \"error\"}, {\"lambdaman@g.com\", \"complaint\", \"success\"}}},\n\t\tFrom: []string{\"from1@m.com\", \"from2@gm.com\"}}\n\n\tm, err := json.Marshal(l)\n\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\n\t//fmt.Println(\"\\033[1;40mlinkFetcher initialized\\033[0m\")\n\t//fmt.Println(l)\n\n\t//fmt.Println(\"\\n\\033[1;42mjson.Marshal returning bytes\\033[0m\")\n\t//fmt.Println(m)\n\n\tfmt.Println(\"\\n\\033[1;41mjson.Marshal as string\\033[0m\")\n\tfmt.Println(string(m))\n}\n```\n\nOutput:\n```bash\njson.Marshal as string\n{\n\t\"notificationType\": \"38733773737xxxx\",\n\t\"B\": {\n\t\t\"bounceType\": \"bounce type\",\n\t\t\"BR\": [\n\t\t\t{\n\t\t\t\t\"emailAddress\": \"devops@g.com\",\n\t\t\t\t\"action\": \"permanet\",\n\t\t\t\t\"status\": \"error\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"emailAddress\": \"lambdaman@g.com\",\n\t\t\t\t\"action\": \"complaint\",\n\t\t\t\t\"status\": \"success\"\n\t\t\t}\n\t\t]\n\t},\n\t\"from\": [\n\t\t\"from1@m.com\",\n\t\t\"from2@gm.com\"\n\t]\n}\n```\n\nIn the example below there is an entire field in lowercase, this field the **json.Marshal** function **will not be** able to do marshal, because the field initializes with the lowercase letter **\"myname\"**, so it works the first letter has that is **\"Myname\"**\nAnother legal point our struct is set to receive \"N\" values as an array of struct **v[]struct\"**\nAnd inside the struct we have a string-type field **\"[]string\"**.\ntoo cool is not? Let's see how we do the initialization and fill in the values, look at the code below.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n)\n\ntype linkResult []struct {\n\tBody   string   `json:\"body\"`\n\tUrls   []string `json:\"urls\"`\n\tmyname string   `json:\"myname\"`\n}\n\nfunc main() {\n\t\n\t// creating our struct\n\t// with some fields\n\t// interesting as [] string\n\t// and showing how to initialize them\n\tvar ll = linkResult{\n\t\t{\n\t\t\tBody:   \"The Go Programming Language\",\n\t\t\tUrls:   []string{\"https://golang.org/pkg/\", \"https://golang.org/cmd/\"},\n\t\t\tmyname: \"lambda man\",\n\t\t},\n\t\t{\n\t\t\tBody:   \"Package\",\n\t\t\tUrls:   []string{\"https://golang.org/\", \"https://golang.org/cmd/\", \"https://golang.org/pkg/fmt/\"},\n\t\t\tmyname: \"go_br in action\",\n\t\t}}\n\n\t//m0, err := json.Marshal(ll)\n\tm0, err := json.MarshalIndent(ll, \"\", \"\\t\")\n\n\tif err != nil {\n\t\tlog.Println(err)\n\t}\n\t//fmt.Println(\"linkFetcher initialized\")\n\t//fmt.Println(ll)\n\n\t//fmt.Println(\"\\njson.Marshal returning bytes\")\n\t//fmt.Println(m0)\n\n\tfmt.Println(\"\\njson.Marshal as string\")\n\tfmt.Println(string(m0))\n}\n```\n\nOutput:\n```bash\nlinkFetcher initialized\n[{The Go Programming Language [https://golang.org/pkg/ https://golang.org/cmd/] lambda man} {Package [https://golang.org/ https://golang.org/cmd/ https://golang.org/pkg/fmt/] go_br in action}]\n\njson.Marshal returning bytes\n[91 10 9 123 10 9 9 34 98 111 100 121 34 58 32 34 84 104 101 32 71 111 32 80 114 111 103 114 97 109 109 105 110 103 32 76 97 110 103 117 97 103 101 34 44 10 9 9 34 117 114 108 115 34 58 32 91 10 9 9 9 34 104 116 116 112 115 58 47 47 103 111 108 97 110 103 46 111 114 103 47 112 107 103 47 34 44 10 9 9 9 34 104 116 116 112 115 58 47 47 103 111 108 97 110 103 46 111 114 103 47 99 109 100 47 34 10 9 9 93 10 9 125 44 10 9 123 10 9 9 34 98 111 100 121 34 58 32 34 80 97 99 107 97 103 101 34 44 10 9 9 34 117 114 108 115 34 58 32 91 10 9 9 9 34 104 116 116 112 115 58 47 47 103 111 108 97 110 103 46 111 114 103 47 34 44 10 9 9 9 34 104 116 116 112 115 58 47 47 103 111 108 97 110 103 46 111 114 103 47 99 109 100 47 34 44 10 9 9 9 34 104 116 116 112 115 58 47 47 103 111 108 97 110 103 46 111 114 103 47 112 107 103 47 102 109 116 47 34 10 9 9 93 10 9 125 10 93]\n\njson.Marshal as string\n[\n\t{\n\t\t\"body\": \"The Go Programming Language\",\n\t\t\"urls\": [\n\t\t\t\"https://golang.org/pkg/\",\n\t\t\t\"https://golang.org/cmd/\"\n\t\t]\n\t},\n\t{\n\t\t\"body\": \"Package\",\n\t\t\"urls\": [\n\t\t\t\"https://golang.org/\",\n\t\t\t\"https://golang.org/cmd/\",\n\t\t\t\"https://golang.org/pkg/fmt/\"\n\t\t]\n\t}\n]\n```\n\n```go\npackage main\n\nimport (\n    \"encoding/json\"\n    \"fmt\"\n    \"log\"\n)\n\ntype crud struct {\n    Create   bool\n    Retrieve bool\n    Update   bool\n    Delete   bool\n}\n\ntype crudWithDetail struct {\n    crud\n    Detail bool\n}\n\ntype acceleration struct {\n    crudWithDetail\n    Participant crudWithDetail\n    Challenge   crudWithDetail\n}\n\ntype acl struct {\n    User         crud\n    Acceleration acceleration\n}\n\nfunc main() {\n\n    // on this boot we show exactly how it would be using non-embedded structs but all separated and making type of each one of them\n    // all initialization is more friendly, although having nesting between structs is much better if we have built structs ie\n    // structs being declared directly inside structs what they call embedded.\n\n    // Example embedded strcut would\n    // type my struct {\n    //    M struct {\n    //       Name string\n    //   }\n    // }\n\n    j := acl{\n        User: crud{Create: true, Retrieve: false, Update: false, Delete: true},\n        Acceleration: acceleration{\n            Participant:    crudWithDetail{Detail: true, crud: crud{Create: false, Retrieve: false, Update: true, Delete: false}},\n            Challenge:      crudWithDetail{Detail: false, crud: crud{Create: true, Retrieve: true, Update: true, Delete: false}},\n            crudWithDetail: crudWithDetail{Detail: false, crud: crud{Create: true, Retrieve: false, Update: true, Delete: false}}},\n    }\n\n    json, err := json.MarshalIndent(j, \"\", \"\\t\")\n    if err != nil {\n        log.Println(err)\n    }\n    fmt.Println(string(json))\n}\n```\n\nOutput:\n```bash\n{\n\t\"User\": {\n\t\t\"Create\": true,\n\t\t\"Retrieve\": false,\n\t\t\"Update\": false,\n\t\t\"Delete\": true\n\t},\n\t\"Acceleration\": {\n\t\t\"Create\": true,\n\t\t\"Retrieve\": false,\n\t\t\"Update\": true,\n\t\t\"Delete\": false,\n\t\t\"Detail\": false,\n\t\t\"Participant\": {\n\t\t\t\"Create\": false,\n\t\t\t\"Retrieve\": false,\n\t\t\t\"Update\": true,\n\t\t\t\"Delete\": false,\n\t\t\t\"Detail\": true\n\t\t},\n\t\t\"Challenge\": {\n\t\t\t\"Create\": true,\n\t\t\t\"Retrieve\": true,\n\t\t\t\"Update\": true,\n\t\t\t\"Delete\": false,\n\t\t\t\"Detail\": false\n\t\t}\n\t}\n}\n```\n\nLet's now present 3 ways to declare a map [string] interfaces {} inside a struct and generate a json of it all after initializing our struct.\n\nTake a look at the example below:\n```go\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\n// create type map\ntype body map[string]interface{}\n\n// struct Message\ntype Message struct {\n\tSubject  string                 `json:\"subject\"`\n\tTimeSent int64                  `json:\"sent\"`\n\tBody     body                   `json:\"body\"`  // embedded =\u003e Body of the type map[string]interface{}\n\tBody2    map[string]interface{} `json:\"body2\"` // Body of the type map[string]interface{}\n\tStatus   string                 `json:\"status\"`\n}\n\nfunc main() {\n\n\t// our interface map body\n\t// This map can be dynamic,\n\t// create types as needed, because the interface{}\n\t// is for this purpose, it creates dynamic types.\n\tb := body{\n\t\t\"Data\": body{\n\t\t\t\"login\":  \"jeffotoni\",\n\t\t\t\"level\":  1000,\n\t\t\t\"create\": true,\n\t\t}, \"Address\": body{\n\t\t\t\"City\": \"Jersey City\",\n\t\t\t\"Zip\":  \"34.566-333\",\n\t\t\t\"Fone\": body{\n\t\t\t\t\"fone1\": \"87-77047345\",\n\t\t\t\t\"fone2\": \"83-93483838\",\n\t\t\t},\n\t\t},\n\t}\n\n\t// create type\n\ttype out map[string]interface{}\n\n\t// a way to initialize the struct\n\t// and the map contained within the struct\n\ts := \u0026Message{\n\t\tSubject:  \"Test Struct to Map\",\n\t\tTimeSent: 345,\n\t\tBody:     b,\n\t\tBody2:    out{\"Instance\": \"c5.xlarge\", \"vCpu\": \"4\", \"Ecu\": \"16\", \"Mem\": \"8\"},\n\t\tStatus:   \"success\",\n\t}\n\tfmt.Println(s)\n\n\t// Another way to implement is to generate\n\t// the map interface {} inside the initialization\n\t// of the struture.\n\ts2 := \u0026Message{\n\t\tSubject:  \"Test Struct to Map\",\n\t\tTimeSent: 345,\n\t\tBody:     b,\n\t\tBody2:    map[string]interface{}{\"Instance\": \"c5.xlarge\", \"vCpu\": \"4\", \"Ecu\": \"16\", \"Mem\": \"8\"},\n\t\tStatus:   \"success\",\n\t}\n\tfmt.Println(s2)\n\n\t// converting everything to Json\n\tm, err := json.Marshal(s2)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\t// sending json to the screen\n\tfmt.Println(\"##### json\")\n\tfmt.Println(string(m))\n}\n``` \n\nOutput:\n```bash\n\u0026{Test Struct to Map 345 map[Data:map[create:true login:jeffotoni level:1000] Address:map[City:Jersey City Zip:34.566-333 Fone:map[fone1:87-77047345 fone2:83-93483838]]] map[Instance:c5.xlarge vCpu:4 Ecu:16 Mem:8] success}\n\u0026{Test Struct to Map 345 map[Data:map[login:jeffotoni level:1000 create:true] Address:map[City:Jersey City Zip:34.566-333 Fone:map[fone1:87-77047345 fone2:83-93483838]]] map[Ecu:16 Mem:8 Instance:c5.xlarge vCpu:4] success}\n##### json\n{\n\t\"subject\": \"Test Struct to Map\",\n\t\"sent\": 345,\n\t\"body\": {\n\t\t\"Address\": {\n\t\t\t\"City\": \"Jersey City\",\n\t\t\t\"Fone\": {\n\t\t\t\t\"fone1\": \"87-77047345\",\n\t\t\t\t\"fone2\": \"83-93483838\"\n\t\t\t},\n\t\t\t\"Zip\": \"34.566-333\"\n\t\t},\n\t\t\"Data\": {\n\t\t\t\"create\": true,\n\t\t\t\"level\": 1000,\n\t\t\t\"login\": \"jeffotoni\"\n\t\t}\n\t},\n\t\"body2\": {\n\t\t\"Ecu\": \"16\",\n\t\t\"Instance\": \"c5.xlarge\",\n\t\t\"Mem\": \"8\",\n\t\t\"vCpu\": \"4\"\n\t},\n\t\"status\": \"success\"\n}\n```\n\n### Initialized Collections Of Data\n\nSome ways to anonymously declare and initialize types and collections of types in marshal to transform into Json.\n\nTake a look at the example below:\n```go\nfunc main() {\n\n    // let's try something simple\n    // to understand what's\n    // really going on\n    m, _ := json.Marshal(false)\n    fmt.Println(m)         // show as bytes\n    fmt.Println(string(m)) // show as string\n\n    m2, _ := json.Marshal(-1)\n    fmt.Println(string(m2))\n\n    m3, _ := json.Marshal(0)\n    fmt.Println(string(m3))\n\n    m4, _ := json.Marshal(102.3)\n    fmt.Println(string(m4))\n\n    m5, _ := json.Marshal(\"DevOpsBH\")\n    fmt.Println(string(m5))\n\n    // For this to occur we need to pass a collection\n    // with fields, something like a struct, a slice,\n    // maps, interfaces {} Let's see below an example\n    m6, _ := json.Marshal([...]string{\"Elixir\", \"Scala\"})\n    fmt.Println(string(m6))\n\n    m7, _ := json.Marshal(map[string]string{\"twitter\": \"@jeffotoni\"})\n    fmt.Println(string(m7))\n\n    m8, _ := json.Marshal(map[string]interface{}{\"instagram\": \"jeffotoni\", \"langs\": struct{ G string }{G: \"gophers\"}})\n    fmt.Println(string(m8))\n\n    m9, _ := json.Marshal(map[string]struct{ L string }{\"jeff\": {L: \"@Ricardo Maraschini\"}})\n    fmt.Println(string(m9))\n}\n```\n\nOutput:\n```bash\n```\n### Json NewEncoder\n\nNewEncoder returns a new encoder that writes to w. \n\n```go\nfunc NewEncoder(w io.Writer) *Encoder\n```\n\nWith this function we can implement our own custom Marshal function\n\nCheck out the example below:\n```go\n\npackage main\n\nimport (\n    \"bytes\"\n    \"encoding/json\"\n    \"fmt\"\n)\n\nconst (\n    empty = \"\"\n    tab   = \"\\t\"\n)\n\nfunc main() {\n\n    //json, err := MyJson(map[string]string{\"twitter\": \"@jeffotoni\"})\n    json, err := MyJson(map[string]interface{}{\"instagram\": \"jeffotoni\", \"langs\": struct{ G string }{G: \"gophers\"}})\n\n    if err != nil {\n        fmt.Println(err)\n    }\n\n    fmt.Println(json)\n}\n\nfunc MyJson(data interface{}) (string, error) {\n    buffer := new(bytes.Buffer)\n    encoder := json.NewEncoder(buffer)\n    encoder.SetIndent(empty, tab)\n    // encode...\n    err := encoder.Encode(data)\n    if err != nil {\n        return empty, err\n    }\n    return buffer.String(), nil\n}\n```\n\nOutput:\n```\n{\n\t\"instagram\": \"jeffotoni\",\n\t\"langs\": {\n\t\t\"G\": \"gophers\"\n\t}\n}\n```\nThe above example shows the use of the json.NewEncoder () function. Encode () to transform the data collection into JSON, very cool, right?\n\n\n### Json Unmarshal Decode\n\nUnmarshal parses the JSON-encoded data and stores the result in the value pointed to by v. If v is nil or not a pointer, Unmarshal returns an \"InvalidUnmarshalError\".\n\nUnmarshal uses the inverse of the encodings that Marshal uses, allocating maps, slices, and pointers as necessary, with the following additional rules:\n\nTo unmarshal JSON into a pointer, Unmarshal first handles the case of the JSON being the JSON literal null. In that case, Unmarshal sets the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into the value pointed at by the pointer. If the pointer is nil, Unmarshal allocates a new value for it to point to.\n\nTo unmarshal JSON into a value implementing the Unmarshaler interface, Unmarshal calls that value's UnmarshalJSON method, including when the input is a JSON null. Otherwise, if the value implements encoding.TextUnmarshaler and the input is a JSON quoted string, Unmarshal calls that value's UnmarshalText method with the unquoted form of the string.\n\nTo unmarshal JSON into a struct, Unmarshal matches incoming object keys to the keys used by Marshal (either the struct field name or its tag), preferring an exact match but also accepting a case-insensitive match. By default, object keys which don't have a corresponding struct field are ignored (see Decoder.DisallowUnknownFields for an alternative).\n\nTo unmarshal a JSON array into a slice, Unmarshal resets the slice length to zero and then appends each element to the slice. As a special case, to unmarshal an empty JSON array into a slice, Unmarshal replaces the slice with a new empty slice. \n\nConsider this JSON data, stored in the variable b: \n\n ```go\nb := []byte(`{\"Name\":\"DevOps\",\"Age\":10,\"Parents\":[\"Google\",\"Aws\"]}`)\n ```\n\nWithout knowing this data's structure, we can decode it into an interface{} value with Unmarshal:\n\n```go\nvar f interface{}\nerr := json.Unmarshal(b, \u0026f)\n```\n\nTo unmarshal JSON into an interface value, Unmarshal stores one of these in the interface value:\n\n```go\nbool, for JSON booleans\nfloat64, for JSON numbers\nstring, for JSON strings\n[]interface{}, for JSON arrays\nmap[string]interface{}, for JSON objects\nnil for JSON null\n```\n\nAll of the content below has been described and created examples using unmarshal with interfaces {} which is one of the most complex ways of handling a value that we do not know the type they can be born dynamically, and for this we need to understand a little more how interfaces { } and how to do type assertions in Go.\n\nSoon after we will return in unmarshal using structs.\n\n### Generic JSON with Interface{} and Assertion\n\nThe interface{} (empty interface) type describes an interface with zero methods. Every Go type implements at least zero methods and therefore satisfies the empty interface.\n\nThe empty interface serves as a general container type:\n\n```go\nvar i interface{}\ni = \"DevOps BH\"\ni = 2019\ni = 9.5\n```\n\nA type assertion accesses the underlying concrete type: \n\n```go\nr := i.(float64)\nfmt.Println(\"the circle's area\", math.Pi*r*r)\n```\n\nOr, if the underlying type is unknown, a type switch determines the type: \n\n```go\nswitch v := i.(type) {\ncase int:\n    fmt.Println(\"twice i is\", v*2)\ncase float64:\n    fmt.Println(\"the reciprocal of i is\", 1/v)\ncase string:\n    h := len(v) / 2\n    fmt.Println(\"i swapped by halves is\", v[h:]+v[:h])\ndefault:\n    // i isn't one of the types above\n}\n```\n\nThe code below was perfect for us to understand, and to know how we make insertions using Golang.\n\nExample:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar i interface{} = \"DevOpsBh\"\n\n\ts := i.(string)\n\tfmt.Println(s)\n\n\ts, ok := i.(string)\n\tfmt.Println(s, ok)\n\n\tf, ok := i.(float64)\n\tfmt.Println(f, ok)\n\n\t// f = i.(float64) // panic\n\t// fmt.Println(f)\n}\n```\n\nOutput:\n```bash\nDevOpsBh\nDevOpsBh true\n0 false\n```\n\n**Type Switches**\n\nA type switch is a construct that permits several type assertions in series.\nA type switch is like a regular switch statement, but the cases in a type switch specify types (not values), and those values are compared against the type of the value held by the given interface value.\n\n```bash\nswitch v := i.(type) {\ncase T:\n    // here v has type T\ncase S:\n    // here v has type S\ndefault:\n    // no match; here v has the same type as i\n}\n```\nThe declaration in a type switch has the same syntax as a type assertion i.(T), but the specific type T is replaced with the keyword type. \n\nCheck out the code below:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc doInterface(i interface{}) {\n\tswitch v := i.(type) {\n\tcase int:\n\t\tfmt.Printf(\"Twice %v is %v\\n\", v, v*2)\n\tcase string:\n\t\tfmt.Printf(\"%q is %v bytes long\\n\", v, len(v))\n\tdefault:\n\t\tfmt.Printf(\"I don't know about type %T!\\n\", v)\n\t}\n}\n\nfunc main() {\n\tdoInterface(33)\n\tdoInterface(\"DevOpsBH\")\n\tdoInterface(\"Lambda\")\n\tdoInterface(true)\n}\n```\n\nOutput:\n```bash\nTwice 33 is 66\n\"DevOpsBH\" is 8 bytes long\n\"Lambda\" is 6 bytes long\nI don't know about type bool!\n```\n\nThe code below will initialize the interface causing it to receive several different types.\n\nCheck out all the code below:\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tvar i interface{}\n\tfmt.Println(i)\n\n\ti = \"DevOps BH\"\n\tfmt.Println(i)\n\n\ti = 2019\n\tfmt.Println(i)\n\n\ti = 9.5\n\tfmt.Println(i)\n\n\ti = [...]string{\"Pike\", \"Jeffotoni\", \"Thompson\", \"Griesemer\"}\n\tfmt.Println(i)\n\n\ti = map[string]interface{}{\"Lang\": []string{\"Go\", \"Rust\", \"Scala\", \"Elixir\"}}\n\tfmt.Println(i)\n\n\t//struct{ City string }{City: \"BH\"}\n\ti = map[struct{ L string }]interface{}{{L: \"Lang\"}: []string{\"Go\", \"Rust\", \"Scala\", \"Elixir\"}}\n\tfmt.Println(i)\n}\n```\n\nOutput:\n```bash\n\u003cnil\u003e\nDevOps BH\n2019\n9.5\n[Pike Jeffotoni Thompson Griesemer]\nmap[Lang:[Go Rust Scala Elixir]]\nmap[{Lang}:[Go Rust Scala Elixir]]\n```\nIt is noticed that the interface created accepted all the types that was passed to it, was created dynamically.\n\n**Syntax of Type Assertion is Defined as:** \n\n```go\nPrimaryExpression.(Type)\n```\n\nAt this point the Go value in f would be a map whose keys are strings and whose values are themselves stored as empty interface values: \n\n```go\nf = map[string]interface{}{\n    \"Name\": \"DevOps\",\n    \"Age\":  10,\n    \"Parents\": []interface{}{\n        \"Google\",\n        \"Aws\",\n    },\n}\n```\n\nTo access this data we can use a type assertion to access f's underlying map[string]interface{}: \n\n```go\nm := f.(map[string]interface{})\n```\n\nWe can then iterate through the map with a range statement and use a type switch to access its values as their concrete types: \n\n```go\nfor k, v := range m {\n    switch vv := v.(type) {\n    case string:\n        fmt.Println(k, \"is string\", vv)\n    case float64:\n        fmt.Println(k, \"is float64\", vv)\n    case []interface{}:\n        fmt.Println(k, \"is an array:\")\n        for i, u := range vv {\n            fmt.Println(i, u)\n        }\n    default:\n        fmt.Println(k, \"is of a type I don't know how to handle\")\n    }\n}\n```\n\nIn this way you can work with unknown JSON data while still enjoying the benefits of type safety.\n\nSee full code below:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc main() {\n\n\tb := []byte(`{\"Name\":\"DevOps\",\"Age\":10,\"Company\":[\"Google\",\"Aws\"]}`)\n\n\tvar f interface{}\n\tif err := json.Unmarshal(b, \u0026f); err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tfmt.Println(f)\n\n\tm := f.(map[string]interface{})\n\tfor k, v := range m {\n\t\tswitch vv := v.(type) {\n\t\tcase string:\n\t\t\tfmt.Println(k, \"is string\", vv)\n\t\tcase float64:\n\t\t\tfmt.Println(k, \"is float64\", vv)\n\t\tcase []interface{}:\n\t\t\tfmt.Println(k, \"is an array:\")\n\t\t\tfor i, u := range vv {\n\t\t\t\tfmt.Println(i, u)\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Println(k, \"is of a type I don't know how to handle\")\n\t\t}\n\t}\n\t//fmt.Println()\n}\n```\n\n```bash\nmap[Name:DevOps Age:10 Company:[Google Aws]]\nName is string DevOps\nAge is float64 10\nCompany is an array:\n0 Google\n1 Aws\n```\n\nWhen we work with empty interfaces, we have to do asserts, so we can use them and treat them correctly, because in Golang everything is static and typed, if we do not assert we will not be able to capture the values of types that are in the interface that can be any type.\n\nCheck the code below:\n```go\n\tcase string:\n\t// ..\n\tcase float64:\n\t// ..\n\tcase [] interface {}:\n\t// ..\n\tcase int:\n\t// ..\n\tcase bool:\n\t// ..\n\tcase map[string]interface{}:\n```\n\n### Dynamic Type\n\nBesides static type that all variables have (it’s a type from variable’s declaration), variables of interface type also have a dynamic type. It’s a type of value currently set in interface type variable. Over the course of program execution variable of interface type has the same static type but its dynamic type can change as different values implementing desired interface will be assigned:\n\nCheck out the example:\n```go\npackage main\n\nimport \"fmt\"\n\ntype I interface {\n\tcomeon()\n}\n\ntype A struct{}\n\nfunc (a A) comeon() {}\n\ntype B struct{}\n\nfunc (b B) comeon() {}\n\nfunc main() {\n\tvar i I\n\ti = A{} // dynamic type of i is A\n\tfmt.Printf(\"%T\\n\", i.(A))\n\ti = B{} // dynamic type of i is B\n\tfmt.Printf(\"%T\\n\", i.(B))\n}\n```\n\n```bash\nmain.A\nmain.B\n```\n\n### What is Reflection\n\nReflection is the ability of a program to inspect its variables and values at run time and find their type. You might not understand what this means but that's alright. You will get a clear understanding of reflection by the end of this section, so stay with me.\n\nReflection is a very powerful and advanced concept in Go and it should be used with care. It is very difficult to write clear and maintainable code using reflection. It should be avoided wherever possible and should be used only when absolutely necessary.\n\nThis is very powerful, we managed to sweep our entire struct using asserts and reflect, we got the name of the struct, name of the fields, their values, their tags, this feature is used to do Parse in Files, like Yaml, Toml, Json etc ......\n\n\nCheck the code below:\n```go\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc main() {\n\n\tb := []byte(`{\"Name\":\"Pike Hob\",\"Age\":56,\"Parents\":[\"Denis\",\"James\"]}`)\n\tvar f interface{}\n\t_ = json.Unmarshal(b, \u0026f)\n\n\tm := f.(map[string]interface{})\n\n\t// a way to initialize a map interface\n\t////////////////////////////////////////\n\n\t// f = map[string]interface{}{\n\t// \t\"Name\": \"Wednesday\",\n\t// \t\"Age\":  6,\n\t// \t\"Parents\": []interface{}{\n\t// \t\t\"Torvalds\",\n\t// \t\t\"Mark Zuckerberg\",\n\t// \t},\n\t// }\n\t/////////////////////////////////////\n\n\tfor k, v := range m {\n\t\tswitch vv := v.(type) {\n\t\tcase string:\n\t\t\tfmt.Println(k, \"|is string|\", vv)\n\t\tcase float64:\n\t\t\tfmt.Println(k, \"|is float64|\", vv)\n\t\tcase []interface{}:\n\t\t\tfmt.Println(k, \"|is an array|\")\n\t\t\tfor i, u := range vv {\n\t\t\t\tfmt.Println(i, u)\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Println(k, \"is of a type I don't know how to handle\")\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\nAge |is float64| 56\nParents |is an array|\n0 Denis\n1 James\nName |is string| Pike Hob\n```\n\nLet's take another example when using Unmarshal in Interfaces{}\nExample:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc main() {\n\t// map more interface\n\tinput := map[string]interface{}{\n\t\t\"Key1\": []string{\"some\", \"key\"},\n\t\t\"key3\": nil,\n\t\t\"val\":  2,\n\t\t\"val2\": \"str\",\n\t\t\"val3\": 4,\n\t}\n\n\tfmt.Println(input)\n\tfor key, value := range input {\n\t\tslice, ok := value.([]string)\n\t\tif ok {\n\t\t\tinput[\"Count\"+key] = len(slice)\n\t\t}\n\t}\n\tfmt.Println(input)\n\n\t// Encode to Json\n\tm, err := json.Marshal(input)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\t// convert byte to string\n\tfmt.Println(string(m))\n\n\t// interface empty\n\tvar f interface{}\n\n\t// Decode json\n\tif err := json.Unmarshal(m, \u0026f); err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\t// show screen\n\tfmt.Println(f)\n\n\tfmt.Println(\"### loop interface\")\n\tm2 := f.(map[string]interface{})\n\tloopI(m2)\n}\n\n// loop in interface\nfunc loopI(m2 map[string]interface{}) {\n\tfor k, v := range m2 {\n\n\t\t// assert interface\n\t\tswitch vv := v.(type) {\n\t\tcase string:\n\t\t\tfmt.Println(k, \"is string\", vv)\n\t\tcase float64:\n\t\t\tfmt.Println(k, \"is float64\", vv)\n\t\tcase []interface{}:\n\t\t\tfmt.Println(k, \"is an array:\")\n\t\t\tfor i, u := range vv {\n\t\t\t\tfmt.Println(i, u)\n\t\t\t}\n\t\tdefault:\n\t\t\tfmt.Println(k, \"is of a type I don't know how to handle\")\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\nmap[key3:\u003cnil\u003e Key1:[some key] val:2 val2:str val3:4]\nmap[key3:\u003cnil\u003e Key1:[some key] val:2 val2:str val3:4 CountKey1:2]\n{\"CountKey1\":2,\"Key1\":[\"some\",\"key\"],\"key3\":null,\"val\":2,\"val2\":\"str\",\"val3\":4}\nmap[CountKey1:2 Key1:[some key] key3:\u003cnil\u003e val:2 val2:str val3:4]\n### loop interface\nKey1 is an array:\n0 some\n1 key\nkey3 is of a type I don't know how to handle\nval is float64 2\nval2 is string str\nval3 is float64 4\nCountKey1 is float64 2\n```\n\n### Making Reflect with Struct\n\nThe example below clearly shows how we would do a reflect in a struct in a simple way.\nWe were able to sweep the struct at element level, we get the Struct Name, the Field Name the field types, the tags in the fields and their values when they are filled. Phew, a lot of cool stuff there.\n\nLet's see the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\ntype User struct {\n\tFirstName string `tag_name:\"firstname\"`\n\tLastName  string `tag_name:\"lastname\"`\n\tAge       int    `tag_name:\"age\"`\n}\n\nfunc (f *User) reflect() {\n\n\t// slice the element of struct\n\tval := reflect.ValueOf(f).Elem()\n\n\t// loop in elemnts of struct\n\tfor i := 0; i \u003c val.NumField(); i++ {\n\n\t\t// value of interface\n\t\tvalueField := val.Field(i)\n\n\t\t// object of struct\n\t\ttypeField := val.Type().Field(i)\n\n\t\t// tag of field\n\t\ttag := typeField.Tag\n\t\tfmt.Printf(\"Field Name: %s,\\t Field Value: %v,\\t Tag Value: %s\\n\", typeField.Name, valueField.Interface(), tag.Get(\"tag_name\"))\n\t}\n}\n\nfunc main() {\n\n\tf := \u0026User{\n\t\tFirstName: \"Jefferson\",\n\t\tLastName:  \"Otoni\",\n\t\tAge:       350,\n\t}\n\n\tf.reflect()\n}\n```\n\nOutput:\n```bash\nField Name: FirstName,\t Field Value: Jefferson,\t Tag Value: firstname\nField Name: LastName,\t Field Value: Otoni,\t Tag Value: lastname\nField Name: Age,\t Field Value: 350,\t Tag Value: age\n```\n\nLet's see how we would do an array dump using reflect.\n\nCheck out the complete code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"reflect\"\n)\n\nfunc dump_interface_array(args interface{}) {\n\n\t// getting the interface\n\tval := reflect.ValueOf(args)\n\n\t// test the type\n\tif val.Kind() == reflect.Array {\n\t\tfmt.Println(\"len = \", val.Len())\n\t\tfor i := 0; i \u003c val.Len(); i++ {\n\t\t\te := val.Index(i)\n\t\t\tswitch e.Kind() {\n\t\t\tcase reflect.Int:\n\t\t\t\tfmt.Printf(\"%v, \", e.Int())\n\t\t\tcase reflect.Float32:\n\t\t\t\tfallthrough\n\t\t\tcase reflect.Float64:\n\t\t\t\tfmt.Printf(\"%v, \", e.Float())\n\t\t\tcase reflect.String:\n\t\t\t\tfmt.Printf(\"%v, \", e.String())\n\t\t\tdefault:\n\t\t\t\tpanic(fmt.Sprintf(\"invalid Kind: %v\", e.Kind()))\n\t\t\t}\n\t\t}\n\t\tfmt.Println()\n\t}\n}\n\nfunc main() {\n\n\t// array int\n\tint_ary := [4]int{1, 2, 3, 4}\n\n\t// array float\n\tfloat32_ary := [4]float32{1.1, 2.2, 3.3, 4.4}\n\n\t// array float\n\tfloat64_ary := [4]float64{1.1, 2.2, 3.3, 4.4}\n\n\t// array string\n\tstring_ary := [...]string{\"Scala\", \"Elixir\", \"Lisp\", \"Clojure\"}\n\n\tdump_interface_array(int_ary)\n\tdump_interface_array(float32_ary)\n\tdump_interface_array(float64_ary)\n\tdump_interface_array(string_ary)\n}\n```\n\nOutput:\n```bash\nlen =  4\n1, 2, 3, 4,\nlen =  4\n1.100000023841858, 2.200000047683716, 3.299999952316284, 4.400000095367432, \nlen =  4\n1.1, 2.2, 3.3, 4.4, \nlen =  4\nScala, Elixir, Lisp, Clojure, \n```\n\nAnother way to sweep dynamic slices, cool, let's check.\n\nLook at the complete code:\n```go\npackage main\n\nimport \"fmt\"\nimport \"reflect\"\n\nfunc main() {\n\n\t// slice dinamic\n\tslice := []string{\"C\", \"C++\", \"Fortram\", \"Cobol\"}\n\tdump_slice(slice)\n\n\t// slice int\n\tdataint := []int{1, 2, 3}\n\tdump_slice(dataint)\n}\n\n// dump interfaces\nfunc dump_slice(t interface{}) {\n\n\t// type kind only slice\n\tswitch reflect.TypeOf(t).Kind() {\n\n\t// slice\n\tcase reflect.Slice:\n\n\t\t// return interface\n\t\ts := reflect.ValueOf(t)\n\n\t\t// loop in type\n\t\tfor i := 0; i \u003c s.Len(); i++ {\n\t\t\tfmt.Println(s.Index(i))\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\nC\nC++\nFortram\nCobol\n1\n2\n3\n```\n\nBelow we have an example doing some types of reflect, simple but for us to have a good idea of reflect power.\n\nLet's see the complete code below:\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"reflect\"\n)\n\nfunc main() {\n\n    // map interface\n    Schema := map[string]interface{}{}\n\n    // let's fill in the fields\n    Schema[\"int\"] = 10\n    Schema[\"string\"] = \"this is a string and map with interface\"\n    Schema[\"bool\"] = false\n    Schema[\"sliceString\"] = [...]string{\"C\", \"C++\", \"Lisp\"}\n\n    // interface\n    val := reflect.ValueOf(Schema)\n\n    // all data\n    fmt.Println(\"Schema\", val)\n\n    // type\n    fmt.Println(\"Type = \", val.Kind())\n\n    // kind type == reflect map\n    if val.Kind() == reflect.Map {\n        for _, key := range val.MapKeys() {\n            v := val.MapIndex(key)\n\n            // kind type, interface type\n            switch value := v.Interface().(type) {\n\n            // testing types\n            case int:\n                fmt.Println(key, value)\n            case string:\n                fmt.Println(key, value)\n            case bool:\n                fmt.Println(key, value)\n\n            // case map[string]string:\n\n            // case []interface{}:\n\n            // case map[string]interface{}:\n\n            default:\n                val2 := reflect.ValueOf(Schema[\"sliceString\"])\n                // type array\n                if val2.Kind() == reflect.Array {\n                    //fmt.Println(\"len = \", val2.Len())\n\n                    // loop array\n                    for i := 0; i \u003c val2.Len(); i++ {\n                        // index key\n                        e := val2.Index(i)\n\n                        // kind type\n                        switch e.Kind() {\n\n                        // case types\n                        case reflect.String:\n                            fmt.Printf(\"%v, \", e.String())\n\n                        //default\n                        default:\n                            panic(fmt.Sprintf(\"invalid Kind: %v\", e.Kind()))\n                        }\n                    }\n                    fmt.Println()\n                }\n            }\n        }\n    }\n}\n```\n\nOutput:\n```bash\nSchema map[int:10 string:this is a string and map with interface bool:false sliceString:[C C++ Lisp]]\nType =  map\nint 10\nstring this is a string and map with interface\nbool false\nC, C++, Lisp,\n```\n\nNow let's complicate it a bit, let's do a reflect read of a struct and transform it into a map.\nInside the struct we put a map of interfaces just to see how it would look.\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/url\"\n\t\"reflect\"\n\t\"strconv\"\n)\n\ntype address map[string]interface{}\n\ntype User struct {\n\tLogin   string  `json:\"login\"`\n\tEmail   string  `json:\"email\"`\n\tStatus  string  `json:\"status\"`\n\tAddress address `json:\"address\"`\n}\n\nfunc main() {\n\n\ta := address{\n\t\t\"Address\": address{\n\t\t\t\"City\": \"Belo Horizonte\",\n\t\t\t\"Zip\":  \"34.566-333\",\n\t\t\t\"Fone\": address{\n\t\t\t\t\"fone1\": \"87-77047345\",\n\t\t\t\t\"fone2\": \"83-93483838\",\n\t\t\t},\n\t\t},\n\t}\n\n\tuser := User{\n\t\tLogin:   \"jeffotoni\",\n\t\tEmail:   \"jeffotoni@gm.com\",\n\t\tStatus:  \"alive\",\n\t\tAddress: a,\n\t}\n\n\turlValues := structToMap(\u0026user)\n\tfmt.Println(urlValues)\n}\n\n// convert struct to map\nfunc structToMap(i interface{}) (values url.Values) {\n\tvalues = url.Values{}\n\tiVal := reflect.ValueOf(i).Elem()\n\ttyp := iVal.Type()\n\tfor i := 0; i \u003c iVal.NumField(); i++ {\n\t\tf := iVal.Field(i)\n\t\t// You ca use tags here...\n\t\t// tag := typ.Field(i).Tag.Get(\"tagname\")\n\t\t// Convert each type into a string for the url.Values string map\n\t\tvar v string\n\t\tswitch f.Interface().(type) {\n\t\tcase int, int8, int16, int32, int64:\n\t\t\tv = strconv.FormatInt(f.Int(), 10)\n\t\tcase uint, uint8, uint16, uint32, uint64:\n\t\t\tv = strconv.FormatUint(f.Uint(), 10)\n\t\tcase float32:\n\t\t\tv = strconv.FormatFloat(f.Float(), 'f', 4, 32)\n\t\tcase float64:\n\t\t\tv = strconv.FormatFloat(f.Float(), 'f', 4, 64)\n\t\tcase []byte:\n\t\t\tv = string(f.Bytes())\n\t\tcase string:\n\t\t\tv = f.String()\n\n\t\tdefault:\n\n\t\t\tswitch f.Kind() {\n\t\t\t// map\n\t\t\tcase reflect.Map:\n\t\t\t\tfor _, key := range f.MapKeys() {\n\t\t\t\t\tstrct := f.MapIndex(key)\n\t\t\t\t\t//fmt.Println(key.Interface(), strct.Interface())\n\t\t\t\t\tv = fmt.Sprintf(\"%v %v\", key.Interface(), strct.Interface())\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tvalues.Set(typ.Field(i).Name, v)\n\t}\n\treturn\n}\n```\n\nOutput:\n```bash\nmap[Login:[jeffotoni] Email:[jeffotoni@gm.com] Status:[alive] \nAddress:[Address map[City:Belo Horizonte Zip:34.566-333 \nFone:map[fone1:87-77047345 fone2:83-93483838]]]]\n```\n\n### Json Unmarshal Structs\n\nWe saw the most complex part of using Unmarshal in dynamic composites using interfaces {} and had to make assertions to capture the values.\nNow let's use Unmarshal in structures, in this scenario the structure is something static, it has to be always predefined.\n\nWhen we develop our API, we will realize that we will have to do Unmarshal and Marshal all the time of receiving and sending information using json.\n\nSo if we get angry at Unmarshal, Marshal, Interfaces {} and Structs, our APIs will be a little tricky to develop.\n\nLet's take a look at the code below that represents exactly the way we use Unmarshal with Structs.\n\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\ntype jsoninput []struct {\n\tName string `json:\"name\"`\n}\n\nfunc main() {\n\n\t// json in memory\n\t// this is an array of values\n\tresp := `[{\"name\":\"Andre\"},{\"name\":\"Pike\"}]`\n\n\t// initialization struct\n\tdata := \u0026jsoninput{}\n\n\t// Unmarshal in bytes\n\t_ = json.Unmarshal([]byte(resp), data)\n\n\t// loop to see the values in the fields\n\t// loop in struct\n\tfor _, value := range *data {\n\t\tfmt.Println(value.Name)\n\t}\n}\n```\n\nOutput:\n```bash\nAndre\nPike\n```\n\nExample:\n```go\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n)\n\nfunc main() {\n\n\t// byte with json\n\tvar jsonBlob = []byte(`[\n\t{\"Name\": \"Golang\", \"Level\": \"10\"},\n\t{\"Name\": \"Rust\",    \"Level\": \"7\"}\n]`)\n\n\t// struct that is our model\n\ttype Lang struct {\n\t\tName  string\n\t\tLevel string\n\t}\n\n\tvar langs []Lang\n\n\t// convert Json to Struct\n\terr := json.Unmarshal(jsonBlob, \u0026langs)\n\tif err != nil {\n\t\tfmt.Println(\"error:\", err)\n\t}\n\n\tfmt.Printf(\"\\n%+v\", langs)\n\tfmt.Printf(\"\\n%+v\", langs[0].Name)\n\tfmt.Printf(\"\\n%+v\", langs[0].Level)\n\tfmt.Printf(\"\\n%+v\", langs[1].Name)\n\tfmt.Printf(\"\\n%+v\", langs[1].Level)\n}\n```\n\nOutput:\n```bash\n[{Name:Golang Level:10} {Name:Rust Level:7}]\nGolang\n10\nRust\n7\n```\n\nIn other words, we get a string of bytes that is a Json and fill in the values of the struct with those elements.\nUsing the json.Unmarshal function, Fantastic it.\nIn other words, Json has to be compatible with the struct that is our model.\n\n### MarshalJSON and UnmarshalJSON\n\nThere is the possibility of customizing the native method of Marshal and Unmarshal, that is to override with other functionalities without changing their behavior as a whole, but to increase in the already existing method.\nVery cool this feature, I do not need to rewrite the whole method in yes add a behavior.\n\nFirst we create our struct with the fields we want to add the new rule as the example below:\n\n```go\ntype Email struct {\nEmail string\n}\n```\n\nSoon after the initialization of my struct where it feeds the information will receive this struct as parameter as the example below:\n\n```go\na: = struct {\nLogin string\nEmail\nTime Time\n}\n```\n\nReady now we simply implement our method always with the name **MarshalJSON** referencing this struct that we created **\"Email\"**.\n\n```go\nfunc (and Email) MarshalJSON () ([] byte, error) {\nreturn [] byte (fmt.Sprintf (`\"% s \"`, checkEmail (e.Email))), nil\n}\n```\n\nThe checkEmail function is a regular expression that we created to validate the email.\nReady when running the Marshal function it will icorporate this method that you implemented.\nSee the example below with the complete code.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"time\"\n)\n\ntype Email struct {\n\tEmail string\n}\n\ntype Time struct {\n\ttime.Time\n}\n\n// layout\nconst layout = \"2006-01-02\"\n\nvar regxmail = regexp.MustCompile(\"^[a-zA-Z0-9.!#$%\u0026'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$\")\n\nfunc (t Time) MarshalJSON() ([]byte, error) {\n\treturn []byte(fmt.Sprintf(`\"%s\"`, t.Time.Format(layout))), nil\n}\n\nfunc (e Email) MarshalJSON() ([]byte, error) {\n\treturn []byte(fmt.Sprintf(`\"%s\"`, checkEmail(e.Email))), nil\n}\n\nfunc checkEmail(email string) string {\n\tif regxmail.MatchString(email) {\n\t\treturn email\n\t} else {\n\t\treturn \"-invalid-\"\n\t}\n}\n\nfunc main() {\n\ta := struct {\n\t\tLogin string\n\t\tEmail Email\n\t\tTime  Time\n\t}{\n\t\tLogin: \"devops\",\n\t\tEmail: Email{\"jeffotoni-go.com\"},\n\t\tTime:  Time{time.Now()},\n\t}\n\n\tfmt.Println(a)\n\tjson, err := json.MarshalIndent(a, \"\", \"\\t\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\n\tfmt.Println(string(json))\n}\n```\n\nOutput:\n```bash\n{devops {jeffotoni-go.com} 2019-01-30 22:41:00.506602023 -0200 -02 m=+0.000508436}\n{\n\t\"Login\": \"devops\",\n\t\"Email\": \"-invalid-\",\n\t\"Time\": \"2019-01-30\"\n}\n```\n\nThe Unmarshal version is a little more complex, since we will need to scan the received structures. The email was added in a string map, to scan the field and add the functionality to validate the email.\n\nCheck out the complete code below.\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"regexp\"\n\t\"strings\"\n\t\"time\"\n)\n\ntype Email struct {\n\tEmail string\n}\n\ntype Time struct {\n\ttime.Time\n}\n\n// layout\nconst layout = \"2006-01-02\"\n\n// regex to email\nvar regxmail = regexp.MustCompile(\"^[a-zA-Z0-9.!#$%\u0026'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$\")\n\nfunc (t *Time) UnmarshalJSON(b []byte) (err error) {\n\tif b[0] == '\"' \u0026\u0026 b[len(b)-1] == '\"' {\n\t\tb = b[1 : len(b)-1]\n\t}\n\tif string(b) == `null` {\n\t\t*t = Time{}\n\t\treturn\n\t}\n\tt.Time, err = time.Parse(layout, string(b))\n\treturn\n}\n\n// Unmarshal Json\nfunc (t *Email) UnmarshalJSON(b []byte) (err error) {\n\tif b[0] == '\"' \u0026\u0026 b[len(b)-1] == '\"' {\n\t\tb = b[1 : len(b)-1]\n\t}\n\tif string(b) == `null` {\n\t\treturn\n\t}\n\tvar stuff map[string]string\n\terr = json.Unmarshal(b, \u0026stuff)\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor key, value := range stuff {\n\t\tif strings.ToLower(key) == \"email\" {\n\t\t\tt.Email = checkEmail(value)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc checkEmail(email string) string {\n\tif regxmail.MatchString(email) {\n\t\treturn email\n\t} else {\n\t\treturn \"-invalid-\"\n\t}\n}\n\nfunc main() {\n\ta := struct {\n\t\tLogin string\n\t\tEmail Email\n\t\tTime  Time\n\t}{}\n\n\tb := []byte(`{\"Login\":\"devops\",\"Email\":{\"Email\":\"devops-go.com\"},\"Time\":\"2019-01-30\"}`)\n\terr := json.Unmarshal(b, \u0026a)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(a)\n}\n```\n\nOutput:\n```bash\n{devops {-invalid-} 2019-01-30 00:00:00 +0000 UTC}\n```\n\n### Parse Json\n---\n\n###  Reading and Parsing a JSON File\n\nLet's do parse in Json file, there are several libs to do this, let's create our own, simple to understand the whole process and of course get mad at Parse.\n\nThe file below is saved in the folder **parsejson** and we will create our parse within this directory.\n\n```json\n{\n  \"users\": [\n    {\n      \"name\" : \"Devopsbh\",\n      \"type\" : \"Reader\",\n      \"age\" : 29,\n      \"social\" : {\n        \"facebook\" : \"https://facebook.com/devopsbh\",\n        \"twitter\" : \"https://twitter.com/devopsbh\",\n        \"instagram\" : \"https://instagram.com/devopsbh\"\n      }\n    },\n    {\n      \"name\" : \"Jefferson\",\n      \"type\" : \"Author\",\n      \"age\" : 160,\n      \"social\" : {\n        \"facebook\" : \"https://facebook.com/jeffotoni\",\n        \"twitter\" : \"https://twitter.com/jeffotoni\"\n        \"instagram\" : \"https://instagram.com/jeffotoni\"\n      }\n    }\n  ]\n}\n```\n\nWe'll be using the packages in order to open up our users.json file from our filesystem. Once we have opened the file, we'll defer the closing of the file to the end of the function so that we can work with the data inside of it.\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n)\n\nfunc main() {\n\t//fmt.Println(os.Getwd())\n\t// Open our jsonFile\n\tjsonFile, err := os.Open(\"./users.json\")\n\n\t// if we os.Open returns an error then handle it\n\tif err != nil {\n\t\tfmt.Println(err)\n\t}\n\tfmt.Println(\"Successfully Opened users.json\")\n\t// defer the closing of our jsonFile so that we can parse it later on\n\tdefer jsonFile.Close()\n}\n```\n\n### Parsing with Structs\t\n\nWe have a few options when it comes to parsing the JSON that is contained within our users.json file. We could either unmarshal the JSON using a set of predefined structs, or we could unmarshal the JSON using a map[string]interface{} to parse our JSON into strings mapped against arbitrary data types.\n\nIf you know the structure that you are expecting then I would recommend going down the verbose route and defining your structs like so:\n\n```go\npackage main\n\nfunc main() {\n\t// Users struct which contains\n\t// an array of users\n\ttype Users struct {\n\t\tUsers []User `json:\"users\"`\n\t}\n\n\t// Social struct which contains a\n\t// list of links\n\ttype Social struct {\n\t\tFacebook string `json:\"facebook\"`\n\t\tTwitter  string `json:\"twitter\"`\n\t\tInstagram  string `json:\"instagram\"`\n\t}\n\n\t// User struct which contains a name\n\t// a type and a list of social links\n\ttype User struct {\n\t\tName   string `json:\"name\"`\n\t\tType   string `json:\"type\"`\n\t\tAge    int    `json:\"Age\"`\n\t\tSocial Social `json:\"social\"`\n\t}\n}\n```\n\nOnce we have these in place, we can use them to unmarshal our JSON.\nUnmarshalling our JSON - Once we’ve used the os.Open function to read our file into memory, we then have to convert it toa byte array using ioutil.ReadAll. Once it’s in a byte array we can pass it to our json.Unmarshal() method.\n\nRemember if the json file is a wrong comma, it will not convert the file to json format that has it right.\nNow you can check the code below.\n\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"strconv\"\n)\n\n// Users struct which contains\n// an array of users\ntype Users struct {\n\tUsers []User `json:\"users\"`\n}\n\n// Social struct which contains a\n// list of links\ntype Social struct {\n\tFacebook  string `json:\"facebook\"`\n\tTwitter   string `json:\"twitter\"`\n\tInstagram string `json:\"instagram\"`\n}\n\n// User struct which contains a name\n// a type and a list of social links\ntype User struct {\n\tName   string `json:\"name\"`\n\tType   string `json:\"type\"`\n\tAge    int    `json:\"Age\"`\n\tSocial Social `json:\"social\"`\n}\n\nfunc main() {\n\n\t//fmt.Println(os.Getwd())\n\t// Open our jsonFile\n\tjsonFile, err := os.Open(\"./users.json\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tdefer jsonFile.Close()\n\n\t// read our opened xmlFile as a byte array.\n\tbyteValue, _ := ioutil.ReadAll(jsonFile)\n\n\t// show json\n\tfmt.Println(string(byteValue))\n\n\t// we initialize our Users array\n\tvar users Users\n\n\t// we unmarshal our byteArray which contains our\n\t// jsonFile's content into 'users' which we defined above\n\tjson.Unmarshal(byteValue, \u0026users)\n\n\tfmt.Println(users)\n\n\t// we iterate through every user within our users array and\n\t// print out the user Type, their name, and their facebook url\n\t// as just an example\n\tfor i := 0; i \u003c len(users.Users); i++ {\n\t\tfmt.Println(\"User Type: \" + users.Users[i].Type)\n\t\tfmt.Println(\"User Age: \" + strconv.Itoa(users.Users[i].Age))\n\t\tfmt.Println(\"User Name: \" + users.Users[i].Name)\n\t\tfmt.Println(\"Facebook Url: \" + users.Users[i].Social.Facebook)\n\t\tfmt.Println(\"Twitter Url: \" + users.Users[i].Social.Twitter)\n\t\tfmt.Println(\"Instagram Url: \" + users.Users[i].Social.Instagram)\n\t}\n}\n```\n\nOutput:\n```bash\n{[{Devopsbh Reader 29 {https://facebook.com/devopsbh https://twitter.com/devopsbh https://instagram.com/devopsbh}} {Jefferson Author 160 {https://facebook.com/jeffotoni https://twitter.com/jeffotoni https://instagram.com/jeffotoni}}]}\nUser Type: Reader\nUser Age: 29\nUser Name: Devopsbh\nFacebook Url: https://facebook.com/devopsbh\nTwitter Url: https://twitter.com/devopsbh\nInstagram Url: https://instagram.com/devopsbh\nUser Type: Author\nUser Age: 160\nUser Name: Jefferson\nFacebook Url: https://facebook.com/jeffotoni\nTwitter Url: https://twitter.com/jeffotoni\nInstagram Url: https://instagram.com/jeffotoni\n```\n### Parsing with Map and Interface\n\nSometimes, going through the process of creating structs for everything can be somewhat time consuming and overly verbose for the problems you are trying to solve. In this instance, we can use standard interfaces{} in order to read in any JSON data:\n\nFormat Json Example:\n\n```json\n{\n  \"name\" : \"Devopsbh\",\n  \"city\" : \"Belo Horizonte\",\n  \"age\" : 29\n}\n```\n\n**How can we do Unmarshal in this file and access the fields?**\n\nWhen we read json and do the parse, there are several boring points we have to deal with, and an excellent strategy is to divide to conquer. The above example is an arrayless json with no complexity, a json in its simplest possible format.\n\nOur Unmarshal received **var result map[string]interface{}** to be able to play all the data in an interface map so we have something dynamic without having to define the fields the interface makes the magic of accepting any type.\nIn this example we have no problem in directly accessing the map fields, in json format we have the keys and values and ready we can direct access.\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\t// Open our jsonFile\n\tbyteJson, err := ioutil.ReadFile(\"./user-only-0.json\")\n\n\t// if we os.Open returns an error then handle it\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\t// show screen\n\tfmt.Println(\"Successfully Opened users.json\")\n\n\t// defining the interface map that will receive\n\t// the file and the format is dynamic\n\tvar result = make(map[string]interface{})\n\n\t// let's now run our Unmarshal and convert to objects\n\tjson.Unmarshal(byteJson, \u0026result)\n\n\t// show all\n\tfmt.Println(result)\n\n\t// how is a map I can do exactly\n\t// the syntax below\n\tval, ok := result[\"name\"].(string)\n\tfmt.Println(val, ok)\n\n\t// type string\n\tfmt.Println(result[\"name\"].(string))\n\n\t// type string\n\tfmt.Println(result[\"city\"].(string))\n\n\t// type float64\n\tfmt.Println(result[\"age\"].(float64))\n}\n```\n\nOutput:\n```bash\nSuccessfully Opened users.json\nmap[age:3 name:Devopsbh city:Belo Horizonte]\nDevopsbh true\nDevopsbh\nBelo Horizonte\n3\n```\n\nNow let's complicate our Json file a bit, let's put an Array of users and let's see how we should proceed to access the keys and values of this Json.\n\n```json\n{\n  \"users\":\n  [\n    {\n    \"name\" : \"Andre Almar\",\n    \"type\" : \"knowledge\",\n    \"age\" : 25,\n    \"nick\": \"@andrealmar\"\n    },\n    {\n    \"name\" : \"Jefferson\",\n    \"type\" : \"knowledge\",\n    \"age\" : 160,\n    \"nick\": \"@jeffotoni\"\n    },\n    {\n    \"name\" : \"Ieso Dias\",\n    \"type\" : \"knowledge\",\n    \"age\" : 23,\n    \"nick\": \"@iesodias\"\n    }\n  ]\n}\n```\n\nNow our file is an Array of values, let's see how we do it to access the keys and values of our new Json.\n\nLet's take a look at the code:\n```go\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"os\"\n\t\"reflect\"\n)\n\nfunc main() {\n\n\t// We can use the ioutil.ReadFile which would already\n\t// return bytes and we would not need to use two functions\n\t// ioutil.ReadFile(\"./user-only.json\")\n\n\t// Open our jsonFile\n\tjsonFile, err := os.Open(\"./user-only.json\")\n\n\t// if we os.Open returns an error then handle it\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\tfmt.Println(\"Successfully Opened users.json\")\n\n\t// defer the closing of our jsonFile so that we can parse it later on\n\tdefer jsonFile.Close()\n\n\t// reading archive content\n\tbyteValue, _ := ioutil.ReadAll(jsonFile)\n\n\t// defining the interface map that will receive\n\t// the file and the format is dynamic\n\tvar result map[string]interface{}\n\n\t// the syntax below is also allowed\n\t//var result = make(map[string]interface{})\n\n\t// let's now run our Unmarshal and convert to objects\n\tjson.Unmarshal([]byte(byteValue), \u0026result)\n\n\t// Let's access the interface on our map\n\tobj := result[\"users\"]\n\n\t// Here completely changes from the\n\t// previous example we now have an [] interface,\n\t// ie an array of interfaces a slice.\n\tobjInterface := obj.([]interface{})\n\n\t// Now as we have multiple users,\n\t// we'll loop through to fetch them\n\t// and access each user's key\n\t// and value in the slice\n\tfor line, keyOne := range objInterface {\n\n\t\tfmt.Println(\"#### line \", line)\n\n\t\t// ValueOf returns a new Value initialized\n\t\t// to the concrete value stored in the interface i.\n\t\tval := reflect.ValueOf(keyOne)\n\n\t\t// A Kind represents the\n\t\t// specific kind of type\n\t\t// that a Type represents.\n\t\tif val.Kind() == reflect.Map {\n\n\t\t\t// Loop the map\n\t\t\tfor _, key := range val.MapKeys() {\n\n\t\t\t\t// Index of Map\n\t\t\t\tv := val.MapIndex(key)\n\n\t\t\t\t// get the value of type Interface\n\t\t\t\tswitch value := v.Interface().(type) {\n\n\t\t\t\t// v.Interface().(type)\n\t\t\t\t// here test the types\n\t\t\t\tcase int:\n\t\t\t\t\tfmt.Println(key, value)\n\t\t\t\tcase float64:\n\t\t\t\t\tfmt.Println(key, value)\n\t\t\t\tcase string:\n\t\t\t\t\tfmt.Println(key, value)\n\t\t\t\tcase bool:\n\t\t\t\t\tfmt.Println(key, value)\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Println(\"not found\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\nSuccessfully Opened users.json\nk: 0 v: map[name:Andre Almar city:Sao Paulo age:25 nick:@andrealmar]\nname Andre Almar\ncity Sao Paulo\nage 25\nnick @andrealmar\nk: 1 v: map[name:Jefferson city:Belo Horizonte age:160 nick:@jeffotoni]\nname Jefferson\ncity Belo Horizonte\nage 160\nnick @jeffotoni\nk: 2 v: map[age:23 nick:@iesodias name:Ieso Dias city:Mato Grosso]\nname Ieso Dias\ncity Mato Grosso\nage 23\nnick @iesodias\n```\n\n**What if I have a Recursion in Json?**\n\n```json\n{\n  \"users\":\n  [\n    {\n      \"name\" : \"Joelson\",\n      \"city\" : \"Porto Alegre\",\n      \"age\" : 39,\n      \"social\" : {\n        \"facebook\" : \"https://facebook.com/joelson\",\n        \"twitter\" : \"https://twitter.com/joelson\",\n        \"instagram\" : \"https://instagram.com/joelson\"\n      },\n      \"fone\" : {\n        \"cell\" : \"5531987387246\",\n        \"resid1\" : \"55314565678\",\n        \"job\" : \"55314785679\"\n      }\n    },\n    {\n      \"name\" : \"Jefferson\",\n      \"city\" : \"Belo Horizonte\",\n      \"age\" : 160,\n      \"social\" : {\n        \"facebook\" : \"https://facebook.com/jeffotoni\",\n        \"twitter\" : \"https://twitter.com/jeffotoni\",\n        \"instagram\" : \"https://instagram.com/jeffotoni\"\n      },\n      \"fone\" : {\n        \"cell\" : \"5531987387246\",\n        \"resid1\" : \"55314565678\",\n        \"job\" : \"55314785679\"\n      }\n    }\n  ]\n}\n```\n\n```go\n\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"reflect\"\n)\n\nfunc main() {\n\n\t// Open our jsonFile\n\tbyteJson, err := ioutil.ReadFile(\"./users.json\")\n\n\t// if we os.Open returns an error then handle it\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\t// show screen\n\tfmt.Println(\"Successfully Opened users.json\")\n\n\t// defining the interface map that will receive\n\t// the file and the format is dynamic\n\tvar result = make(map[string]interface{})\n\n\t// let's now run our Unmarshal and convert to objects\n\tjson.Unmarshal(byteJson, \u0026result)\n\n\tobj := result[\"users\"]\n\n\t// get []interface\n\tobjData := obj.([]interface{})\n\n\t// recursive\n\tDecodeMapVetInterface(objData)\n}\n\nfunc DecodeMapVetInterface(objData []interface{}) {\n\t//fmt.Println(objData)\n\tfor line, v := range objData {\n\n\t\tfmt.Println(\"#### line: \", line)\n\n\t\t// ValueOf returns a new Value initialized\n\t\t// to the concrete value stored in the interface i.\n\t\tval := reflect.ValueOf(v)\n\n\t\t// A Kind represents the\n\t\t// specific kind of type\n\t\t// that a Type represents.\n\t\tif val.Kind() == reflect.Map {\n\n\t\t\t// Loop the map\n\t\t\tfor _, key := range val.MapKeys() {\n\n\t\t\t\tfmt.Println(\"..............................................\")\n\n\t\t\t\t// Index\n\t\t\t\tv := val.MapIndex(key)\n\t\t\t\tswitch iv := v.Interface().(type) {\n\n\t\t\t\t// v.Interface().(type)\n\t\t\t\t// here test the types\n\t\t\t\tcase int:\n\t\t\t\t\tfmt.Println(key, iv)\n\t\t\t\tcase float64:\n\t\t\t\t\tfmt.Println(key, iv)\n\t\t\t\tcase string:\n\t\t\t\t\tfmt.Println(key, iv)\n\t\t\t\tcase bool:\n\t\t\t\t\tfmt.Println(key, iv)\n\t\t\t\tdefault:\n\t\t\t\t\tfmt.Println(key)\n\t\t\t\t\tDecodeMapInterface(iv)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunc DecodeMapInterface(v interface{}) {\n\tval := reflect.ValueOf(v)\n\tif val.Kind() == reflect.Map {\n\t\tfor _, e := range val.MapKeys() {\n\t\t\tv := val.MapIndex(e)\n\t\t\tswitch t := v.Interface().(type) {\n\t\t\tcase int:\n\t\t\t\tfmt.Println(e, t)\n\t\t\tcase float64:\n\t\t\t\tfmt.Println(e, t)\n\t\t\tcase string:\n\t\t\t\tfmt.Println(e, t)\n\t\t\tcase bool:\n\t\t\t\tfmt.Println(e, t)\n\t\t\tdefault:\n\t\t\t\tfmt.Println(\"not found!\")\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\nSuccessfully Opened users.json\n#### line:  0\n..............................................\nname Joelson\n..............................................\ncity Porto Alegre\n..............................................\nage 39\n..............................................\nsocial\nfacebook https://facebook.com/joelson\ntwitter https://twitter.com/joelson\ninstagram https://instagram.com/joelson\n..............................................\nfone\ncell 5531987387246\nresid1 55314565678\njob 55314785679\n#### line:  1\n..............................................\nname Jefferson\n..............................................\ncity Belo Horizonte\n..............................................\nage 160\n..............................................\nsocial\ninstagram https://instagram.com/jeffotoni\nfacebook https://facebook.com/jeffotoni\ntwitter https://twitter.com/jeffotoni\n..............................................\nfone\ncell 5531987387246\nresid1 55314565678\njob 55314785679\n```\n\nWe were able to recursively list our Json, with several layers.\nBut every Json file will have to be handled, structures change as needed, so this recursion will only work for this file template.\n\nLet's take another example, with a new json with several layers.\n\nLet's take a look at the code below:\n```json\n{\n\"payload\": \n  [\n    {\n        \"products\": {\n            \"house\": {\n                \"rectangular bed\": {\n                    \"price\": 99.33,\n                    \"weight\": 44\n                },\n                \"Corner table\": {\n                    \"price\": 100.00,\n                    \"weight\": 400\n                }\n            },\n            \"car\": {\n                \"bmw\": {\n                    \"price\": 400.000,\n                    \"weight\": 2000\n                },\n                \"jaguar\": {\n                    \"price\": 600.000,\n                    \"weight\": 3000\n                }\n            },\n            \"robotics\": {\n                \"arduino circuit board\": {\n                    \"price\": 3000,\n                    \"weight\": 140\n                },\n                \"proximity sensor...\": {\n                    \"price\": 100,\n                    \"weight\": 34\n                },\n                \"temperature sensor\": {\n                    \"price\": 344,\n                    \"weight\": 55\n                }\n            }\n        }\n    }\n  ]\n}\n```\n\nComplete code:\n```go\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\t// open file json\n\tdata, err := ioutil.ReadFile(\"./payload.json\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\t// make map interface\n\tpayload := make(map[string]interface{})\n\n\t// Unmarshal data\n\terr = json.Unmarshal(data, \u0026payload)\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\t// call recursive\n\trecursivMap(payload)\n}\n\n// recursive Map\nfunc recursivMap(payload map[string]interface{}) {\n\tfor k, v := range payload {\n\t\t//fmt.Printf(\"%v %T: %v\\n\", k, v, v)\n\t\tswitch v.(type) {\n\t\tcase []interface{}:\n\t\t\trecursivSlice(v.([]interface{}))\n\t\tcase map[string]interface{}:\n\t\t\t//fmt.Printf(\"%v %T: %v\\n\", k, v, v)\n\t\t\tfmt.Println(\"----------------------\")\n\t\t\tfmt.Printf(\"%v\\n\", k)\n\t\t\trecursivMap(v.(map[string]interface{}))\n\n\t\tdefault:\n\t\t\tfmt.Printf(\"%v=%v\\n\", k, v)\n\t\t}\n\t}\n}\n\n// recursive Slice\nfunc recursivSlice(pauload []interface{}) {\n\tfor _, v := range pauload {\n\t\tswitch v.(type) {\n\t\tcase []interface{}:\n\t\t\trecursivSlice(v.([]interface{}))\n\t\tcase map[string]interface{}:\n\t\t\trecursivMap(v.(map[string]interface{}))\n\t\t}\n\t}\n}\n```\n\nOutput:\n```bash\n----------------------\nproducts\n----------------------\nhouse\n----------------------\nrectangular bed\nprice=99.33\nweight=44\n----------------------\nCorner table\nprice=100\nweight=400\n----------------------\ncar\n----------------------\nbmw\nprice=400\nweight=2000\n----------------------\njaguar\nprice=600\nweight=3000\n----------------------\nrobotics\n----------------------\narduino circuit board\nprice=3000\nweight=140\n----------------------\nproximity sensor...\nprice=100\nweight=34\n----------------------\ntemperature sensor\nprice=344\nweight=55\n```\n\nNow, we did something totally recursive, presenting all the keys and values from our Json file.\n\n\n### Parsing in yaml Format Using Go\n\nAfter this bunch of information we learn how to do parse with reflection using Go we are ready to create our own libs to parse in files. Reflection is very powerful and has several features and applicabilities, existing libs use reflection to parse files in json, toml, yaml or gcfg formats.\n\nLet's see in practice the lib gopkg.in/yaml.v2, and let's parse a file in Yaml format.\n\nWe have to install the lib on our local machine and to do this just use the command below.\n```bash\n$ go get -u gopkg.in/yaml.v2\n```\n\nCheck out the complete code below\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\n\tyaml \"gopkg.in/yaml.v2\"\n)\n\ntype ServersSsh struct {\n\tVersion string `yaml:\"version\"`\n\n\tInfo struct {\n\t\tDescription string `yaml:\"description\"`\n\t}\n\n\tServer1 struct {\n\t\tHost    string `yaml:\"host\"`\n\t\tPort    string `yaml:\"port\"`\n\t\tUser    string `yaml:\"user\"`\n\t\tFilePem string `yaml:\"filepem\"`\n\t\tKeyAws  string `yaml:\"keyaws\"`\n\t}\n\n\tServer2 struct {\n\t\tHost    string `yaml:\"host\"`\n\t\tPort    string `yaml:\"port\"`\n\t\tUser    string `yaml:\"user\"`\n\t\tFilePem string `yaml:\"filepem\"`\n\t\tKeyAws  string `yaml:\"keyaws\"`\n\t}\n}\n\n// Our config case has no structure created\n// the system will dynamically create\nvar YamlMemory = `\n`\n\n// func main\nfunc main() {\n\n\tvar yamlByte []byte\n\tvar Yaml ServersSsh\n\tvar err error\n\n\t// local\n\tfile := \"server.yaml\"\n\n\t// test exist\n\tif !FileExist(file) {\n\t\tfmt.Println(file + \" not exist!\")\n\t\treturn\n\t}\n\n\tif yamlByte, err = ioutil.ReadFile(file); err != nil {\n\t\tlog.Println(\"Error: \", err)\n\t}\n\n\t// Unmarshal receives the file in a byte format and assigns the values passed to the fields in the structure.\n\t// If there is an error it displays an error message on the screen informing the error\n\tif err := yaml.Unmarshal(yamlByte, \u0026Yaml); err != nil {\n\t\tlog.Println(\"Error\", err)\n\t}\n\n\tfmt.Println(\"Version: \", Yaml.Version)\n\tfmt.Println(\"Description: \", Yaml.Info.Description)\n\tfmt.Println(\"Server1.Host: \", Yaml.Server1.Host)\n\tfmt.Println(\"Server2.Host: \", Yaml.Server2.Host)\n}\n\nfunc FileExist(name string) bool {\n\t//if _, err := os.Stat(name); os.IsNotExist(err) {\n\tif stat, err := os.Stat(name); err == nil \u0026\u0026 !stat.IsDir() {\n\t\treturn true\n\t}\n\treturn false\n}\n```\n\nOutput:\n```bash\nVersion:  1.0\nDescription:  this is an example of yaml file to server an ssh server or multiple servers to do ssh automating services on server\nServer1.Host:  127.0.0.1\nServer2.Host:  127.0.0.10\n```\n\n### Parsing in Toml Format Using Go\n\nNow let's parse Toml files, there are several libs that do this, we will use github.com/BurntSushi/toml to do our parses.\n\nThe cool thing is that we have seen what the libs are doing behind the scenes, now to use the libs is very easy and all our understanding of struct, maps helped to unmask what happens behind the scenes.\n\nWe will install the package so that everything goes right.\n```bash\n$ go get github.com/BurntSushi/toml\n```\n\nTry the toml validator:\n```bash\n$ go get github.com/BurntSushi/toml/cmd/tomlv\n$ tomlv server.toml\n```\n\nLet's face it, check out the full code below.\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/BurntSushi/toml\"\n)\n\ntype ConfToml struct {\n\tVersion string\n\tInfo    Info\n\tServer1 Server1\n\tServer2 Server2\n\tClients Clients\n}\n\n// Info from config file\ntype Info struct {\n\tDescription string\n}\n\n// Server1\ntype Server1 struct {\n\tHost    string\n\tPort    int64\n\tUser    string\n\tFilePem string\n\tKeyAws  string\n}\n\n// Server2\ntype Server2 struct {\n\tHost    string\n\tPort    int64\n\tUser    string\n\tFilePem string\n\tKeyAws  string\n}\n\n// info from clients file\ntype Clients struct {\n\tPing  string\n\tData  [][]interface{} // very beautiful\n\tHosts []string\n}\n\nfunc main() {\n\n\tvar Toml ConfToml\n\n\tfile := \"server.toml\"\n\n\tif !FileExist(file) {\n\t\tfmt.Println(file + \" not exist!\")\n\t\treturn\n\t}\n\n\tif _, err := toml.DecodeFile(file, \u0026Toml); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// config data\n\tfmt.Println(\"version:\", Toml.Version)\n\tfmt.Println(\"Info.Description: \", Toml.Info.Description)\n\tfmt.Println(\"Server1.Host: \", Toml.Server1.Host)\n\tfmt.Println(\"Server2.Host:\", Toml.Server2.Host)\n\n\tfmt.Println(Toml.Clients.Data)\n\tfmt.Println(Toml.Clients.Data[0])\n\tfmt.Println(Toml.Clients.Data[0][0])\n\tfmt.Println(Toml.Clients.Data[0][1])\n\n\tfmt.Println(Toml.Clients.Hosts)\n\tfmt.Println(Toml.Clients.Hosts[0])\n\tfmt.Println(Toml.Clients.Hosts[1])\n}\n\nfunc FileExist(name string) bool {\n\t//if _, err := os.Stat(name); os.IsNotExist(err) {\n\tif stat, err := os.Stat(name); err == nil \u0026\u0026 !stat.IsDir() {\n\t\treturn true\n\t}\n\treturn false\n}\n```\n\n\nOutput:\n```bash\nversion: 1.0\nInfo.Description:  this is an example of yaml file to server an ssh server or multiple servers to do ssh automating services on server\nServer1.Host:  127.0.0.1\nServer2.Host: 127.0.0.10\n[[amazon google] [1 2]]\n[amazon google]\namazon\ngoogle\n[aws cloud]\naws\ncloud\n```\n\n### Parsing with Viper\n\nWhen building a modern application, you don’t want to worry about configuration file formats; you want to focus on building awesome software. Viper is here to help with that.\n\nViper is a complete configuration solution for Go applications including 12-Factor apps. It is designed to work within an application, and can handle all types of configuration needs and formats. It supports:\n\n```bash\n - setting defaults\n - reading from JSON, TOML, YAML, HCL, and Java properties config files\n - live watching and re-reading of config files (optional)\n - reading from environment variables\n - reading from remote config systems (etcd or Consul), and watching changes\n - reading from command line flags\n - reading from buffer\n - setting explicit values\n```\n\nViper can be thought of as a registry for all of your applications configuration needs.\n\nLet's now see some practical examples of how to work with viper.\n\n### Viper file Json, Yaml and Toml\n\n```bash\n$ go get github.com/spf13/viper\n```\n\nLook at the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/viper\"\n)\n\nfunc main() {\n\n\t// viper.SetConfigType(\"toml\")\n\t// viper.SetConfigName(\"servert\") // name of config file (without extension)\n\n\t// viper.SetConfigType(\"yaml\")\n\t// viper.SetConfigName(\"servery\") // name of config file (without extension)\n\n\tviper.SetConfigType(\"json\")\n\tviper.SetConfigName(\"serverj\") // name of config file (without extension)\n\n\tviper.AddConfigPath(\".\") // optionally look for config in the working directory\n\n\t//viper.AddConfigPath(\"/etc/appname/\")  // path to look for the config file in\n\t//viper.AddConfigPath(\"$HOME/.appname\") // call multiple times to add many search paths\n\n\terr := viper.ReadInConfig() // Find and read the config file\n\tif err != nil {             // Handle errors reading the config file\n\t\tpanic(fmt.Errorf(\"Fatal error config file: %s \\n\", err))\n\t}\n\n\tviper.Set(\"Verbose\", true)\n\t//viper.Set(\"LogFile\", LogFile)\n\n\tfmt.Println(\"datastore.metric.host: \", viper.GetString(\"datastore.metric.host\"))\n\tfmt.Println(\"datastore.warehouse.host: \", viper.GetString(\"datastore.warehouse.host\"))\n\n\tfmt.Println(\"version.json: \", viper.GetString(\"version\"))\n\tfmt.Println(\"info.json: \", viper.GetString(\"info.description\"))\n\tfmt.Println(\"server1.host.json: \", viper.GetString(\"server1.host\"))\n\tfmt.Println(\"server1.user.json: \", viper.GetString(\"server1.user\"))\n\n\tfmt.Println(\"server2.host.json: \", viper.GetString(\"server2.host\"))\n\tfmt.Println(\"server2.user.json: \", viper.GetString(\"server2.user\"))\n}\n```\n\nOutput:\n```bash\ndatastore.metric.host:  192.168.0.113\ndatastore.warehouse.host:  198.0.0.1\nversion.json:  1.0\ninfo.json:  this is an example of yaml file to server an ssh ..\nserver1.host.json:  127.0.0.1\nserver1.user.json:  ubuntu\nserver2.host.json:  127.0.0.13\nserver2.user.json:  centos\n```\n\nIn the above example the great advantage that we did not change our code to adapt to any specific pattern, we read Json, Toml and Yaml without having to change a line.\n\nOne realizes that we did not create struct to capture the fields nor to create collections, the viper did everything for people, all magic that we learned of reflection he applied in his lib.\n\n### Viper Map with Interface\n\nWe made an interface map to test with Viper.\n\nFrom a check how it was:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/spf13/viper\"\n)\n\nfunc main() {\n\tv1, err := readConfig(\"enviroment\", map[string]interface{}{\n\t\t\"version\": 1.0,\n\t\t\"info\": map[string]string{\n\t\t\t\"description\": \"this is an example of yaml file to server an ssh server or\",\n\t\t},\n\t\t\"server1\": map[string]string{\n\t\t\t\"host\": \"localhost\",\n\t\t\t\"user\": \"titpetric\",\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(fmt.Errorf(\"Error when reading config: %v\\n\", err))\n\t}\n\n\tversion := v1.GetFloat64(\"version\")\n\tinfo := v1.GetString(\"info.description\")\n\tserver1 := v1.GetStringMapString(\"server1\")\n\n\tfmt.Printf(\"version: %0.1f\\n\", version)\n\tfmt.Printf(\"info.description: %s\\n\", info)\n\tfmt.Printf(\"server1:%#v\\n\", server1)\n\tfmt.Printf(\"server1.host: %s\\n\", server1[\"host\"])\n}\n\nfunc readConfig(filename string, defaults map[string]interface{}) (*viper.Viper, error) {\n\tv := viper.New()\n\tfor key, value := range defaults {\n\t\tv.SetDefault(key, value)\n\t}\n\n\tv.SetConfigName(filename)\n\tv.AddConfigPath(\".\")\n\tv.AutomaticEnv()\n\terr := v.ReadInConfig()\n\treturn v, err\n}\n```\n\n```bash\nversion: 1.0\ninfo.description: this is an example of yaml file to server an ssh server or multiple servers to do ssh automating services on server\nserver1:map[string]string{\"type\":\"env\", \"file\":\"key_1.pem\", \"env\":\"KEY_AWS\", \"host\":\"127.0.0.1\", \"port\":\"22\", \"user\":\"ubuntu\"}\nserver1.host: 127.0.0.1\n```\n\n### Viper in Memory\n\nThe example below shows that we can use variables with the content in Yaml, Json or Toml format so that we can parse.\n\nCheck out the complete code below:\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\n\t\"github.com/spf13/viper\"\n)\n\nfunc main() {\n\n\tviper.SetConfigType(\"yaml\") // or viper.SetConfigType(\"YAML\")\n\n\t// any approach to require this configuration into your program.\n\tvar yamlExample = []byte(`\nversion: 1.0\ninfo: \n description: this is an example of yaml file to ...\nserver1:\n  host: 127.0.0.1\n  port: 22\n  user: ubuntu\n  type: env\n  file: key_1.pem\n  env: KEY_AWS\n  Clouds: [Aws, Google, Azure]\n`)\n\n\tviper.ReadConfig(bytes.NewBuffer(yamlExample))\n\n\tfmt.Println(viper.Get(\"version\"))\n\tfmt.Println(viper.Get(\"info.description\"))\n\tfmt.Println(viper.Get(\"server1.host\"))\n\tfmt.Println(viper.Get(\"server1.user\"))\n\tmapsc := viper.GetStringSlice(\"server1.clouds\")\n\n\tfmt.Println(mapsc[0])\n}\n```\n\n```bash\n1\nthis is an example of yaml file to ...\n127.0.0.1\nubuntu\nAws\n```\n\nThe viper is very powerful we can do Marshal, Unmarsha works with multiple viper, access, works with Flags etc.\n\nIt is worth checking.\n\n\n### Links Json to Golang\n\nBelow I am making available some links to convert from Json to Struct in Golang, it gets a json or you write your Json and it mounts the struct for you.\nOf course it helps when you know what you're doing, and it's very useful sometimes to find some more complex json.\n\n - [Mholt Json to Go](https://mholt.github.io/json-to-go/)\n - [Transform json to Go](https://transform.now.sh/json-to-go/)\n - [Json2struct](http://json2struct.mervine.net/)\n\n\n## Lab 04 Building apis with net/http\n---\n\n\n### Introduction http\n\nNow we get to the best part, put into practice everything we learn.\nLet's get to know the net / http package one of the most powerful packages in Go, there are many speculations about it but we will really do our best in what it provides with the features it offers.\nThere are many implementations on the net / http, several routes, frameworks, libs all to minimize the work and speed up various tasks when coding our apis.\nOur goal is to create native APIs, as we did in Lab 03 Parse with Golang.\n\nEverything in Go follows this model, has lib for a lot, and the more you master the language the more habit you will be to choose the libs better or develop your own libs.\nLet's start by developing our API Server, so we can consume it later.\nAPIS as a server can be done in several ways, either by building APIS in the **rEST, GraphQL, SOAP, XML-RPC** and several other forms of communication such as **RPC, Socket or Websocket**.\n\nWe have a powerful and vast library, everything we had in **C or C ++** is in **Go improved**.\nEvery **net/http** package is working on Goroutine, this is one of the pillars of [net/http](https://golang.org/pkg/net/http/)\n\n\n### type Handler\n\nA Handler responds to an HTTP request.\n\nServeHTTP should write reply headers and data to the ResponseWriter and then return. Returning signals that the request is finished; it is not valid to use the ResponseWriter or read from the Request.Body after or concurrently with the completion of the ServeHTTP call. \n\nOnce implemented the http.Handler can be passed to http.ListenAndServe, which will call the ServeHTTP method on every incoming request.\nhttp.Request contains all relevant information about an incoming http request which is being served by your http.Handler.\n\n```go\ntype Handler interface {\n        ServeHTTP(ResponseWriter, *Request)\n}\n```\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype pingHandler struct{}\n\nfunc (h pingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"DevopsBH for Golang simple %s\\n\", r.URL.Path)\n}\n\nfunc main() {\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\terr := http.ListenAndServe(\":8080\", pingHandler{})\n\tlog.Fatal(err)\n}\n```\nRun the curl:\n```bash\n$ curl -i -Xget localhost:8080/v1/api/ping\n$ curl -i -Xget localhost:8080\n```\n\nThe http.ResponseWriter is the interface through which you can respond to the request. It implements the io.Writer interface, so you can use methods like fmt.Fprintf to write a formatted string as the response body, or ones like io.Copy to write out the contents of a file (or any other io.Reader). The response code can be set before you begin writing data using the WriteHeader method.\n\nGo’s http package has turned into one of my favorite things about the Go programming language. Initially it appears to be somewhat complex, but in reality it can be broken down into a couple of simple components that are extremely flexible in how they can be used. \n\n\n### Type Handlerfunc\n\nThe HandlerFunc type is an adapter to allow the use of ordinary functions as HTTP handlers. If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f. \n\nOften defining a full type to implement the http.Handler interface is a bit overkill, especially for extremely simple ServeHTTP functions like the one above. The http package provides a helper function, http.HandlerFunc, which wraps a function which has the signature func(w http.ResponseWriter, r *http.Request), returning an http.Handler which will call it in all cases.*\n\nThe following behaves exactly like the previous example, but uses http.HandlerFunc instead of defining a new type.\n\n```go\ntype HandlerFunc func(ResponseWriter, *Request)\n```\n\nCheck out:\n```go\nhandlerApiPing := http.HandlerFunc(Ping)\n```\n\nLook at the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\thandlerfunc := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tfmt.Fprintf(w, \"DevopsBH for Golang simple two %s\\n\", r.URL.Path)\n\t})\n\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\terr := http.ListenAndServe(\":8080\", handlerfunc)\n\tlog.Fatal(err)\n}\n```\n\n### Func http Handlefunc\n\n HandleFunc registers the handler function for the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patterns are matched.\n\n```go\nfunc HandleFunc(pattern string, handler func(ResponseWriter, *Request))\n```\n\nCheck out the examples below:\n```go\nhttp.HandleFunc(\"/v1/api/ping\", pingHandler)\n```\n\n```go\nhttp.HandleFunc(\"/v1/api/ping\", func(w http.ResponseWriter, req *http.Request){})\n```\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tw.Write([]byte(\"\\nDevops BH for Golang HandleFunc!\"))\n\t}\n\n\t// handleFunc\n\thttp.HandleFunc(\"/v1/api/ping\", pingHandler)\n\thttp.HandleFunc(\"/v1/api/ping2\", pingHandler)\n\thttp.HandleFunc(\"/v1/api/ping3\", pingHandler)\n\n\t// show run server\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n}\n```\n\n### Func http Handle\n\nHandle registers the handler for the given pattern in the DefaultServeMux.\n\n```go\nfunc Handle(pattern string, handler Handler)\n```\n\nCheck out the example below:\n```go\nhttp.Handle(\"/v1/api/ping\", http.HandlerFunc(Ping))\n```\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tw.Write([]byte(\"\\nDevops BH for Golang Handle tree!\"))\n\t}\n\n\t// Handle and recive http.HandlerFunc\n\thttp.Handle(\"/v1/api/ping\", http.HandlerFunc(pingHandler))\n\thttp.Handle(\"/v1/api/ping2\", http.HandlerFunc(pingHandler))\n\thttp.Handle(\"/v1/api/ping3\", http.HandlerFunc(pingHandler))\n\t// http.Handle(\"/v1/api/ping\", pingHandler) // error\n\n\t// show run\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\n\t// Listen\n\t// log.Fatal(http.ListenAndServe(\":8080\", http.HandlerFunc(pingHandler))) ok\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil))\n}\n```\n\n### Func http Error\n\nError replies to the request with the specified error message and HTTP code. It does not otherwise end the request; the caller should ensure no further writes are done to w. The error message should be plain text. \n\n ```go\n func Error(w ResponseWriter, error string, code int)\n ```\n\nCheck out the example below:\n```go\njson := `{\"status\":\"error\", \"msg\":\"method not supported, only POST\"}`\nhttp.Error(w, json, http.StatusUnauthorized)\n```\n\n### Constants Common HTTP Methods\n\nUnless otherwise noted, these are defined in RFC 7231 section 4.3.\n\n```go\n const (\n        MethodGet     = \"GET\"\n        MethodHead    = \"HEAD\"\n        MethodPost    = \"POST\"\n        MethodPut     = \"PUT\"\n        MethodPatch   = \"PATCH\" // RFC 5789\n        MethodDelete  = \"DELETE\"\n        MethodConnect = \"CONNECT\"\n        MethodOptions = \"OPTIONS\"\n        MethodTrace   = \"TRACE\"\n)\n```\n\n**HTTP status codes** as registered with IANA. See: [http/status/code](https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml)\n\n```go\nconst (\n        StatusContinue           = 100 // RFC 7231, 6.2.1\n        StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2\n        StatusProcessing         = 102 // RFC 2518, 10.1\n\n        StatusOK                   = 200 // RFC 7231, 6.3.1\n        StatusCreated              = 201 // RFC 7231, 6.3.2\n        StatusAccepted             = 202 // RFC 7231, 6.3.3\n        StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4\n        StatusNoContent            = 204 // RFC 7231, 6.3.5\n        StatusResetContent         = 205 // RFC 7231, 6.3.6\n        StatusPartialContent       = 206 // RFC 7233, 4.1\n        StatusMultiStatus          = 207 // RFC 4918, 11.1\n        StatusAlreadyReported      = 208 // RFC 5842, 7.1\n        StatusIMUsed               = 226 // RFC 3229, 10.4.1\n\n        StatusMultipleChoices  = 300 // RFC 7231, 6.4.1\n        StatusMovedPermanently = 301 // RFC 7231, 6.4.2\n        StatusFound            = 302 // RFC 7231, 6.4.3\n        StatusSeeOther         = 303 // RFC 7231, 6.4.4\n        StatusNotModified      = 304 // RFC 7232, 4.1\n        StatusUseProxy         = 305 // RFC 7231, 6.4.5\n\n        StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7\n        StatusPermanentRedirect = 308 // RFC 7538, 3\n\n        StatusBadRequest                   = 400 // RFC 7231, 6.5.1\n        StatusUnauthorized                 = 401 // RFC 7235, 3.1\n        StatusPaymentRequired              = 402 // RFC 7231, 6.5.2\n        StatusForbidden                    = 403 // RFC 7231, 6.5.3\n        StatusNotFound                     = 404 // RFC 7231, 6.5.4\n        StatusMethodNotAllowed             = 405 // RFC 7231, 6.5.5\n        StatusNotAcceptable                = 406 // RFC 7231, 6.5.6\n        StatusProxyAuthRequired            = 407 // RFC 7235, 3.2\n        StatusRequestTimeout               = 408 // RFC 7231, 6.5.7\n        StatusConflict                     = 409 // RFC 7231, 6.5.8\n        StatusGone                         = 410 // RFC 7231, 6.5.9\n        StatusLengthRequired               = 411 // RFC 7231, 6.5.10\n        StatusPreconditionFailed           = 412 // RFC 7232, 4.2\n        StatusRequestEntityTooLarge        = 413 // RFC 7231, 6.5.11\n        StatusRequestURITooLong            = 414 // RFC 7231, 6.5.12\n        StatusUnsupportedMediaType         = 415 // RFC 7231, 6.5.13\n        StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4\n        StatusExpectationFailed            = 417 // RFC 7231, 6.5.14\n        StatusTeapot                       = 418 // RFC 7168, 2.3.3\n        StatusMisdirectedRequest           = 421 // RFC 7540, 9.1.2\n        StatusUnprocessableEntity          = 422 // RFC 4918, 11.2\n        StatusLocked                       = 423 // RFC 4918, 11.3\n        StatusFailedDependency             = 424 // RFC 4918, 11.4\n        StatusUpgradeRequired              = 426 // RFC 7231, 6.5.15\n        StatusPreconditionRequired         = 428 // RFC 6585, 3\n        StatusTooManyRequests              = 429 // RFC 6585, 4\n        StatusRequestHeaderFieldsTooLarge  = 431 // RFC 6585, 5\n        StatusUnavailableForLegalReasons   = 451 // RFC 7725, 3\n\n        StatusInternalServerError           = 500 // RFC 7231, 6.6.1\n        StatusNotImplemented                = 501 // RFC 7231, 6.6.2\n        StatusBadGateway                    = 502 // RFC 7231, 6.6.3\n        StatusServiceUnavailable            = 503 // RFC 7231, 6.6.4\n        StatusGatewayTimeout                = 504 // RFC 7231, 6.6.5\n        StatusHTTPVersionNotSupported       = 505 // RFC 7231, 6.6.6\n        StatusVariantAlsoNegotiates         = 506 // RFC 2295, 8.1\n        StatusInsufficientStorage           = 507 // RFC 4918, 11.5\n        StatusLoopDetected                  = 508 // RFC 5842, 7.2\n        StatusNotExtended                   = 510 // RFC 2774, 7\n        StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6\n)\n```\n\nDefaultMaxHeaderBytes is the maximum permitted size of the headers in an HTTP request. This can be overridden by setting **Server.MaxHeaderBytes**.\n\n```go\nconst DefaultMaxHeaderBytes = 1 \u003c\u003c 20 // 1 MB\n```\n\nDefaultMaxIdleConnsPerHost is the default value of Transport's MaxIdleConnsPerHost. \n\n```go\nconst DefaultMaxIdleConnsPerHost = 2\n```\n\nTimeFormat is the time format to use when generating times in HTTP headers. It is like time.RFC1123 but hard-codes GMT as the time zone. The time being formatted must be in UTC for Format to generate the correct format.\n\nFor parsing this time format, see ParseTime. \n\n```go\nconst TimeFormat = \"Mon, 02 Jan 2006 15:04:05 GMT\"\n```\n\n### Type ServeMux\n\nServeMux is an HTTP request multiplexer. It matches the URL of each incoming request against a list of registered patterns and calls the handler for the pattern that most closely matches the URL.\n\nPatterns name fixed, rooted paths, like \"/favicon.ico\", or rooted subtrees, like \"/images/\" (note the trailing slash). Longer patterns take precedence over shorter ones, so that if there are handlers registered for both \"/images/\" and \"/images/thumbnails/\", the latter handler will be called for paths beginning \"/images/thumbnails/\" and the former will receive requests for any other paths in the \"/images/\" subtree.\n\nNote that since a pattern ending in a slash names a rooted subtree, the pattern \"/\" matches all paths not matched by other registered patterns, not just the URL with Path == \"/\".\n\nIf a subtree has been registered and a request is received naming the subtree root without its trailing slash, ServeMux redirects that request to the subtree root (adding the trailing slash). This behavior can be overridden with a separate registration for the path without the trailing slash. For example, registering \"/images/\" causes ServeMux to redirect a request for \"/images\" to \"/images/\", unless \"/images\" has been registered separately.\n\nPatterns may optionally begin with a host name, restricting matches to URLs on that host only. Host-specific patterns take precedence over general patterns, so that a handler might register for the two patterns \"/codesearch\" and \"codesearch.google.com/\" without also taking over requests for \"http://www.google.com/\".\n\nServeMux also takes care of sanitizing the URL request path and the Host header, stripping the port number and redirecting any request containing . or .. elements or repeated slashes to an equivalent, cleaner URL.\n\n```go\ntype ServeMux struct {\n     // contains filtered or unexported fields\n}\n```\n\n### Type NewServeMux\n\nNewServeMux allocates and returns a new ServeMux. \n\n```go\nfunc NewServeMux() *ServeMux\n```\n\nCheck out:\n```go\nmux := http.NewServeMux()\n```\n\n### func (\\*ServeMux) HandleFunc\n\n```go\nfunc (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Request))\n```\n\nHandleFunc registers the handler function for the given pattern.\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\tmux := http.NewServeMux()\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tw.Write([]byte(\"\\nDevops BH for Golang mux HandleFunc!\"))\n\t}\n\n\t// handleFunc\n\tmux.HandleFunc(\"/v1/api/ping\", pingHandler) // ok\n\n\tmux.HandleFunc(\"/v1/api/ping2\", http.HandlerFunc(pingHandler)) // ok\n\n\tmux.HandleFunc(\"/v1/api/ping3\", pingHandler) // ok\n\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.WriteHeader(http.StatusNotFound)\n\t\tfmt.Fprintln(w, \"You're lost, go home devopsBH!\")\n\t})\n\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(\":8080\", mux))\n}\n```\n\nRun cURL:\n```bash\n$ curl -i -Xget localhost:8080/\n```\n\n### Type ServeMux Handle\n\nHandle registers the handler for the given pattern. If a handler already exists for pattern, Handle panics. \n\n```go\nfunc (mux *ServeMux) Handle(pattern string, handler Handler)\n```\n\nCheck out:\n```go\nmux := http.NewServeMux()\nmux.Handle(\"/v1/api/ping\", http.HandlerFunc(Ping))\n```\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\tmux := http.NewServeMux()\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tw.Write([]byte(\"\\nDevops BH for Golang mux Handle()!\"))\n\t}\n\n\t// handlerFunc\n\tmux.Handle(\"/v1/api/ping\", http.HandlerFunc(pingHandler)) // ok\n\t// mux.Handle(\"/v1/api/ping2\", pingHandler) // error\n\t// mux.Handle(\"/v1/api/ping\", mux.HandlerFunc(pingHandler)) // error\n\n\t// mux.Handle(\"/\", func(w http.ResponseWriter, r *http.Request) {  // error\n\t// \tw.WriteHeader(http.StatusNotFound)\n\t// \tfmt.Fprintln(w, \"You're lost, go home devopsBH!\")\n\t// })\n\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(\":8080\", mux))\n}\n```\n\nRun cURL:\n```bash\n$ curl -i -Xget localhost:8080/\n```\n\n\n### Func ListenAndServe\n\nHandleFunc registers the handler function for the given pattern in the DefaultServeMux. The documentation for ServeMux explains how patterns are matched. \n\n```go\nfunc ListenAndServe(addr string, handler Handler) error\n```\n\nListenAndServe listens on the TCP network address addr and then calls Serve with handler to handle requests on incoming connections. Accepted connections are configured to enable TCP keep-alives.\n\nThe handler is typically nil, in which case the DefaultServeMux is used.\n\nListenAndServe always returns a non-nil error. \n\n\nCheck out our first example:\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nfunc main() {\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tio.WriteString(w, \"DevopsBH, Golang for Devops!\\n\")\n\t}\n\n\t// handlerFunc\n\thttp.HandleFunc(\"/v1/api/ping\", pingHandler)\n\n\t// Listen\n\t// log.Fatal(http.ListenAndServe(\":8080\", http.HandlerFunc(pingHandler))) ok\n\tlog.Fatal(http.ListenAndServe(\":8080\", nil)) // ok\n\n}\n```\n\nIn this apis scenario, the program is listening on the port determined by the function **ListenAndServe** waiting for the requests to be received so that it can respond to incoming requests.\n\n```bash\n$ curl -i -XPOST localhost:8080/v1/api/ping\n```\n\nOutput:\n```bash\nHTTP/1.1 200 OK\nDate: Fri, 01 Feb 2019 17:01:23 GMT\nContent-Length: 29\nContent-Type: text/plain; charset=utf-8\n\nDevopsBH, Golang for Devops!\n```\n\n### func ListenAndServeTLS \n\nListenAndServeTLS acts identically to ListenAndServe, except that it expects HTTPS connections. Additionally, files containing a certificate and matching private key for the server must be provided. If the certificate is signed by a certificate authority, the certFile should be the concatenation of the server's certificate, any intermediates, and the CA's certificate. \n\n```go\nfunc ListenAndServeTLS(addr, certFile, keyFile string, handler Handler) error\n```\n\nBefore we have to generate the keys, .pem or .crt and the .key file.\nLet's generate all running openssl.\n\nCheck the codes below:\n```bash\n#generating .key and .csr\n$ openssl req -nodes -newkey rsa:2048 -keyout server.key -out server.csr -subj \"/C=BR/ST=Minas/L=Belo Horizonte/O=s3wf Ltd./OU=IT/CN=localhost\"\n\n# generating server .crt or .pem\n$ openssl x509 -req -sha256 -in server.csr -signkey server.key -out server.crt -days 365\n```\n\nSoon we generate server.crt, server.csr, server.key.\n\nNow, let's go to our api below:\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nvar (\n\taddr = \":443\"\n)\n\nfunc main() {\n\n\thttp.HandleFunc(\"/v1/api/ping\", func(w http.ResponseWriter, req *http.Request) {\n\t\tio.WriteString(w, \"DevopsBH, Golang for Devops TLS!\\n\")\n\t})\n\n\t// show\n\tlog.Printf(\"Server Run %s TLS / https://localhost%s\", addr, addr)\n\n\t// conf listen TLS\n\terr := http.ListenAndServeTLS(addr, \"server.crt\", \"server.key\", nil)\n\tlog.Fatal(err)\n}\n```\nBelow the same code however modifying listen TLS using http.HandlerFunc()\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nvar (\n\taddr = \":443\"\n)\n\nfunc main() {\n\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tio.WriteString(w, \"DevopsBH, Golang for Devops TLS!\\n\")\n\t}\n\n\t// show\n\tlog.Printf(\"Server Run %s TLS / https://localhost%s\", addr, addr)\n\n\t// conf listen TLS\n\terr := http.ListenAndServeTLS(addr, \"server.crt\", \"server.key\", http.HandlerFunc(pingHandler))\n\tlog.Fatal(err)\n}\n\n// curl --insecure -i -XGET https://localhost:8443/v1/api/ping\n// curl -k -i -XGET https://localhost:8443/v1/api/ping\n```\n\n```bash\n$ curl --insecure -i -XGET https://localhost:443/v1/api/ping\nor\n$ curl -k -i -XGET https://localhost:443/v1/api/ping\n```\n\nNow we will use some properties of the tls package and we will make a config, as we have already learned mux we will use it as well.\nAt first it seems confusing, but in fact it's simple let's check it out.\n\nLook at the code below:\n```go\npackage main\n\nimport (\n\t\"crypto/tls\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n)\n\nvar (\n\taddr = \":443\"\n)\n\nfunc main() {\n\n\tmux := http.NewServeMux()\n\n\tmux.HandleFunc(\"/v1/api/ping\",\n\t\tfunc(w http.ResponseWriter, req *http.Request) {\n\t\t\tw.Header().Add(\"Strict-Transport-Security\", \"max-age=63072000; includeSubDomains\")\n\t\t\tio.WriteString(w, \"DevopsBH, Golang for Devops TLS MUX!\\n\")\n\t\t})\n\n\tcfg := \u0026tls.Config{\n\t\tMinVersion:               tls.VersionTLS12,\n\t\tCurvePreferences:         []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256},\n\t\tPreferServerCipherSuites: true,\n\t\tCipherSuites: []uint16{\n\t\t\ttls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,\n\t\t\ttls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,\n\t\t\ttls.TLS_RSA_WITH_AES_256_GCM_SHA384,\n\t\t\ttls.TLS_RSA_WITH_AES_256_CBC_SHA,\n\t\t},\n\t}\n\n\tsrv := \u0026http.Server{\n\t\tAddr:         addr,\n\t\tHandler:      mux,\n\t\tTLSConfig:    cfg,\n\t\tTLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 0),\n\t}\n\n\t// show\n\tlog.Printf(\"Server Run %s TLS / https://localhost%s\", addr, addr)\n\n\t// conf listen TLS\n\terr := srv.ListenAndServeTLS(\"server.crt\", \"server.key\")\n\tlog.Fatal(err)\n}\n\n// curl --insecure -i -XGET https://localhost:443/v1/api/ping\n// curl -k -i -XGET https://localhost:443/v1/api/ping\n```\n\nRun cURL:\n```bash\n$ curl --insecure -i -XGET https://localhost:443/v1/api/ping\nor\n$ curl -k -i -XGET https://localhost:443/v1/api/ping\n```\n\n---\n\nNow let's put some functions that will make a difference when we run our api for high performance, let's try not to use the fmt library to write to the monitor, let's use io and buff.\nWell performance is something absurdly faster.\n\nFrom one checked in the complete code below:\n```go\npackage main\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n)\n\nvar (\n\taddr = \":8080\"\n)\n\n// write bufio to optimization\nfunc write(text string) {\n\t// var writer *bufio.Writer\n\twriter := bufio.NewWriter(os.Stdout)\n\twriter.WriteString(text)\n\twriter.Flush()\n}\n\nfunc main() {\n\n\t// our function\n\tpingHandler := func(w http.ResponseWriter, req *http.Request) {\n\t\tjson := `{\"status\":\"success\", \"msg\":\"DevopsBH, Golang for Devops!\"}`\n\t\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\tio.WriteString(w, json)\n\t}\n\n\t// handlerFunc\n\thttp.HandleFunc(\"/v1/api/ping\", pingHandler)\n\n\t// show\n\twrite(\"\\033[0;33mServer Run Port \" + addr + \"\\033[0m\\n\")\n\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(addr, nil))\n}\n```\n\n```go\n// Go in action\n// @jeffotoni\n// 2019-01-01\n\npackage main\n\nimport (\n\t\"bufio\"\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n)\n\nvar (\n\taddr = \":8080\"\n)\n\n// show log on screen\nfunc logf(method, uri, nameHandle string, timeHandler time.Duration) {\n\n\texpre := \"\\033[5m%s \\033[0;103m%s\\033[0m \\033[0;93m%s\\033[0m \\033[1;44m%s\\033[0m\"\n\tlog.Printf(expre, method, uri, nameHandle, timeHandler)\n}\n\n// write bufio to optimization\nfunc write(text string) {\n\t// var writer *bufio.Writer\n\twriter := bufio.NewWriter(os.Stdout)\n\twriter.WriteString(text)\n\twriter.Flush()\n}\n\nfunc Ping(w http.ResponseWriter, r *http.Request) {\n\n\t// start time\n\tstart := time.Now()\n\n\tif http.MethodPost == strings.ToUpper(r.Method) {\n\n\t\tjson := `{\"status\":\"success\", \"msg\":\"DevopsBH, Golang for Devops!\"}`\n\t\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\tw.WriteHeader(http.StatusOK)\n\t\tio.WriteString(w, json)\n\n\t} else {\n\n\t\tjson := `{\"status\":\"error\", \"msg\":\"method not supported, only POST\"}`\n\t\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\tio.WriteString(w, json)\n\t}\n\n\tlogf(r.Method,\n\t\tr.RequestURI,\n\t\t\"Ping\",\n\t\ttime.Since(start))\n}\n\nfunc main() {\n\n\t// handlerFunc\n\thttp.HandleFunc(\"/v1/api/ping\", Ping)\n\n\t// show\n\twrite(\"\\033[0;33mServer Run \" +\n\t\t\"Port \" +\n\t\taddr + \"\\033[0m\\n\")\n\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(addr, nil))\n}\n```\n\n```bash\n$ curl -i -XPOSt localhost:8080/v1/api/ping\nHTTP/1.1 200 OK\nContent-Type: application/json; charset=utf-8\nDate: Fri, 01 Feb 2019 22:04:57 GMT\nContent-Length: 58\n{\"status\":\"success\", \"msg\":\"DevopsBH, Golang for Devops!\"}\n```\n\n```bash\n$ curl -i -XGET localhost:8080/v1/api/ping\nHTTP/1.1 401 Unauthorized\nContent-Type: application/json; charset=utf-8\nDate: Fri, 01 Feb 2019 22:05:46 GMT\nContent-Length: 59\n{\"status\":\"error\", \"msg\":\"method not supported, only POST\"}\n```\n\n### Other Muxes\n\nThere are numerous replacements for **http.ServeMux** like **gorilla/mux** which give you things like automatically pulling variables out of paths, easily asserting what http methods are allowed on an endpoint, and more. Most of these replacements will implement http.Handler like http.ServeMux does, and accept **http.Handlers** as arguments, and so are easy to use in conjunction with the rest of the things I’m going to talk about in this post.\n\nLet's write our own http.HandlerFunc, let's create something simple just so we can understand what happens with our apis.\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n)\n\ntype numberDumperString string\ntype numberDumperInt int\n\n// http HandlerFunc\nfunc (n numberDumperString) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"DevOps BH, Golang is Life, Here's your number: %s\\n\", n)\n}\n\n// http HandlerFunc\nfunc (n numberDumperInt) ServeHTTP(w http.ResponseWriter, r *http.Request) {\n\tfmt.Fprintf(w, \"DevOps BH, Golang is Life, Here's your number: %d\\n\", n)\n}\n\nfunc main() {\n\tmux := http.NewServeMux()\n\n\tmux.Handle(\"/one\", numberDumperString(\"one\"))\n\tmux.Handle(\"/two\", numberDumperString(\"two\"))\n\tmux.Handle(\"/three\", numberDumperInt(3))\n\tmux.Handle(\"/four\", numberDumperInt(4))\n\tmux.Handle(\"/five\", numberDumperInt(5))\n\n\tmux.HandleFunc(\"/\", func(w http.ResponseWriter, r *http.Request) {\n\t\tw.WriteHeader(404)\n\t\tfmt.Fprintln(w, \"That's not a supported number new Ghoper!\")\n\t})\n\n\t// show run\n\tlog.Printf(\"\\nServer run 8080\\n\")\n\n\t// listen\n\terr := http.ListenAndServe(\":8080\", mux)\n\tlog.Fatal(err)\n}\n```\n\nRun cURL:\n```bash\n$ curl -i -Xget localhost:8080/one\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 01:25:39 GMT\nContent-Length: 51\nContent-Type: text/plain; charset=utf-8\n\nDevOps BH, Golang is Life, Here's your number: one\n\n$ curl -i -Xget localhost:8080/two \nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 01:25:39 GMT\nContent-Length: 51\nContent-Type: text/plain; charset=utf-8\n\nDevOps BH, Golang is Life, Here's your number: two\n\n$ curl -i -Xget localhost:8080/three\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 01:25:39 GMT\nContent-Length: 51\nContent-Type: text/plain; charset=utf-8\n\nDevOps BH, Golang is Life, Here's your number: three\n\n$ curl -i -Xget localhost:8080/four\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 01:25:39 GMT\nContent-Length: 51\nContent-Type: text/plain; charset=utf-8\n\nDevOps BH, Golang is Life, Here's your number: four\n\n$ curl -i -Xget localhost:8080/eleven\n\nHTTP/1.1 404 Not Found\nDate: Sat, 02 Feb 2019 01:26:57 GMT\nContent-Length: 42\nContent-Type: text/plain; charset=utf-8\n\nThat's not a supported number new Ghoper!\n```\n\n### Testing Http endpoints\n\nTesting http endpoints is extremely easy in Go, and doesn’t even require you to actually listen on any ports! The httptest package provides a few handy utilities, including NewRecorder which implements http.ResponseWriter and allows you to effectively make an http request by calling ServeHTTP directly. Here’s an example of a test for our previously \nimplemented numberDumperInt and numberDumperString, commented with what exactly is happening:\n\nLet's test the api above, to see the behavior and how easy it is to use tests using endpoints...\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t. \"testing\"\n)\n\nfunc TestNumberDumperInt(t *T) {\n\t// We first create the http.Handler we wish to test\n\tn := numberDumperInt(3)\n\n\t// We create an http.Request object to test with. The http.Request is\n\t// totally customizable in every way that a real-life http request is, so\n\t// even the most intricate behavior can be tested\n\tr, _ := http.NewRequest(\"GET\", \"/one\", nil)\n\n\t// httptest.Recorder implements the http.ResponseWriter interface, and as\n\t// such can be passed into ServeHTTP to receive the response. It will act as\n\t// if all data being given to it is being sent to a real client, when in\n\t// reality it's being buffered for later observation\n\tw := httptest.NewRecorder()\n\n\t// Pass in our httptest.Recorder and http.Request to our numberDumper. At\n\t// this point the numberDumper will act just as if it was responding to a\n\t// real request\n\tn.ServeHTTP(w, r)\n\n\t// httptest.Recorder gives a number of fields and methods which can be used\n\t// to observe the response made to our request. Here we check the response\n\t// code\n\tif w.Code != 200 {\n\t\tt.Fatalf(\"wrong code returned: %d\", w.Code)\n\t}\n\n\t// We can also get the full body out of the httptest.Recorder, and check\n\t// that its contents are what we expect\n\tbody := w.Body.String()\n\n\tif body != fmt.Sprintf(\"DevOps BH, Golang is Life, Here's your number: 3\\n\") {\n\t\tt.Fatalf(\"wrong body returned: %s\", body)\n\t}\n}\n```\n\nIn this way it’s easy to create tests for your individual components that you are using to build your application, keeping the tests near to the functionality they’re testing.\n**Note:** if you ever do need to spin up a test server in your tests, httptest also provides a way to create a server listening on a random open port for use in tests as well.\n\nRun go\n```bash\n$ go test \n```\n\nOutput:\n```bash\nPASS\nok  \tnet-http/tests-endpoints\t0.002s\n\n```\n\n### Http Shutdown Gracefully\n\n```go\npackage main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"sync\"\n\t\"time\"\n)\n\n// HTMLServer represents the web service that serves up HTML\ntype GoServerHttp struct {\n\tserver *http.Server\n\twg     sync.WaitGroup\n}\n\nfunc indexHandler(w http.ResponseWriter, req *http.Request) {\n\tw.Write([]byte(`\n\t\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\u003chead\u003e\n  \u003cmeta charset=\"utf-8\"\u003e\n  \u003cmeta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\"\u003e\n  \u003ctitle\u003eGolang/DevOpsBH\u003c/title\u003e\n\n  \u003cstyle\u003e\n  body {\n  background-color: #424242;\n  color: #F6F6F6;\n  text-align: center;\n  font-family: Helvetica, Arial, sans-serif;\n  font-size: 20px;\n  }\n  h1, h2, h3 {\n  margin: 0;\n  line-height: 1.5;\n  }\n  .print-container {\n  background-color: rgba(0, 0, 0, .3);\n  padding: 15px;\n  margin: 30px auto;\n  width: 50%;\n  border-radius: 4px;\n  }\n\u003c/style\u003e\n\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"print-container\"\u003e\n  \u003ch1\u003e{{ .Name }}\u003c/h1\u003e\n  \u003ch2\u003eWorkshop Golang for DevOps!\u003c/h2\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n\t`))\n}\n\nfunc Ping(w http.ResponseWriter, req *http.Request) {\n\tw.Write([]byte(`{\"status\":\"success\",\"msg\":\"Devops BH for Golang StartServer!\"}`))\n}\n\nfunc main() {\n\t// DefaultServeMux\n\tmux := http.NewServeMux()\n\n\t// POST handler /api/v1/ping\n\thandlerApiPing := http.HandlerFunc(Ping)\n\n\t// handler ping\n\tmux.Handle(\"/v1/api/ping\", handlerApiPing)\n\n\t// templates/index html\n\t// if you want to activate this handler, the directory templates\n\t// where the html file is located must\n\t// be sent next to the binary to work, as it needs to parse the html\n\t// mux.HandleFunc(\"/\", tpl.ShowHtml)\n\n\t// this handler implements the version\n\t// that does not need the html file\n\tmux.Handle(\"/\", http.HandlerFunc(indexHandler))\n\n\t// Create the HTML Server\n\tApiServer := GoServerHttp{\n\t\tserver: \u0026http.Server{\n\t\t\tAddr:           \":8080\",\n\t\t\tHandler:        mux,\n\t\t\tReadTimeout:    10 * time.Second,\n\t\t\tWriteTimeout:   20 * time.Second,\n\t\t\tMaxHeaderBytes: 1 \u003c\u003c 25, //32Mb\n\t\t},\n\t}\n\n\tgo func() {\n\n\t\tlog.Printf(\"\\nServer run :8080\\n\")\n\t\t// service connections\n\t\tif err := ApiServer.server.ListenAndServe(); err != nil {\n\t\t\tlog.Printf(\"listen: %s\\n\", err)\n\t\t}\n\t}()\n\n\tvar errs = make(chan error, 2)\n\n\tgo func() {\n\t\t// Setting up signal capturing\n\t\tc := make(chan os.Signal)\n\t\tsignal.Notify(c, os.Interrupt)\n\t\terrs \u003c- fmt.Errorf(\"Notify here: %s\", \u003c-c)\n\n\t}()\n\n\tstop := make(chan os.Signal, 1)\n\tsignal.Notify(stop, os.Interrupt)\n\n\t// Waiting for SIGINT (pkill -2)\n\t//\u003c-errs\n\n\t// Wait for interrupt signal to gracefully shutdown the server with\n\t// a timeout of 5 seconds.\n\t//quit := make(chan os.Signal)\n\t//signal.Notify(quit, os.Interrupt)\n\t//\u003c-quit\n\t\u003c-stop\n\n\tlog.Println(\"Shutdown Server ...\")\n\t// ... here is the code to close all\n\t// ...\n\t// ....\n\n\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\tdefer cancel()\n\n\tif err := ApiServer.server.Shutdown(ctx); err != nil {\n\t\tlog.Fatal(\"Server Shutdown now:\", err)\n\t\t// ... here is the code to close all error context\n\t\t// ...\n\t\t// ....\n\t}\n\n\t// execute finish\n\tlog.Println(\"Server exist\")\n\n\t\u003c-errs\n}\n```\n\nGo to the browser and type:\n```bash\nhttp://localhost:8080\n```\n\nMaking a request in your api:\n```bash\n$ curl -i -Xget localhost:8080/v1/api/ping\n\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 02:32:32 GMT\nContent-Length: 62\nContent-Type: text/plain; charset=utf-8\n\n{\"status\":\"success\",\"msg\":\"Devops BH for Golang StartServer!\"}%   \n```\n\nAfter stopping the program, with CTRL + C, look what will happen.\n```bash\n2019/02/02 00:55:30 \nServer run :8080\n^C2019/02/02 00:55:31 Shutdown Server ...\n2019/02/02 00:55:31 Server exist\n2019/02/02 00:55:31 listen: http: Server closed\n```\n\nNow let's try using the kill command\n```bash\n$ ps aux | grep \"name-api\"\n$ kill -SIGINT \u003cPID\u003e\n```\n\nLook at the exit:\n```bash\n2019/02/02 00:52:24 \nServer run :8080\n2019/02/02 00:55:10 Shutdown Server ...\n2019/02/02 00:55:10 listen: http: Server closed\n2019/02/02 00:55:10 Server exist\n```\n\n### Middleware\n\nServing endpoints is nice, but often there’s functionality you need to run for every request before the actual endpoint’s handler is run. For example, access logging. A middleware component is one which implements http.Handler, but will actually pass the request off to another http.Handler after doing some set of actions. The http.ServeMux we looked at earlier is actually an example of middleware, since it passes the request off to another http.Handler for actual processing. \n\nThere are several ways to implement a Middleware, but the concept behind everything is the same for everyone, we will always have to return a return http.HandlerFunc, all libs have done this way, there are very elegant implementations and several libs on the internet to do this.\n\nLet's implement our Middlewares and see how it works in practice.\n\nCome with me, now that things start to get cool.\n\nHere’s an example of our previous example with some logging middleware:\n\nCheck the code below:\n```go\npackage main\n\nimport (\n\t\"io\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n)\n\n// color terminal\nvar Expre = \"\\033[5m%s \\033[0;103m%s\\033[0m \\033[0;93m%s\\033[0m \\033[1;44m%s\\033[0m\"\n\nfunc Ping(w http.ResponseWriter, r *http.Request) {\n\n\tjson := `{\"status\":\"success\",\"msg\":\"pong\"}`\n\tw.Write([]byte(json))\n}\n\n// This middleware is responsible for holding up when we have a\n// very large number of accesses in a very small time interval,\n// depending on the capacity of your traffic, cpu and memory.\n// It is one of the favorite middlewares, it is very powerful,\n// not only determines the number of clients, but it does\n// not have to lose in the requests sent.\nfunc MaxClients(n int) Adapter {\n\tsema := make(chan struct{}, n)\n\treturn func(h http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tsema \u003c- struct{}{}\n\t\t\tdefer func() { \u003c-sema }()\n\t\t\th.ServeHTTP(w, r)\n\t\t})\n\t}\n}\n\n// This middleware is only a simulation, to implement the\n// jwt in Go is very quiet, I will\n// demonstrate in other topics below.\nfunc AuthJwt() Adapter {\n\t//s1 := logg.Start()\n\treturn func(h http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t//if gjwt.CheckJwt(w, r) {\n\t\t\tif r.Header.Get(\"X-KEY\") == \"123\" {\n\t\t\t\th.ServeHTTP(w, r)\n\t\t\t} else {\n\t\t\t\tmsgjson := `{\"status\":\"error\",\"message\":\"error in Jwt!\"}`\n\t\t\t\tw.Header().Set(\"Content-Type\", \"application/json; charset=utf-8\")\n\t\t\t\tw.WriteHeader(http.StatusUnauthorized)\n\t\t\t\tio.WriteString(w, msgjson)\n\t\t\t\t//logg.Show(r.URL.Path, strings.ToUpper(r.Method), \"error\", s1)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// Middleware Logger\nfunc Logger(name string) Adapter {\n\treturn func(h http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tstart := time.Now()\n\t\t\th.ServeHTTP(w, r)\n\t\t\tlog.Printf(\n\t\t\t\t\"%s %s %s %s\",\n\t\t\t\tr.Method,\n\t\t\t\tr.RequestURI,\n\t\t\t\tname,\n\t\t\t\ttime.Since(start),\n\t\t\t)\n\t\t})\n\t}\n}\n\n// Middleware Logger\nfunc LoggerColor(name string) Adapter {\n\treturn func(h http.Handler) http.Handler {\n\t\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\tstart := time.Now()\n\t\t\th.ServeHTTP(w, r)\n\t\t\tlog.Printf(\n\t\t\t\tExpre,\n\t\t\t\tr.Method,\n\t\t\t\tr.RequestURI,\n\t\t\t\tname,\n\t\t\t\ttime.Since(start),\n\t\t\t)\n\t\t})\n\t}\n}\n\ntype Adapter func(http.Handler) http.Handler\n\n// Middleware\nfunc Middleware(h http.Handler, adapters ...Adapter) http.Handler {\n\tfor _, adapter := range adapters {\n\t\th = adapter(h)\n\t}\n\treturn h\n}\n\nfunc main() {\n\n\tmux := http.NewServeMux()\n\n\thandlerApiPing := http.HandlerFunc(Ping)\n\n\t// generate token jwt\n\t// handler token\n\tmux.Handle(\"/v1/api/ping\",\n\t\tMiddleware(handlerApiPing,\n\t\t\tLogger(\"ping\"),\n\t\t))\n\n\tmux.Handle(\"/v1/api/login\",\n\t\tMiddleware(handlerApiPing,\n\t\t\tAuthJwt(),\n\t\t\t//Logger(\"login\"),\n\t\t\tLoggerColor(\"login\"),\n\t\t))\n\n\t// show run server\n\tlog.Printf(\"\\nServer run :8080\\n\")\n\n\t// Listen\n\tlog.Fatal(http.ListenAndServe(\":8080\", mux))\n}\n```\n\n```bash\n$ go run api-server-middleware.go\n```\n\n```bash\n$ curl -i -Xget localhost:8080/v1/api/login -H \"X-KEY: 123\"\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 03:37:12 GMT\nContent-Length: 33\nContent-Type: text/plain; charset=utf-8\n\n{\"status\":\"success\",\"msg\":\"pong\"}% \n```\n\n```bash\n$ curl -i -Xget localhost:8080/v1/api/login -H \"X-KEY: 123454\"\nHTTP/1.1 401 Unauthorized\nContent-Type: application/json; charset=utf-8\nDate: Sat, 02 Feb 2019 03:43:39 GMT\nContent-Length: 44\n\n{\"status\":\"error\",\"message\":\"error in Jwt!\"}% \n```\n\n```bash\n$ curl -i -Xget localhost:8080/v1/api/ping\nHTTP/1.1 200 OK\nDate: Sat, 02 Feb 2019 03:43:57 GMT\nContent-Length: 33\nContent-Type: text/plain; charset=utf-8\n\n{\"status\":\"success\",\"msg\":\"pong\"}% \n```\n\n### http DetectContentType\n\nDetectContentType implements the algorithm described at [mimesniff](https://mimesniff.spec.whatwg.org/) to determine the Content-Type of the given data. It considers at most the first 512 bytes of data. DetectContentType always returns a valid MIME type: if it cannot determine a more specific one, it returns \"application/octet-stream\". \n\n ```go\n func DetectContentType(data []byte) string\n ```\n\nLet's now visualize a code that is will simply open the file to discover its content-type.\n\nWe see that we can use the http.DetectContentType function to work together even without being an API directly.\n\nCheck the code below:\n```go\nimport (\n    \"fmt\"\n    \"net/http\"\n    \"os\"\n)\n\nfunc main() {\n\n    // Open File\n    f, err := os.Open(\"./jeff-super.jpeg\")\n    if err != nil {\n        panic(err)\n    }\n    defer f.Close()\n\n    // Get the content\n    contentType, err := GetFileContentType(f)\n    if err != nil {\n        panic(err)\n    }\n\n    fmt.Println(\"Content Type: \" + contentType)\n}\n\nfunc GetFileContentType(out *os.File) (string, error) {\n\n    // Only the first 512 bytes are used to sniff the content type.\n    buffer := make([]byte, 512)\n\n    _, err := out.Read(buffer)\n    if err != nil {\n        return \"\", err\n    }\n\n    // Use the net/http package's handy DectectContentType function. Always returns a valid\n    // content-type by returning \"application/octet-stream\" if no others seemed to match.\n    contentType := http.DetectContentType(buffer)\n\n    return contentType, nil\n}\n```\n\nOutput:\n```bash\nContent Type: image/jpeg\n```\n","funding_links":[],"categories":["Others","Repositories"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjeffotoni%2Fgoworkshopdevops/lists"}