Looking ahead
Its almost the end of the last semester of my studies! And I’ve finally said Good-bye to my old career. One that has helped me grow and learn how cruel life can be. The last 2 years was both a nightmare and an eye-opener, hopefully expanding my horizon further will allow me to pursue something greater than what I started with.
I love to code, but still not as confident about myself when I see others who can come up with solutions that I can figure out as quickly as they do.
Go Microservice I
This time round, we learnt about building microservices with Go. Our adjunct lecturer is really fun and interactive, the whole course was amazing as we built an api step-by-step. First we learnt how to use the HTTP service to communicate with our SQL database. Then we use the encoding library, gorilla/mux librarys to parse in the data by marshal and unmarshal to json. And learnt about Docker containers and creating instances to run the application.
For the project assignment, we were tasked to build on the existing guide to combine the two services together. What I liked most about my project was the generation of API keys. Here is a snippet of the code which I figured out to create API keys via curl.
1package routes23import (4 "net/http"56 "github.com/gorilla/mux"7)89func (api *API) getAllKeys(w http.ResponseWriter, r *http.Request) {10 key, err := api.keyController.GetAllKeys()1112 if err != nil {13 response := createResponse(Error, "Internal Server Error", nil)14 sendResponse(w, http.StatusInternalServerError, response)15 return16 }1718 response := createResponse(Message, "OK", key)19 sendResponse(w, http.StatusOK, response)20}2122func (api *API) createAPIKey(w http.ResponseWriter, r *http.Request) {23 key, err := api.keyController.CreateKey()2425 if err != nil {26 response := createResponse(Error, "Internal Server Error", nil)27 sendResponse(w, http.StatusInternalServerError, response)28 return29 }3031 response := createResponse(Message, "OK", key)32 sendResponse(w, http.StatusOK, response)33}3435func (api *API) deleteAPIKey(w http.ResponseWriter, r *http.Request) {36 vars := mux.Vars(r)37 key := vars["id"]3839 err := api.keyController.DeleteKey(key)4041 if err != nil {42 response := createResponse(Error, "error deleting key", nil)43 sendResponse(w, http.StatusNotFound, response)44 return45 }4647 response := createResponse(Message, "OK", "Deleted")48 sendResponse(w, http.StatusOK, response)49}5051func (api *API) getAPIKeyByID(w http.ResponseWriter, r *http.Request) {52 vars := mux.Vars(r)53 key := vars["id"]5455 keyResponse, err := api.keyController.GetKeyByID(key)5657 if err != nil {58 response := createResponse(Error, "error getting key", nil)59 sendResponse(w, http.StatusNotFound, response)60 return61 }6263 response := createResponse(Message, "OK", keyResponse)64 sendResponse(w, http.StatusOK, response)65}6667func (api *API) toggleAccess(w http.ResponseWriter, r *http.Request) {68 vars := mux.Vars(r)69 key := vars["id"]7071 keyResponse, err := api.keyController.ToggleAccess(key)7273 if err != nil {74 response := createResponse(Error, "error changing status", nil)75 sendResponse(w, http.StatusNotFound, response)76 return77 }7879 response := createResponse(Message, "OK", keyResponse)80 sendResponse(w, http.StatusOK, response)81}
And subsequently this are the functions that allow the basic CRUD operations. So the keys are supposed to be unique and stored in a MySQL database table. Access is granted via boolean values, which if true you are allowed to fetch requests from the api. If false, you do not have permission to access the requests.
1package controller23import (4 "crypto/rand"5 "fmt"6 "log"7 "restapi/database"8)910// Key model11type Key struct {12 ID string `json:"id,omitempty"`13 Key string `json:"key,omitempty"`14 Status bool `json:"status,omitempty"`15}1617func createAPIKey() string {18 key := make([]byte, 16)1920 if _, err := rand.Read(key); err != nil {21 panic(err)22 }23 apiKey := fmt.Sprintf("%x", key)24 return apiKey25}2627// CreateKey creates key in database28func (k *Key) CreateKey() (string, error) {29 db := database.GetInstance().GetConnection()30 defer db.Close()31 key := Key{32 Status: true,33 Key: createAPIKey(),34 }35 err := db.Save(&key)3637 if err != nil {38 return key.Key, err.Error39 }40 return "error", nil41}4243// GetAllKeys returns all the keys44func (k *Key) GetAllKeys() ([]Key, error) {45 db := database.GetInstance().GetConnection()46 defer db.Close()4748 keys := []Key{}4950 err := db.Find(&keys)5152 if err != nil {53 return keys, err.Error54 }55 return keys, nil56}5758// DeleteKey deletes course in database59func (k *Key) DeleteKey(id string) error {60 db := database.GetInstance().GetConnection()61 defer db.Close()6263 kT := Key{}64 err := db.Where("id = ?", id).First(&kT)65 if err != nil {66 return err.Error67 }6869 err = db.Delete(kT)7071 if err != nil {72 return err.Error73 }74 return nil75}7677// GetKeyByID gets the key78func (c *Key) GetKeyByID(id string) (Key, error) {79 db := database.GetInstance().GetConnection()80 defer db.Close()8182 key := Key{}8384 err := db.First(&key, id)8586 if err != nil {87 return key, err.Error88 }89 if key.Key != "" {90 return key, nil91 }9293 return key, nil94}9596// ToggleAccess gets the key97func (c *Key) ToggleAccess(id string) (Key, error) {98 db := database.GetInstance().GetConnection()99 defer db.Close()100101 key := Key{}102103 err := db.First(&key, id)104105 log.Println(key)106 newStatus := false107 if key.Status == true {108 newStatus = false109 } else {110 newStatus = true111 }112113 err = db.Model(&key).Update("status", newStatus)114115 if err != nil {116 return Key{}, nil117 }118119 return key, nil120}
Go Microservice II
So next up this week, it’ll be the last course of the entire GoSchool apprenticeship program. After this course, there is a 1hr assessment for the program to assign you to the relevant engineering department in their partnership Companies. Hopefully, i’m able to do well in this as honestly this would be my second time going through a developer assessment. And I still don’t have any confidence in being able to do well. Wish me luck!