Table of content
- Introduction
- Objective
- Function main
- Get Method
- Full Source Code
- Go REST API Unit testing
- Executing Go Unit Testing
- Go Source Build and Run
- Real time test
Introduction
We have learnt how to create simple REST API in the previous blog.
We will now see the below topics in this blog,
- How to add REST API versioning
- How to create query string parameters
- How to add basic authentication to REST API
- How to write Go unit testing for API authentication code
- How to test the REST API with authentication in real time
Objective
- We will be creating REST API that listens on
localhostport1357and has the API versioning with query string parameter. - Sample URL format we are planning to create,
http://localhost:1357/api/v1/PersonId/Id456
Now let us start creating the code!
Function main
Add the below code function main()
Adding API Versioning and Basic authentication
// Define gin router
router := gin.Default()
// Create Sub Router for customized API version and basic auth
subRouterAuthenticated := router.Group("/api/v1/PersonId", gin.BasicAuth(gin.Accounts{
"basic_auth_user": "userpass",
}))
Passing Query String Parameters
subRouterAuthenticated.GET("/:IdValue", GetMethod)
REST API Listening on Port
listenPort := "1357"
// Listen and Server on the LocalHost:Port
router.Run(":"+listenPort)
Get Method
- Define a
GetMethodfunction and add the following code - It fetches and prints the
Person IdValuefrom the query string parameter passed in the API URL
func GetMethod(c *gin.Context) {
fmt.Println("\n'GetMethod' called")
IdValue := c.Params.ByName("IdValue")
message := "GetMethod Called With Param: " + IdValue
c.JSON(http.StatusOK, message)
// Print the Request Payload in console
ReqPayload := make([]byte, 1024)
ReqPayload, err := c.GetRawData()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Request Payload Data: ", string(ReqPayload))
}
Full Source Code
// Golang REST API with API versioning and Basic Auth
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func GetMethod(c *gin.Context) {
fmt.Println("\n'GetMethod' called")
IdValue := c.Params.ByName("IdValue")
message := "GetMethod Called With Param: " + IdValue
c.JSON(http.StatusOK, message)
ReqPayload := make([]byte, 1024)
ReqPayload, err := c.GetRawData()
if err != nil {
fmt.Println(err)
return
}
fmt.Println("Request Payload Data: ", string(ReqPayload))
}
func main() {
router := gin.Default()
// Create Sub Router for customised API version
subRouterAuthenticated := router.Group("/api/v1/PersonId", gin.BasicAuth(gin.Accounts{
"admin": "adminpass",
}))
subRouterAuthenticated.GET("/:IdValue", GetMethod)
listenPort := "1357"
// Listen and Server on the LocalHost:Port
router.Run(":"+listenPort)
}
Go REST API Unit testing
Go
testingmodule can be used for creating unit testing code for Go sourceGo Unit testing code looks as below,
// Golang REST API unit testing program
package main
import (
"testing"
"net/http"
"net/http/httptest"
"fmt"
"bytes"
"github.com/gin-gonic/gin"
)
func TestGetMethod(t *testing.T) {
// Switch to test mode so you don't get such noisy output
gin.SetMode(gin.TestMode)
// Create the mock request you'd like to test. Make sure the second argument
// here is the same as one of the routes you defined in the router setup
// block!
body := bytes.NewBuffer([]byte("{\"ApiTest\":\"GetReq\"}"))
req, err := http.NewRequest("GET", "/api/v1/PersonId/Id456", body)
if err != nil {
t.Fatalf("Couldn't create request: %v\n", err)
}
req.Header.Set("Content-Type", "application/json")
req.SetBasicAuth("admin", "adminpass")
// Setup your router, just like you did in your main function, and
// register your routes
router := gin.Default()
router.GET("/api/v1/PersonId/:IdValue", GetMethod)
// Create a response recorder so you can inspect the response
w := httptest.NewRecorder()
// Perform the request
router.ServeHTTP(w, req)
fmt.Println(w.Body)
}
Executing Go Unit Testing
Run the command go test and it shows the below output in console,
'GetMethod' called
Request Payload Data: {"ApiTest":"GetReq"}
[GIN] 2020/08/03 - 12:26:29 | 200 | 7.2µs | | GET "/api/v1/PersonId/Id456"
"GetMethod Called With Param: Id456"
PASS
ok apiauth 0.008s
This confirms the REST API code we have created is working fine.
Go Source Build and Run
- If we want to test the API in our server, on which the code is created, run the below command
go run apiauth.go
- This command invokes the REST API on
localhostport1357& console shows the below output,
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /api/v1/PersonId/:IdValue --> main.GetMethod (4 handlers)
[GIN-debug] Listening and serving HTTP on :1357
- Then proceed to test the REST API real-time
Real time test
CURL method
Run curl with basic authentication user-password
curl -u username:password -i -X GET http://localhost:1357/api/v1/PersonId/Id456
- This will show the output as below in Console
"GetMethod Called With Param: Id456"
Ngrok method
- Execute the
go runcommand to start the API,go run apiauth.go - To verify our REST API, we need to expose the localhost of the server to internet
- So we can use "ngrok" for this purpose
- Download ngrok here
- Extract the ngrok executable in some location on your server.
- Start ngrok on port 1357(Port defined in go API code) as below,
./ngrok http 1357 and prints the output as follows in console
ngrok by @inconshreveable (Ctrl+C to quit)
Session Status online
Session Expires 7 hours, 12 minutes
Version 2.3.35
Region United States (us)
Web Interface http://127.0.0.1:4040
Forwarding http://ca6d2c4cee3e.ngrok.io -> http://localhost:4000
Forwarding https://ca6d2c4cee3e.ngrok.io -> http://localhost:4000
ngrok generates a dynamic URL. For ex:
http://ca6d2c4cee3e.ngrok.ioThe REST API can be tested by adding the URL in browser address bar,
http://ca6d2c4cee3e.ngrok.io/api/v1/PersonId/Id456Browser will prompt to enter the authentication details. So enter credentials

After entering the credential, the browser should show,
GetMethod Called With Param: Id456

Key Take away
We have seen the below major topics in this blog,
- Adding basic authentication to REST API
- Go unit testing for API authentication code
- Testing the REST API with basic authentication in real time

Formed in 2009, the Archive Team (not to be confused with the archive.org Archive-It Team) is a rogue archivist collective dedicated to saving copies of rapidly dying or deleted websites for the sake of history and digital heritage. The group is 100% composed of volunteers and interested parties, and has expanded into a large amount of related projects for saving online and digital history.


Discussion (0)