forked from aeneasr/workshop-dbg
/
main.go
118 lines (95 loc) · 3.18 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package main
// The import section defines libraries that we are going to use in our program.
import (
"fmt"
"log"
"net/http"
"encoding/json"
"github.com/gorilla/mux"
"github.com/ory-am/common/env"
"github.com/rs/cors"
)
// In a 12 factor app, we must obey the environment variables.
var envHost = env.Getenv("HOST", "")
var envPort = env.Getenv("PORT", "5678")
// Contact defines the structure of a contact which including name, department and company.
type Contact struct {
ID string `json:"id"`
// Name is the contact's full name.
Name string `json:"name"`
// Department is the contact's department in a company.
Department string `json:"department"`
// Company is the name of the company the contact works for.
Company string `json:"company"`
}
// Contacts is a list of contact structs.
type Contacts []Contact
// myContacts is an exemplary
var MyContacts = Contacts{
{
ID: "john-bravo",
Name: "John Bravo",
Department: "IT",
Company: "ACME Inc",
},
{
ID: "cathrine-mueller",
Name: "Cathrine Müller",
Department: "HR",
Company: "Grove AG",
},
{
ID: "john-bravo",
Name: "Maximilian Schmidt",
Department: "PR",
Company: "Titanpad AG",
},
}
// The main routine is going the "entry" point.
func main() {
// Create a new router.
router := mux.NewRouter()
// Requests to "/" are by method listContacts.
router.HandleFunc("/", ListContacts(&MyContacts)).Methods("GET")
router.HandleFunc("/", AddContact(&MyContacts)).Methods("POST")
// Print some information.
fmt.Printf("Listening on %s\n", "http://localhost:5678")
// Cross origin resource requests
c := cors.New(cors.Options{AllowedOrigins: []string{"*"}})
// Start up the server and check for errors.
listenOn := fmt.Sprintf("%s:%s", envHost, envPort)
err := http.ListenAndServe(listenOn, c.Handler(router))
if err != nil {
log.Fatalf("Could not set up server because %s", err)
}
}
// listContacts takes a contact list and outputs it.
func ListContacts(contacts *Contacts) func(rw http.ResponseWriter, r *http.Request) {
return func(rw http.ResponseWriter, r *http.Request) {
output, err := json.MarshalIndent(contacts, "", "\t")
// If an error occurs, handle it.
if err != nil {
http.Error(rw, fmt.Sprintf("Could not read vcards because %s", err), http.StatusInternalServerError)
return
}
rw.Write(output)
}
}
// addContact will add a contact to the list
func AddContact(contacts *Contacts) func(rw http.ResponseWriter, r *http.Request) {
return func(rw http.ResponseWriter, r *http.Request) {
// newContact poses as a placeholder for the contact that the request is going to add.
var newContact Contact
// We decode the information and "inject" it to newContact.
err := json.NewDecoder(r.Body).Decode(&newContact)
// If an error occurs while decoding, handle it.
if err != nil {
http.Error(rw, fmt.Sprintf("Could not read vcards because %s", err), http.StatusInternalServerError)
return
}
// Save newContact to the list of available contacts.
*contacts = append(*contacts, newContact)
// Per specification, RESTful may return an empty response when a POST request was successful
rw.WriteHeader(http.StatusNoContent)
}
}