package main
import (
"coin/exam09/blockchain"
"fmt"
"html/template"
"log"
"net/http"
)
const (
port string = ":4000"
templateDir string = "templates/"
)
var templates *template.Template
type homeData struct {
PageTitle string
Blocks []*blockchain.Block
}
func home(rw http.ResponseWriter, r *http.Request) {
data := homeData{"Home", blockchain.GetBlockchain().AllBlocks()}
templates.ExecuteTemplate(rw, "home", data)
}
func add(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
templates.ExecuteTemplate(rw, "add", nil)
case "POST":
r.ParseForm()
data := r.FormValue("blockData")
fmt.Println(data)
blockchain.GetBlockchain().AddBlock(data)
http.Redirect(rw, r, "/", http.StatusPermanentRedirect)
}
}
func main() {
templates = template.Must(template.ParseGlob(templateDir + "pages/*.gohtml"))
templates = template.Must(templates.ParseGlob(templateDir + "partials/*.gohtml"))
http.HandleFunc("/", home)
http.HandleFunc("/add", add)
fmt.Printf("Listening on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
{{define "add"}}
<!DOCTYPE html>
<html lang="en">
{{template "head" "Add"}}
<body>
{{template "header" "Add"}}
<main>
<form method="POST">
<input type="text" placeholder="Data for your block" required name="blockData" />
<button>Add Block</button>
</form>
</main>
{{template "footer"}}
</body>
</html>
{{end}}
{{define "home"}}
<!DOCTYPE html>
<html lang="en">
{{template "head" .PageTitle}}
<body>
{{template "header" .PageTitle}}
<main>
{{range .Blocks}}
{{template "block" .}}
{{end}}
</main>
{{template "footer"}}
</body>
</html>
{{end}}
package main
import (
"coin/exam11/explorer"
)
func main() {
explorer.Start()
}
package explorer
import (
"coin/exam11/blockchain"
"fmt"
"log"
"net/http"
"text/template"
)
const (
port string = ":4000"
templateDir string = "explorer/templates/"
)
var templates *template.Template
type homeData struct {
PageTitle string
Blocks []*blockchain.Block
}
func home(rw http.ResponseWriter, r *http.Request) {
data := homeData{"Home", blockchain.GetBlockchain().AllBlocks()}
templates.ExecuteTemplate(rw, "home", data)
}
func add(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case "GET":
templates.ExecuteTemplate(rw, "add", nil)
case "POST":
r.ParseForm()
data := r.FormValue("blockData")
fmt.Println(data)
blockchain.GetBlockchain().AddBlock(data)
http.Redirect(rw, r, "/", http.StatusPermanentRedirect)
}
}
func Start() {
// Standard 라이브러리를 사용하고
templates = template.Must(template.ParseGlob(templateDir + "pages/*.gohtml"))
// templates 변수를 사용했다. (템플릿 위에 템플릿을 얹은 형태)
templates = template.Must(templates.ParseGlob(templateDir + "partials/*.gohtml"))
http.HandleFunc("/", home)
http.HandleFunc("/add", add)
fmt.Printf("Listening on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
{{define "block"}}
<div>
<ul>
<li><strong>Data: </strong>{{.Data}}</li>
<li><strong>Hash: </strong>{{.Hash}}</li>
{{if .PrevHash}}
<li><strong>Previous Hash: </strong>{{.PrevHash}}</li>
{{end}}
</ul>
</div>
<hr />
{{end}}
package main
import (
"coin/exam12/utils"
"encoding/json"
"fmt"
"log"
"net/http"
)
const port string = ":4000"
type URLDescription struct {
URL string
Method string
Description string
}
// Client에게 JSON을 보낸다.
func documentation(rw http.ResponseWriter, r *http.Request) {
data := []URLDescription{
{
URL: "/",
Method: "GET",
Description: "See Documentation",
},
}
// data를 JSON형태로 인코딩한다.
b, err := json.Marshal(data)
utils.HandleErr(err)
fmt.Printf("%s", b)
}
func main() {
http.HandleFunc("/", documentation)
fmt.Printf("Listening on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
const port string = ":4000"
// struct field tag 사용
// omitempty : Field가 비어있으면 Field를 숨겨준다.
// "-" : 해당 필드를 무시한다.
type URLDescription struct {
URL string `json:"url"`
Method string `json:"method"`
Description string `json:"description"`
Payload string `json:"payload,omitempty"`
Field int `json:"-"`
}
// Client에게 JSON을 보낸다.
func documentation(rw http.ResponseWriter, r *http.Request) {
data := []URLDescription{
{
URL: "/",
Method: "GET",
Description: "See Documentation",
Field: 1,
},
{
URL: "/blocks",
Method: "POST",
Description: "Add A Block",
Payload: "data:string",
},
}
// Client에게 JSON임을 알려주기 위함
rw.Header().Add("Content-Type", "application/json")
// // data를 JSON형태로 인코딩한다.
// b, err := json.Marshal(data)
// utils.HandleErr(err)
// fmt.Fprintf(rw, "%s", b)
// 위와 같은 동작을 한다.
json.NewEncoder(rw).Encode(data)
}
func main() {
http.HandleFunc("/", documentation)
fmt.Printf("Listening on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
)
const port string = ":4000"
type URL string
// MarshalText()는 인터페이스이다.
func (u URL) MarshalText() ([]byte, error) {
url := fmt.Sprintf("http://localhost%s%s", port, u)
return []byte(url), nil
}
type URLDescription struct {
URL URL `json:"url"`
Method string `json:"method"`
Description string `json:"description"`
Payload string `json:"payload,omitempty"`
}
func (u URLDescription) String() string {
return "Hello I'm the URL Description"
}
// Client에게 JSON을 보낸다.
func documentation(rw http.ResponseWriter, r *http.Request) {
data := []URLDescription{
{
URL: URL("/"),
Method: "GET",
Description: "See Documentation",
},
{
URL: URL("/blocks"),
Method: "POST",
Description: "Add A Block",
Payload: "data:string",
},
}
// [사용법 2]
// fmt.Println(data)
rw.Header().Add("Content-Type", "application/json")
json.NewEncoder(rw).Encode(data)
}
func main() {
// [사용법 1]
// fmt 패키지는 String()가 구현되어 있으면 호출해준다.
// fmt.Println(URLDescription{
// URL: "/",
// Method: "GET",
// Description: "See Documentation",
// })
http.HandleFunc("/", documentation)
fmt.Printf("Listening on http://localhost%s\n", port)
log.Fatal(http.ListenAndServe(port, nil))
}