with TypeScript frontend, REST, a .txt as “data store”, no external dependencies, all compiling to a single binary. The overwhelming result:
But it represents a starting point for a three tier application. Any real world example would use an actual database and maybe a better routing scheme. You need Go, tsc
(npm install -g typescript
), Make
and a browser. Compile and start with make
, then open http://localhost:8000 and hit the button.
$ cat Makefile
all: hello.js hello
hello.js: hello.ts
which tsc || sudo npm install -g typescript
tsc hello.ts
hello:
go run hello.go
$ cat hello.ts
interface Answer {
Current: Number
}
async function getCurrent() {
let answer = await fetch("/current")
.then(res => res.json())
.then(res => res as Answer);
let counter = document.getElementById('current');
if (counter != null)
counter.innerText = answer.Current.toString();
}
$ cat go.mod
module hello
go 1.16
$ cat hello.go
package main
import (
_ "embed"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
//go:embed hello.js
var js string
var html string = `
<html>
<head><title></title>
<script>` + js + `
</script>
</head>
<body>
<h1 id="current"></h1>
<button onclick="getCurrent()">Load Current</button>
</body>
</html>
`
const storefile = "myfancydatastore.txt"
type Answer struct {
Current int
}
func readFromStore() Answer {
b, err := ioutil.ReadFile(storefile)
if err != nil {
// do something
}
var a Answer
err = json.Unmarshal(b, &a)
if err != nil {
// do something
}
return a
}
func writeToStore(a Answer) {
b, err := json.Marshal(a)
if err != nil {
// do something
}
ioutil.WriteFile(storefile, b, 0644)
}
func serveIndex(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
w.Header().Set("content-type", "text/html; charset=utf-8")
w.Write([]byte(html))
}
}
func handler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodGet {
w.Header().Set("content-type", "application/json")
a := readFromStore()
b, err := json.Marshal(a)
if err != nil {
// do something
}
w.Write(b)
a.Current = a.Current + 1
writeToStore(a)
}
}
func main() {
writeToStore(Answer{Current: 0})
mux := http.NewServeMux()
mux.HandleFunc("/", serveIndex)
mux.HandleFunc("/current", handler)
fmt.Println("Starting server on localhost:8000")
http.ListenAndServe("localhost:8000", mux)
}
Posted in
programming
2022-12-12 23:03 UTC