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

changed the structure f the project and split op the main class inn different oppgaver

parent 30f29385
Branches
No related tags found
No related merge requests found
package handelers
import (
"encoding/json"
"net/http"
)
// hjemmeside for kjøring av applikasjonen som sender deg direkte til en side uten spesifiksejoner gitt
// av brukeren.
//INFO
func HomeHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := map[string]interface{}{
"WELCOME": "Welcome to the Country Info API",
"endpoints": map[string]interface{}{
"Get Country Info": map[string]string{
"Description": "Get country details including cities, population, and more.",
"URL Format": "http://localhost:8080/countryinfo/v1/info/{country_code}{?limit=10}",
"Example": "http://localhost:8080/countryinfo/v1/info/NO?cities=5",
},
"Get status info" : map[string]string{
"Description" : "Get information about the API statuses",
"URL" : "http://localhost:8080/status/",
},
},
}
json.NewEncoder(w).Encode(response)
}
\ No newline at end of file
package handelers
import(
"strings"
"net/http"
"fmt"
"strconv"
"encoding/json"
)
// Henter landdata fra REST Countries API
func getCountryDataByCode(countryCode string) (*CountryInfo, error) {
url := fmt.Sprintf("http://129.241.150.113:8080/v3.1/alpha/%s", countryCode)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error retrieving country data, status code: %d", resp.StatusCode)
}
var countries []CountryInfo
if err := json.NewDecoder(resp.Body).Decode(&countries); err != nil {
return nil, err
}
if len(countries) == 0 {
return nil, fmt.Errorf("country not found for code: %s", countryCode)
}
return &countries[0], nil
}
func CountryInfoHandler(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) < 5 {
http.Error(w, "Invalid format. Use: /countryinfo/v1/info/{countryCode}", http.StatusBadRequest)
return
}
countryCode := parts[4]
// Hent landdata fra REST Countries API
country, err := getCountryDataByCode(countryCode)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Hent antall byer som skal vises fra URL-parameteren (default til 10)
// F.eks. /countryinfo/v1/info/NO?cities=5
cityCount := 10 // Standardverdi
cityCountStr := r.URL.Query().Get("cities") // Hent "cities" parameteren
if cityCountStr != "" {
// Prøv å konvertere parameteren til et heltall
if count, err := strconv.Atoi(cityCountStr); err == nil && count > 0 {
cityCount = count
}
}
// Hent byene fra countriesnow API
cities, err := getCitiesByCountry(country.Name.Common)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Hvis det er flere enn det brukeren ønsker, begrens listen
if len(cities) > cityCount {
cities = cities[:cityCount]
}
// Feilsøking: Hvis ingen byer ble funnet
if len(cities) == 0 {
fmt.Printf("No cities found for %s\n", country.Name.Common)
}
// Bygg kombinert respons
response := CombinedInfo{
Name: country.Name.Common,
Continents: country.Continents,
Population: country.Population,
Languages: country.Languages,
Borders: country.Borders,
Flags: country.Flags.PNG,
Capital: "",
Cities: strings.Join(cities, ", "), // Legg til de 10 første byene som en kommaseparert liste
}
if len(country.Capital) > 0 {
response.Capital = country.Capital[0]
}
// Sett Content-Type til application/json
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func getCitiesByCountry(countryName string) ([]string, error) {
url := fmt.Sprintf("https://countriesnow.space/api/v0.1/countries/cities/q?country=%s", countryName)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error retrieving cities, status code: %d", resp.StatusCode)
}
var responseBody map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
return nil, err
}
if cities, ok := responseBody["data"].([]interface{}); ok {
var cityList []string
for _, city := range cities {
if cityStr, ok := city.(string); ok {
cityList = append(cityList, cityStr)
}
}
// Hvis ingen byer er funnet, returner en feilmelding
if len(cityList) == 0 {
fmt.Println("No cities found in the response.")
}
return cityList, nil
}
return nil, fmt.Errorf("no cities found for country %s", countryName)
}
\ No newline at end of file
package handelers
\ No newline at end of file
package handelers
import (
"net/http"
"time"
"fmt"
"encoding/json"
)
var serviceStartTime time.Time
// Funksjon for å hente statuskode fra et API
func getAPIStatus(url string) (int, error) {
resp, err := http.Get(url)
if err != nil {
return 0, err
}
defer resp.Body.Close()
// Returner HTTP-statuskoden
return resp.StatusCode, nil
}
// Funksjon for å beregne oppetid
func getUptime() int64 {
return int64(time.Since(serviceStartTime).Seconds())
}
// Handler for Diagnostics endpoint
func DiagnosticsHandler(w http.ResponseWriter, r *http.Request) {
serviceStartTime = time.Now()
// Hent statuskoder fra eksterne API-er
countriesNowStatus, err := getAPIStatus("http://129.241.150.113:3500/api/v0.1/countries")
if err != nil {
http.Error(w, "Error fetching CountriesNow status", http.StatusInternalServerError)
return
}
restCountriesStatus, err := getAPIStatus("http://129.241.150.113:8080/v3.1/all") //funker med all
if err != nil {
http.Error(w, "Error fetching RestCountries status", http.StatusInternalServerError)
return
}
// Bygg responsen med statusinformasjon
response := map[string]interface{}{
"countriesnowapi": fmt.Sprintf("%d", countriesNowStatus),
"restcountriesapi": fmt.Sprintf("%d", restCountriesStatus),
"version": "v1", // Versjon av API
"uptime": getUptime(), // Oppetid i sekunder
}
// Sett Content-Type til application/json
w.Header().Set("Content-Type", "application/json")
// Returner JSON-responsen
json.NewEncoder(w).Encode(response)
}
\ No newline at end of file
package handelers
type Flags struct{
PNG string `json:"png"`
}
// Struktur for data fra REST Countries API
type CountryInfo struct {
Name struct {
Common string `json:"common"`
Official string `json:"official"`
} `json:"name"`
Capital []string `json:"capital"`
Languages map[string]string `json:"languages"`
Continents []string `json:"continents"`
Borders []string `json:"borders"`
Population int `json:"population"`
Flags Flags `json:"flags"`
}
type CityInfo struct {
Cities []string `json:"cities"`
}
// Struktur for kombinert respons
type CombinedInfo struct {
Name string `json:"name"`
Continents []string `json:"continenents"`
Population int `json:"population"`
Languages map[string]string `json:"languages"`
Borders []string `json:"borders"`
Flags string `json:"flags"`
Capital string `json:"capital"`
Cities string `json:"cities"`
}
\ No newline at end of file
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
"strings"
"strconv"
"git.gvk.idi.ntnu.no/Mathilde/cloud/handelers"
)
var serviceStartTime time.Time
// Funksjon for å hente statuskode fra et API
func getAPIStatus(url string) (int, error) {
resp, err := http.Get(url)
if err != nil {
return 0, err
}
defer resp.Body.Close()
// Returner HTTP-statuskoden
return resp.StatusCode, nil
}
// Funksjon for å beregne oppetid
func getUptime() int64 {
return int64(time.Since(serviceStartTime).Seconds())
}
// Handler for Diagnostics endpoint
func diagnosticsHandler(w http.ResponseWriter, r *http.Request) {
// Hent statuskoder fra eksterne API-er
countriesNowStatus, err := getAPIStatus("http://129.241.150.113:3500/api/v0.1/countries")
if err != nil {
http.Error(w, "Error fetching CountriesNow status", http.StatusInternalServerError)
return
}
restCountriesStatus, err := getAPIStatus("http://129.241.150.113:8080/v3.1/all") //funker med all
if err != nil {
http.Error(w, "Error fetching RestCountries status", http.StatusInternalServerError)
return
}
// Bygg responsen med statusinformasjon
response := map[string]interface{}{
"countriesnowapi": fmt.Sprintf("%d", countriesNowStatus),
"restcountriesapi": fmt.Sprintf("%d", restCountriesStatus),
"version": "v1", // Versjon av API
"uptime": getUptime(), // Oppetid i sekunder
}
// Sett Content-Type til application/json
w.Header().Set("Content-Type", "application/json")
// Returner JSON-responsen
json.NewEncoder(w).Encode(response)
}
type Flags struct{
PNG string `json:"png"`
}
// Struktur for data fra REST Countries API
type CountryInfo struct {
Name struct {
Common string `json:"common"`
Official string `json:"official"`
} `json:"name"`
Capital []string `json:"capital"`
Languages map[string]string `json:"languages"`
Continents []string `json:"continents"`
Borders []string `json:"borders"`
Population int `json:"population"`
Flags Flags `json:"flags"`
}
type CityInfo struct {
Cities []string `json:"cities"`
}
// Struktur for kombinert respons
type CombinedInfo struct {
Name string `json:"name"`
Continents []string `json:"continenents"`
Population int `json:"population"`
Languages map[string]string `json:"languages"`
Borders []string `json:"borders"`
Flags string `json:"flags"`
Capital string `json:"capital"`
Cities string `json:"cities"`
}
// Henter landdata fra REST Countries API
func getCountryDataByCode(countryCode string) (*CountryInfo, error) {
url := fmt.Sprintf("http://129.241.150.113:8080/v3.1/alpha/%s", countryCode)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error retrieving country data, status code: %d", resp.StatusCode)
}
var countries []CountryInfo
if err := json.NewDecoder(resp.Body).Decode(&countries); err != nil {
return nil, err
}
if len(countries) == 0 {
return nil, fmt.Errorf("country not found for code: %s", countryCode)
}
return &countries[0], nil
}
func getCitiesByCountry(countryName string) ([]string, error) {
url := fmt.Sprintf("https://countriesnow.space/api/v0.1/countries/cities/q?country=%s", countryName)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("error retrieving cities, status code: %d", resp.StatusCode)
}
var responseBody map[string]interface{}
if err := json.NewDecoder(resp.Body).Decode(&responseBody); err != nil {
return nil, err
}
if cities, ok := responseBody["data"].([]interface{}); ok {
var cityList []string
for _, city := range cities {
if cityStr, ok := city.(string); ok {
cityList = append(cityList, cityStr)
}
}
// Hvis ingen byer er funnet, returner en feilmelding
if len(cityList) == 0 {
fmt.Println("No cities found in the response.")
}
return cityList, nil
}
return nil, fmt.Errorf("no cities found for country %s", countryName)
}
func countryInfoHandler(w http.ResponseWriter, r *http.Request) {
parts := strings.Split(r.URL.Path, "/")
if len(parts) < 5 {
http.Error(w, "Invalid format. Use: /countryinfo/v1/info/{countryCode}", http.StatusBadRequest)
return
}
countryCode := parts[4]
// Hent landdata fra REST Countries API
country, err := getCountryDataByCode(countryCode)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Hent antall byer som skal vises fra URL-parameteren (default til 10)
// F.eks. /countryinfo/v1/info/NO?cities=5
cityCount := 10 // Standardverdi
cityCountStr := r.URL.Query().Get("cities") // Hent "cities" parameteren
if cityCountStr != "" {
// Prøv å konvertere parameteren til et heltall
if count, err := strconv.Atoi(cityCountStr); err == nil && count > 0 {
cityCount = count
}
}
// Hent byene fra countriesnow API
cities, err := getCitiesByCountry(country.Name.Common)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Hvis det er flere enn det brukeren ønsker, begrens listen
if len(cities) > cityCount {
cities = cities[:cityCount]
}
// Feilsøking: Hvis ingen byer ble funnet
if len(cities) == 0 {
fmt.Printf("No cities found for %s\n", country.Name.Common)
}
// Bygg kombinert respons
response := CombinedInfo{
Name: country.Name.Common,
Continents: country.Continents,
Population: country.Population,
Languages: country.Languages,
Borders: country.Borders,
Flags: country.Flags.PNG,
Capital: "",
Cities: strings.Join(cities, ", "), // Legg til de 10 første byene som en kommaseparert liste
}
if len(country.Capital) > 0 {
response.Capital = country.Capital[0]
}
// Sett Content-Type til application/json
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
}
func main() {
http.HandleFunc("/status/", handelers.DiagnosticsHandler)
http.HandleFunc("/", handelers.HomeHandler)
http.HandleFunc("/countryinfo/v1/info/", handelers.CountryInfoHandler)
//starttidspunkt for tjenesten
serviceStartTime = time.Now()
http.HandleFunc("/status/", diagnosticsHandler)
http.HandleFunc("/", homeHandler)
http.HandleFunc("/countryinfo/v1/info/", 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)
}
}
func homeHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
response := map[string]interface{}{
"WELCOME": "Welcome to the Country Info API",
"endpoints": map[string]interface{}{
"Get Country Info": map[string]string{
"Description": "Get country details including cities, population, and more.",
"URL Format": "http://localhost:8080/countryinfo/v1/info/{country_code}{?limit=10}",
"Example": "http://localhost:8080/countryinfo/v1/info/NO?cities=5",
},
"Get status info" : map[string]string{
"Description" : "Get information about the API statuses",
"URL" : "http://localhost:8080/status/",
},
},
}
json.NewEncoder(w).Encode(response)
}
}
\ 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