diff --git a/coolfacts/cmd/coolfacts_server/server.go b/coolfacts/cmd/coolfacts_server/server.go index 29cb62b..6a2c439 100644 --- a/coolfacts/cmd/coolfacts_server/server.go +++ b/coolfacts/cmd/coolfacts_server/server.go @@ -6,31 +6,34 @@ import ( "log" "net/http" "strings" + + "github.com/FTBpro/go-workshop/coolfacts/coolfact" ) type FactsService interface { - // TODO: add methods declerations - // 1. getFacts - returns a slice of fact.Fact and an error + GetFacts() ([]coolfact.Fact, error) } type server struct { - // TODO: add factsService field + factsService FactsService } -func NewServer() *server { - // TODO: returns an initializes server with the factsService - return &server{} +func NewServer(factsService FactsService) *server { + return &server{ + factsService: factsService, + } } func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Println("incoming request", r.Method, r.URL.Path) - // TODO: add case for GET /facts, that will call to `HandleGetFacts` switch r.Method { case http.MethodGet: switch strings.ToLower(r.URL.Path) { case "/ping": s.HandlePing(w, r) + case "/facts": + s.HandleGetFacts(w, r) default: s.HandleNotFound(w, r) } @@ -59,19 +62,26 @@ func (s *server) HandleGetFacts(w http.ResponseWriter, _ *http.Request) { return } - // TODO: - // 1. format the facts to a json response - // 2. write status 200 - // 3. set content type application/json - // 4. write json response: - // { - // "facts": [ - // { - // "id": "..." - // "description": "..." - // }, - // ... - // ] + // we first format the facts to map[string]interface. + formattedFacts := make([]map[string]interface{}, len(facts)) + for i, coolFact := range facts { + formattedFacts[i] = map[string]interface{}{ + "topic": coolFact.Topic, + "description": coolFact.Description, + } + } + + response := s.formatGetFactsResponse(facts) + + // write status and content-type + // status must be written before the body + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + + // write the body. We use json encoding + if err := json.NewEncoder(w).Encode(response); err != nil { + fmt.Printf("HandleGetFacts ERROR writing response: %s", err) + } } func (s *server) HandleNotFound(w http.ResponseWriter, r *http.Request) { @@ -102,3 +112,17 @@ func (s *server) HandleError(w http.ResponseWriter, err error) { fmt.Printf("HandleGetFacts ERROR writing response: %s", err) } } + +func (s *server) formatGetFactsResponse(facts []coolfact.Fact) map[string]interface{} { + formattedFacts := make([]map[string]interface{}, len(facts)) + for i, coolFact := range facts { + formattedFacts[i] = map[string]interface{}{ + "topic": coolFact.Topic, + "description": coolFact.Description, + } + } + + return map[string]interface{}{ + "facts": formattedFacts, + } +} diff --git a/coolfacts/coolfact/fact.go b/coolfacts/coolfact/fact.go index 51a28ad..d83e895 100644 --- a/coolfacts/coolfact/fact.go +++ b/coolfacts/coolfact/fact.go @@ -1,5 +1,6 @@ package coolfact type Fact struct { - // TODO: add fields for the entity fact: topic and description (strings) + Topic string + Description string } diff --git a/coolfacts/coolfact/service.go b/coolfacts/coolfact/service.go index 389c309..15711ff 100644 --- a/coolfacts/coolfact/service.go +++ b/coolfacts/coolfact/service.go @@ -1,18 +1,26 @@ package coolfact +import "fmt" + type Repository interface { - // TODO: add functions decleration - // - getFacts. Returns a slice of Fact and an error + GetFacts() ([]Fact, error) } type service struct { - // TODO: add field factsRepo + factsRepo Repository } func NewService(factsRepo Repository) *service { - // TODO: init a new service with factsRepo + return &service{ + factsRepo: factsRepo, + } } func (s *service) GetFacts() ([]Fact, error) { - // TODO: implement getFacts, using the factsRepo + facts, err := s.factsRepo.GetFacts() + if err != nil { + return nil, fmt.Errorf("factsService.GetFacts: %w", err) + } + + return facts, nil } diff --git a/coolfacts/docs/ex3-get-facts.md b/coolfacts/docs/ex3-get-facts.md index b1930c1..15b3337 100644 --- a/coolfacts/docs/ex3-get-facts.md +++ b/coolfacts/docs/ex3-get-facts.md @@ -264,10 +264,11 @@ As mentioned before, you will implement a new API for the `server`, what you wil - Write status 200. - Set "content-type" header to "application/json". -### Building and Running +## Building and Running If everything is implemented well, this is what the final result should look like when running the program: -![factsgif](https://user-images.githubusercontent.com/5252381/204143457-6eaf59d3-6c52-4fbb-8d2a-19d22436cbd8.gif) +![v3-get-facts](https://user-images.githubusercontent.com/5252381/206864380-9890158e-c841-4d9a-b772-cd779388e58e.gif) + # Full walkthrough In the following section you fill find a full walkthrough. Use it in case you are stuck. diff --git a/coolfacts/inmem/factsrepo.go b/coolfacts/inmem/factsrepo.go index 46e3c3c..f879c95 100644 --- a/coolfacts/inmem/factsrepo.go +++ b/coolfacts/inmem/factsrepo.go @@ -9,9 +9,11 @@ type factsRepo struct { } func NewFactsRepository(facts ...coolfact.Fact) *factsRepo { - // TODO: init facts repo + return &factsRepo{ + facts: facts, + } } func (r *factsRepo) GetFacts() ([]coolfact.Fact, error) { - // TODO: implement + return r.facts, nil }