From 1613e3ea5bd2dae11ab03ccf6d1d5ab853f8bf7d Mon Sep 17 00:00:00 2001
From: andmag <andmag@stud.ntnu.no>
Date: Mon, 14 Oct 2019 20:53:57 +0200
Subject: [PATCH] Optimalization and commenting

---
 cmd/main.go    |   3 ++
 country.go     | 106 +++++++++++++++++++++++++------------------------
 diagnostics.go |  23 ++++++-----
 func.go        |  28 +++++++++++++
 species.go     |  81 +++++++++++++++++++++++--------------
 struct.go      |  11 ++---
 uptime.go      |   4 +-
 7 files changed, 158 insertions(+), 98 deletions(-)
 create mode 100644 func.go

diff --git a/cmd/main.go b/cmd/main.go
index d7e4c84..a2b44d8 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -10,7 +10,10 @@ import (
 
 func main() {
 
+	// start-time
 	assignment1.Init()
+
+	// opens a port
 	port := os.Getenv("PORT")
 	if port == "" {
 		port = "8080"
diff --git a/country.go b/country.go
index fd64c49..155a5f1 100644
--- a/country.go
+++ b/country.go
@@ -7,91 +7,93 @@ import (
 	"strings"
 )
 
-func replyCountry(w http.ResponseWriter, r *http.Request, url string, url2 string) {
+// sends a request to the api and decodes the response into the country struct
+func countryRequest(url string, c *http.Client, country *Country) {
 
-	http.Header.Add(w.Header(), "content-type", "application/json")
+	// sends a request for country and gets the response
+	resp := doRequest(url, c)
 
-	req, err := http.NewRequest(http.MethodGet, url, nil)
-	if err != nil {
-		fmt.Println("Error", err)
-	}
-
-	client := http.DefaultClient
-	resp, err := client.Do(req)
+	// decodes the response into the struct
+	err := json.NewDecoder(resp.Body).Decode(&country)
 	if err != nil {
-		fmt.Println("Error", err)
+		fmt.Println("Error", err.Error())
 	}
 
+	// closes the body
 	defer resp.Body.Close()
-
-	country := &Country{}
-
-	json.NewDecoder(resp.Body).Decode(country)
-
-	replySpeciesCountry(w, r, url2, country)
-
-	json.NewEncoder(w).Encode(country)
-
 }
 
-func replySpeciesCountry(w http.ResponseWriter, r *http.Request, url string, country *Country) {
+// sends a request to the api and decodes the respone into the structs
+func speciesInCountryRequest(url string, c *http.Client, country *Country) {
 
-	req, err := http.NewRequest(http.MethodGet, url, nil)
-	if err != nil {
-		fmt.Println("Error", err)
-	}
-
-	client := http.DefaultClient
-	resp, err := client.Do(req)
-	if err != nil {
-		fmt.Println("Error", err)
-	}
-
-	defer resp.Body.Close()
+	// sends a request for species in a country and gets the response
+	resp := doRequest(url, c)
 
+	// array of results structs
 	type Result Results
 
+	// empty result struct
 	var nameAndKey = &Result{}
 
-	err2 := json.NewDecoder(resp.Body).Decode(nameAndKey)
-	if err2 != nil {
-		fmt.Println("Error", err2.Error())
+	// decodes the response into the array of results
+	err := json.NewDecoder(resp.Body).Decode(nameAndKey)
+	if err != nil {
+		fmt.Println("Error", err.Error())
 	}
 
+	// closes the body
+	defer resp.Body.Close()
+
+	// slice of species and speciesKey
 	var spec []string
 	var specKey []int
 
-	for k, v := range nameAndKey.Result {
-		fmt.Println(k)
+	// appends species and speciesKey to a list so we get two lists, one for species and one for speciesKey
+	for _, v := range nameAndKey.Result {
 		spec = append(spec, v.Species)
 		specKey = append(specKey, v.SpeciesKey)
-
 	}
 
+	// puts the lists in the country struct
 	country.Species = spec
 	country.SpeciesKey = specKey
-
 }
 
-// HandlerCountry dskjfhskjfhk
+// HandlerCountry function: handles the country endpoint
 func HandlerCountry(w http.ResponseWriter, r *http.Request) {
 
-	APIURL := "https://restcountries.eu/rest/v2/alpha/"
+	http.Header.Add(w.Header(), "content-type", "application/json")
 
-	//SJEKK LENGDE 4
+	APIURL := "https://restcountries.eu/rest/v2/alpha/"
 
+	// gets the query we want and splits the string into parts
+	urlQuery := r.URL.RawQuery
 	parts := strings.Split(r.URL.Path, "/")
-	if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "country" || parts[4] == "" {
-		status := http.StatusBadRequest
-		http.Error(w, "Expecting format /conservation/v1/country/'AlphaCode'", status)
-		return
-	}
-
+	/*
+		if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "country" || parts[4] == "" {
+			status := http.StatusBadRequest
+			http.Error(w, "Expecting format /conservation/v1/country/'AlphaCode'", status)
+			return
+		}
+	*/
+
+	// appends the country-code to the country api and appends country-code and limit to the species api
 	APIURL += parts[4]
-	APIURL2 := "http://api.gbif.org/v1/occurrence/search?country="
-	APIURL2 += parts[4]
-	APIURL2 += "?limit="
+	APIURL2 := "http://api.gbif.org/v1/occurrence/search?country=" + parts[4] + "&" + urlQuery
+
+	//empty country struct
+	country := &Country{}
 
-	replyCountry(w, r, APIURL, APIURL2)
+	// makes a client
+	client := http.DefaultClient
+
+	// makes a request for country and species in a country and decodes everything
+	countryRequest(APIURL, client, country)
+	speciesInCountryRequest(APIURL2, client, country)
 
+	// encodes everything to the browser
+	err := json.NewEncoder(w).Encode(country)
+	if err != nil {
+		fmt.Println("Error", err.Error())
+	}
 }
diff --git a/diagnostics.go b/diagnostics.go
index ec6b5b6..33cb93d 100644
--- a/diagnostics.go
+++ b/diagnostics.go
@@ -6,12 +6,7 @@ import (
 	"net/http"
 )
 
-// HandlerNil kjhfkerjhgk
-func HandlerNil(w http.ResponseWriter, r *http.Request) {
-	fmt.Println("Default Handler: Invalid request received.")
-	http.Error(w, "Invalid request", http.StatusBadRequest)
-}
-
+// gets the status code from the url/api
 func getStatusCode(URL string) int {
 	resp, err := http.Get(URL)
 	if err != nil {
@@ -20,15 +15,21 @@ func getStatusCode(URL string) int {
 	return resp.StatusCode
 }
 
-// HandlerDiag dsjfbgdfjgb
+// HandlerDiag function: handles the diag endpoint
 func HandlerDiag(w http.ResponseWriter, r *http.Request) {
 	http.Header.Add(w.Header(), "content-type", "application/json")
 
-	diagnostics := &Diag{}
-	diagnostics.Uptime = Uptime()
-	diagnostics.Version = "v1"
+	diagnostics := &Diag{}        // empty diag struct
+	diagnostics.Uptime = Uptime() // uptime in seconds
+	diagnostics.Version = "v1"    // version
+
+	// gets statuscode from the apis
 	diagnostics.Restcountries = getStatusCode("https://restcountries.eu/")
 	diagnostics.Gbif = getStatusCode("http://api.gbif.org/v1/")
 
-	json.NewEncoder(w).Encode(diagnostics)
+	// encodes everything to the browser
+	err := json.NewEncoder(w).Encode(diagnostics)
+	if err != nil {
+		fmt.Println("Error", err.Error())
+	}
 }
diff --git a/func.go b/func.go
new file mode 100644
index 0000000..336a1cc
--- /dev/null
+++ b/func.go
@@ -0,0 +1,28 @@
+package assignment1
+
+import (
+	"fmt"
+	"net/http"
+)
+
+// HandlerNil function: if the user doesn't write anything valid
+func HandlerNil(w http.ResponseWriter, r *http.Request) {
+	fmt.Println("Default Handler: Invalid request received.")
+	http.Error(w, "Invalid request", http.StatusBadRequest)
+}
+
+// handles all the requests and returns the response
+func doRequest(url string, c *http.Client) *http.Response {
+
+	req, err := http.NewRequest(http.MethodGet, url, nil)
+	if err != nil {
+		fmt.Println("Error", err)
+	}
+
+	resp, err := c.Do(req)
+	if err != nil {
+		fmt.Println("Error", err)
+	}
+
+	return resp
+}
diff --git a/species.go b/species.go
index 18102e3..ae96f4d 100644
--- a/species.go
+++ b/species.go
@@ -7,55 +7,78 @@ import (
 	"strings"
 )
 
-// HandlerSpecies kdsjfhkdjghlfdkhn
+// sends a request to the api and decodes the response into the species struct
+func speciesRequest(url string, c *http.Client, species *Species) {
+
+	// sends a request to the api and gets a response
+	resp := doRequest(url, c)
+
+	// decodes the response into the struct
+	err := json.NewDecoder(resp.Body).Decode(&species)
+	if err != nil {
+		fmt.Println("Error", err.Error())
+	}
+
+	// closes the body
+	defer resp.Body.Close()
+}
+
+// sends a request to the api and decodes the response into the year struct
+func yearRequest(url string, c *http.Client, species *Species) {
+
+	// sends a request to the api and gets a response
+	resp := doRequest(url, c)
+
+	// empty year struct
+	year := &Year{}
+
+	// decodes the response into the struct
+	err := json.NewDecoder(resp.Body).Decode(&year)
+	if err != nil {
+		fmt.Println("Error", err.Error())
+	}
+
+	// puts the year from the year struct into the species struct
+	species.Year = year.Year
+
+	// closes the body
+	defer resp.Body.Close()
+}
+
+// HandlerSpecies function: handles the species endpoint
 func HandlerSpecies(w http.ResponseWriter, r *http.Request) {
 
 	http.Header.Add(w.Header(), "content-type", "application/json")
 
+	// empty struct that will eventually contain the species values
 	species := &Species{}
 
 	APIURL := "http://api.gbif.org/v1/species/"
 
+	// splits the url so we can append user input to the apiurl
 	parts := strings.Split(r.URL.Path, "/")
+
+	// checks if it is a valid path
 	if len(parts) != 5 || parts[1] != "conservation" || parts[2] != "v1" || parts[3] != "species" || parts[4] == "" {
 		status := http.StatusBadRequest
 		http.Error(w, "Expecting format /conservation/v1/species/'speciesNumber'", status)
 		return
 	}
 
+	// Appends userinput to the apiurl
 	APIURL += parts[4]
 	APIURL2 := APIURL + "/name"
 
-	s := "species"
-	y := "year"
-
-	replySpecies(w, r, APIURL, s, species)
-	replySpecies(w, r, APIURL2, y, species)
-
-	json.NewEncoder(w).Encode(species)
-}
-
-func replySpecies(w http.ResponseWriter, r *http.Request, url string, str string, species *Species) {
-
-	req, err := http.NewRequest(http.MethodGet, url, nil)
-	if err != nil {
-		fmt.Println("Error", err)
-	}
-
+	// makes a client
 	client := http.DefaultClient
-	resp, err := client.Do(req)
-	if err != nil {
-		fmt.Println("Error", err)
-	}
 
-	defer resp.Body.Close()
+	// sends requests to the apis, and decodes everything
+	speciesRequest(APIURL, client, species)
+	yearRequest(APIURL2, client, species)
 
-	switch str {
-	case "species":
-		json.NewDecoder(resp.Body).Decode(&species)
-	case "year":
-		year := &Year{}
-		json.NewDecoder(resp.Body).Decode(&year)
-		species.Year = year.Year
+	// encodes species which now contains year as well
+	err := json.NewEncoder(w).Encode(species)
+	if err != nil {
+		fmt.Println("Error", err.Error())
 	}
 }
diff --git a/struct.go b/struct.go
index 75fa2f4..f5c00cb 100644
--- a/struct.go
+++ b/struct.go
@@ -1,6 +1,6 @@
 package assignment1
 
-// Country dslkjfslkfjl
+// Country struct: json values for a country and its species
 type Country struct {
 	Code        string   `json:"alpha2Code"`
 	Countryname string   `json:"name"`
@@ -9,17 +9,18 @@ type Country struct {
 	SpeciesKey  []int    `json:"speciesKey"`
 }
 
-// Name jdhgkjdng
+// Both struct: json values for species and speciesKey
 type Both struct {
 	Species    string `json:"species"`
 	SpeciesKey int    `json:"speciesKey"`
 }
 
+// Results struct: json value for result and contains both species and speciesKey
 type Results struct {
 	Result []Both `json:"results"`
 }
 
-// Species comment endpoint
+// Species struct: json values for one specific species
 type Species struct {
 	Key            int    `json:"key"`
 	Kingdom        string `json:"kingdom"`
@@ -32,12 +33,12 @@ type Species struct {
 	Year           string `json:"year"`
 }
 
-// Year lkerjgflkjtgj
+// Year struct: json value for a species discovery year
 type Year struct {
 	Year string `json:"bracketYear"`
 }
 
-// Diag comment endpoint
+// Diag struct:
 type Diag struct {
 	Gbif          int
 	Restcountries int
diff --git a/uptime.go b/uptime.go
index de8fe30..99d4981 100644
--- a/uptime.go
+++ b/uptime.go
@@ -4,12 +4,14 @@ import (
 	"time"
 )
 
-var startTime time.Time
+var startTime time.Time // to measure the time since the last service restart
 
+// Uptime function: returns time since start time in seconds
 func Uptime() float64 {
 	return time.Since(startTime).Seconds()
 }
 
+// Init function: begins the time
 func Init() {
 	startTime = time.Now()
 }
-- 
GitLab