Skip to content
Snippets Groups Projects
Commit 0653c318 authored by Mathilde Hertaas's avatar Mathilde Hertaas
Browse files

pupolation info is implemented with correct year limit

parent f61a72d0
No related branches found
No related tags found
No related merge requests found
# Cloud Project
### Assignment 1
## Kjøre koden
koden kjøres ved å skrive go run main.go i temrinalen
- Da blir du eventuelt automatisk sendt til
http://localhost:8080/
Dette er Hjemmeside
- Eventuelt kan du bruke fremgangsmåtene under Endepunkter for å navigere applikajsonen
# Endepunkter
1. Hente informasjon om et land basert på en 2-letter country codes (ISO 3166-2).
* Endpoint: /countryinfo/v1/info/{country_code}{?limit=10}
* Metode: GET
* Eksempel: http://localhost:8080/countryinfo/v1/info/NO
# Hjemmeside (/)
## Hjemmeside (/)
Når du åpner API-et uten spesifikke forespørsler (http://localhost:8080/),
vil du bli sendt til en JSON-side med informasjon om hvordan du bruker API-et.
......@@ -17,4 +16,18 @@ Her får du informasjon om de tre endepunktene som er tilgjengelige:
2. populasjon
3. status
Du får også se hvordan riktig format av url forespørsel til en av disse endepunktene
vil se ut og eksempler på riktig bruk.
\ No newline at end of file
vil se ut og eksempler på riktig bruk.
## Endepunkter
#info
1. Hente informasjon om et land basert på en 2-letter country codes (ISO 3166-2).
* Endpoint: /countryinfo/v1/info/{country_code}{?limit=10}
* Metode: GET
* Eksempel: http://localhost:8080/countryinfo/v1/info/NO?limit=4
#populasjon
2. Hente populasjonsdata
GET http://localhost:8080/population/NO
GET http://localhost:8080/population/NO?limit=2010-2015
package handelers
\ No newline at end of file
package handelers
import (
"encoding/json"
"fmt"
"math"
"net/http"
"strconv"
"strings"
)
// responsstruktur for befolkningsdata
type PopulationResponse struct {
Error bool `json:"error"`
Msg string `json:"msg"`
Data []Country `json:"data"`
}
// land og dens befolkningsdata
type Country struct {
Name string `json:"country"`
Code string `json:"iso3"` // Trebokstavskode (ISO 3166-1 alpha-3)
PopulationCounts []PopulationCount `json:"populationCounts"`
}
// befolkningsdate for et bestemt år (brukes i den endelige repsonsen under values)
type PopulationCount struct {
Year int `json:"year"`
Value int `json:"value"`
}
// Responsstruktur for vårt API(det som vises på skjerm)
type PopulationAPIResponse struct {
Name string `json:"land"`
Gjennomsnitt int `json:"gjennomsnittlig populasjon"`
Values []PopulationCount `json:"årlige populasjoner"`
}
// ISO 3166-1 alpha-2 til alpha-3 landkoder
var isoAlpha2ToAlpha3 = make(map[string]string)
// Henter befolkningsdata fra eksternt API
func fetchPopulationData() (*PopulationResponse, error) {
url := "https://countriesnow.space/api/v0.1/countries/population"
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
var data PopulationResponse
err = json.NewDecoder(resp.Body).Decode(&data)
if err != nil {
return nil, err
}
// Bygg dynamisk oppslagskart for landkoder
for _, country := range data.Data {
if len(country.Code) >= 2 {
isoAlpha2ToAlpha3[strings.ToUpper(country.Code[:2])] = country.Code // F.eks. NO → NOR
}
}
return &data, nil
}
// Henter befolkningsdata for et spesifikt land og filtrerer etter år
func getPopulationForCountry(alpha2Code string, startYear, endYear int) (*PopulationAPIResponse, error) {
data, err := fetchPopulationData()
if err != nil {
return nil, err
}
// Konverter ISO 3166-1 alpha-2 til alpha-3
alpha3Code, exists := isoAlpha2ToAlpha3[strings.ToUpper(alpha2Code)]
if !exists {
return nil, fmt.Errorf("invalid country code: %s", alpha2Code)
}
// Finn landet basert på ISO 3166-1 alpha-3 kode
var countryData *Country
for _, c := range data.Data {
if c.Code == alpha3Code {
countryData = &c
break
}
}
if countryData == nil {
return nil, fmt.Errorf("country not found")
}
// Filtrer basert på år
// en tom liste fyllt med PopulationCount, altså fylles med spesifikke år og antall
var filteredValues []PopulationCount
var total int
count := 0
// itererer over alle verdiene som følger med et land sin populasjonsdata
// over alle årstall-verdi strukturene
for _, stk := range countryData.PopulationCounts {
if (startYear == 0 || stk.Year >= startYear) && (endYear == 0 || stk.Year <= endYear) {
filteredValues = append(filteredValues, stk)
total += stk.Value
count++
}
}
// Beregn gjennomsnitt
mean := 0
if count > 0 {
mean = int(math.Round(float64(total) / float64(count)))
}
return &PopulationAPIResponse{
Name: countryData.Name,
Gjennomsnitt: mean,
Values: filteredValues,
}, nil
}
func PopulationHandler(w http.ResponseWriter, r *http.Request) {
// r.URL.Path er den fulle URL som ble sendt til serveren altså /population/NO
// deretter fjerner den /population/ så vi sitter igjen med NO
path := strings.TrimPrefix(r.URL.Path, "/population/")
// NO
countryCode := strings.ToUpper(path) // ISO 3166-2-kode
query := r.URL.RawQuery
limit := strings.Replace(query, "limit=","",1)
startYear, endYear := 0, 0
if len(limit)>0 {
yearRange := strings.Split(limit, "-")
if len(yearRange) == 2 {
startYear, _ = strconv.Atoi(yearRange[0])
endYear, _ = strconv.Atoi(yearRange[1])
} else {
fmt.Println("Year range format is incorrect")
}
}
result, err := getPopulationForCountry(countryCode, startYear, endYear)
if err != nil {
http.Error(w, err.Error(), http.StatusNotFound)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(result)
}
\ No newline at end of file
......@@ -18,6 +18,7 @@ func main() {
})
http.HandleFunc("/", handelers.HomeHandler)
http.HandleFunc("/countryinfo/v1/info/", handelers.CountryInfoHandler)
http.HandleFunc("/population/", handelers.PopulationHandler)
fmt.Println("Server running on port 8080...")
......
package main
import (
"fmt"
"net/http"
"time"
"git.gvk.idi.ntnu.no/Mathilde/cloud/handelers"
)
var serviceStartTime time.Time
func main() {
serviceStartTime = time.Now()
// Send serviceStartTime til DiagnosticsHandler
http.HandleFunc("/status/", func(w http.ResponseWriter, r *http.Request) {
handelers.DiagnosticsHandler(w, r, serviceStartTime)
})
http.HandleFunc("/", handelers.HomeHandler)
http.HandleFunc("/countryinfo/v1/info/", handelers.CountryInfoHandler)
fmt.Println("Server running on port 8080...")
if err := http.ListenAndServe(":8080", nil); err != nil {
fmt.Printf("Server failed to start: %s\n", err)
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment