Skip to content

Commit

Permalink
examples: add todo example for go
Browse files Browse the repository at this point in the history
  • Loading branch information
lithdew committed Jun 16, 2020
1 parent a6261b6 commit 74bce78
Show file tree
Hide file tree
Showing 9 changed files with 422 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.idea/
**/node_modules/
**/dist/
./flatend
/flatend
194 changes: 194 additions & 0 deletions examples/go/todo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
# todo

Ye 'ole todo list example using SQLite.

```
$ flatend
2020/06/17 01:27:03 Listening for microservices on '127.0.0.1:9000'.
2020/06/17 01:27:03 Listening for HTTP requests on '[::]:3000'.
2020/06/17 01:27:10 ??? has connected to you. Services: [all_todos add_todo remove_todo done_todo]
$ go run main.go
2020/06/17 01:27:10 You are now connected to 127.0.0.1:9000. Services: []
$ http://localhost:3000/
```

```toml
addr = "127.0.0.1:9000"

[[http]]
addr = ":3000"

[[http.routes]]
path = "GET /"
static = "./public"

[[http.routes]]
path = "GET /todos"
service = "all_todos"

[[http.routes]]
path = "GET /todos/add/:content"
service = "add_todo"

[[http.routes]]
path = "GET /todos/remove/:id"
service = "remove_todo"

[[http.routes]]
path = "GET /todos/done/:id"
service = "done_todo"
```

```go
package main

import (
"database/sql"
"encoding/json"
"github.com/lithdew/flatend"
_ "github.com/mattn/go-sqlite3"
"os"
"os/signal"
)

func check(err error) {
if err != nil {
panic(err)
}
}

func main() {
db, err := sql.Open("sqlite3", ":memory:")
check(err)

_, err = db.Exec("CREATE TABLE todo (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT, state TEXT)")
check(err)

node := &flatend.Node{
Services: map[string]flatend.Handler{
"all_todos": func(ctx *flatend.Context) {
rows, err := db.Query("SELECT id, content, state FROM todo")
if err != nil {
ctx.Write([]byte(err.Error()))
return
}
defer rows.Close()

type Todo struct {
ID int `json:"id"`
Content string `json:"content"`
State string `json:'state'`
}

todos := make([]Todo, 0)

for rows.Next() {
var todo Todo
if err := rows.Scan(&todo.ID, &todo.Content, &todo.State); err != nil {
ctx.Write([]byte(err.Error()))
return
}
todos = append(todos, todo)
}

buf, err := json.Marshal(todos)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"add_todo": func(ctx *flatend.Context) {
content := ctx.Headers["params.content"]

res, err := db.Exec("INSERT INTO todo (content, state) VALUES (?, '')", content)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"remove_todo": func(ctx *flatend.Context) {
id := ctx.Headers["params.id"]

res, err := db.Exec("DELETE FROM todo WHERE id = ?", id)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"done_todo": func(ctx *flatend.Context) {
id := ctx.Headers["params.id"]

res, err := db.Exec("UPDATE todo SET state = 'done' WHERE id = ?", id)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
},
}
check(node.Start("127.0.0.1:9000"))

ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
<-ch

node.Shutdown()
check(db.Close())
}
```
24 changes: 24 additions & 0 deletions examples/go/todo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
addr = "127.0.0.1:9000"

[[http]]
addr = ":3000"

[[http.routes]]
path = "GET /"
static = "./public"

[[http.routes]]
path = "GET /todos"
service = "all_todos"

[[http.routes]]
path = "GET /todos/add/:content"
service = "add_todo"

[[http.routes]]
path = "GET /todos/remove/:id"
service = "remove_todo"

[[http.routes]]
path = "GET /todos/done/:id"
service = "done_todo"
149 changes: 149 additions & 0 deletions examples/go/todo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package main

import (
"database/sql"
"encoding/json"
"github.com/lithdew/flatend"
_ "github.com/mattn/go-sqlite3"
"os"
"os/signal"
)

func check(err error) {
if err != nil {
panic(err)
}
}

func main() {
db, err := sql.Open("sqlite3", ":memory:")
check(err)

_, err = db.Exec("CREATE TABLE todo (id INTEGER PRIMARY KEY AUTOINCREMENT, content TEXT, state TEXT)")
check(err)

node := &flatend.Node{
Services: map[string]flatend.Handler{
"all_todos": func(ctx *flatend.Context) {
rows, err := db.Query("SELECT id, content, state FROM todo")
if err != nil {
ctx.Write([]byte(err.Error()))
return
}
defer rows.Close()

type Todo struct {
ID int `json:"id"`
Content string `json:"content"`
State string `json:'state'`
}

todos := make([]Todo, 0)

for rows.Next() {
var todo Todo
if err := rows.Scan(&todo.ID, &todo.Content, &todo.State); err != nil {
ctx.Write([]byte(err.Error()))
return
}
todos = append(todos, todo)
}

buf, err := json.Marshal(todos)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"add_todo": func(ctx *flatend.Context) {
content := ctx.Headers["params.content"]

res, err := db.Exec("INSERT INTO todo (content, state) VALUES (?, '')", content)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"remove_todo": func(ctx *flatend.Context) {
id := ctx.Headers["params.id"]

res, err := db.Exec("DELETE FROM todo WHERE id = ?", id)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
"done_todo": func(ctx *flatend.Context) {
id := ctx.Headers["params.id"]

res, err := db.Exec("UPDATE todo SET state = 'done' WHERE id = ?", id)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

var result struct {
LastInsertID int64 `json:"lastInsertRowid"`
RowsAffected int64 `json:"changes"`
}

result.LastInsertID, _ = res.LastInsertId()
result.RowsAffected, _ = res.RowsAffected()

buf, err := json.Marshal(result)
if err != nil {
ctx.Write([]byte(err.Error()))
return
}

ctx.WriteHeader("Content-Type", "application/json")
ctx.Write(buf)
},
},
}
check(node.Start("127.0.0.1:9000"))

ch := make(chan os.Signal, 1)
signal.Notify(ch, os.Interrupt)
<-ch

node.Shutdown()
check(db.Close())
}
15 changes: 15 additions & 0 deletions examples/go/todo/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Flatend Demo - Todo</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.8.0/css/bulma.min.css">
<link rel="stylesheet" href="/style.css">
</head>
<body>
<div id="root"></div>
<script src="/main.js"></script>
</body>
</html>
4 changes: 4 additions & 0 deletions examples/go/todo/public/main.js

Large diffs are not rendered by default.

Loading

0 comments on commit 74bce78

Please sign in to comment.