Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 44 additions & 20 deletions coolfacts/cmd/coolfacts_server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
}
}
3 changes: 2 additions & 1 deletion coolfacts/coolfact/fact.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package coolfact

type Fact struct {
// TODO: add fields for the entity fact: topic and description (strings)
Topic string
Description string
}
18 changes: 13 additions & 5 deletions coolfacts/coolfact/service.go
Original file line number Diff line number Diff line change
@@ -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
}
5 changes: 3 additions & 2 deletions coolfacts/docs/ex3-get-facts.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 4 additions & 2 deletions coolfacts/inmem/factsrepo.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}