Use better router, Get/Update note

This commit is contained in:
MrLetsplay 2023-08-18 22:34:42 +02:00
parent 858174b9d2
commit 84b877017c
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
3 changed files with 104 additions and 18 deletions

2
go.mod
View File

@ -3,3 +3,5 @@ module git.cringe-studios.com/NoteServer
go 1.20
require github.com/mattn/go-sqlite3 v1.14.17
require github.com/julienschmidt/httprouter v1.3.0

2
go.sum
View File

@ -1,2 +1,4 @@
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=

118
main.go
View File

@ -6,7 +6,9 @@ import (
"io"
"log"
"net/http"
"strconv"
"github.com/julienschmidt/httprouter"
_ "github.com/mattn/go-sqlite3"
)
@ -19,6 +21,7 @@ type Note struct {
func httpError(err error, statusCode int, message string, w http.ResponseWriter) bool {
if err != nil {
log.Println(err)
w.WriteHeader(statusCode)
io.WriteString(w, message)
return true
@ -27,7 +30,7 @@ func httpError(err error, statusCode int, message string, w http.ResponseWriter)
return false
}
func getNotes(w http.ResponseWriter, req *http.Request) {
func getNotes(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
res, err := db.Query(`SELECT Id, Content FROM Notes`)
if httpError(err, http.StatusInternalServerError, "Failed to load notes", w) {
return
@ -52,10 +55,11 @@ func getNotes(w http.ResponseWriter, req *http.Request) {
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
func postNotes(w http.ResponseWriter, req *http.Request) {
func postNotes(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
data, err := io.ReadAll(req.Body)
if httpError(err, http.StatusBadRequest, "Failed to read data", w) {
return
@ -91,28 +95,102 @@ func postNotes(w http.ResponseWriter, req *http.Request) {
return
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
w.Write(json)
}
func putNote(w http.ResponseWriter, req *http.Request) {
if req.Method != http.MethodPut {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Invalid method")
func getNote(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
id, err := strconv.ParseInt(p.ByName("id"), 10, 64)
if httpError(err, http.StatusBadRequest, "Invalid id", w) {
return
}
stmt, err := db.Prepare(`SELECT Content FROM Notes WHERE Id = ?`)
if httpError(err, http.StatusInternalServerError, "Failed to get note", w) {
return
}
defer stmt.Close()
res := stmt.QueryRow(id)
var note Note = Note{Id: id}
err = res.Scan(&note.Content)
if err == sql.ErrNoRows {
w.WriteHeader(http.StatusNotFound)
io.WriteString(w, "Note doesn't exist")
return
}
if httpError(err, http.StatusInternalServerError, "Failed to get note", w) {
return
}
json, err := json.Marshal(note)
if httpError(err, http.StatusInternalServerError, "Failed to create JSON", w) {
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
func handleNotes(w http.ResponseWriter, req *http.Request) {
switch req.Method {
case http.MethodGet:
getNotes(w, req)
case http.MethodPost:
postNotes(w, req)
default:
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Invalid method")
func putNote(w http.ResponseWriter, req *http.Request, p httprouter.Params) {
id, err := strconv.ParseInt(p.ByName("id"), 10, 64)
if httpError(err, http.StatusBadRequest, "Invalid id", w) {
return
}
data, err := io.ReadAll(req.Body)
if httpError(err, http.StatusBadRequest, "Failed to read data", w) {
return
}
var note Note
err = json.Unmarshal(data, &note)
if httpError(err, http.StatusBadRequest, "Invalid request", w) {
return
}
if len(note.Content) == 0 {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, "Missing note content")
return
}
stmt, err := db.Prepare(`UPDATE Notes SET Content = ? WHERE Id = ?`)
if httpError(err, http.StatusInternalServerError, "Failed to update note", w) {
return
}
defer stmt.Close()
res, err := stmt.Exec(note.Content, id)
if httpError(err, http.StatusInternalServerError, "Failed to update note", w) {
return
}
updated, err := res.RowsAffected()
if httpError(err, http.StatusInternalServerError, "Failed to update note", w) {
return
}
if updated == 0 {
w.WriteHeader(http.StatusNotFound)
io.WriteString(w, "Note doesn't exist")
return
}
note.Id = id
json, err := json.Marshal(note)
if httpError(err, http.StatusInternalServerError, "Failed to create JSON", w) {
return
}
w.Header().Set("Content-Type", "application/json")
w.Write(json)
}
func main() {
@ -134,7 +212,11 @@ func main() {
log.Println("Listening")
http.HandleFunc("/api/notes", handleNotes)
http.HandleFunc("/api/note/", putNote)
http.ListenAndServe(":8080", nil) // TODO: configure host, port, TLS
router := httprouter.New()
router.GET("/api/notes", getNotes)
router.POST("/api/notes", postNotes)
router.GET("/api/note/:id", getNote)
router.PUT("/api/note/:id", putNote)
http.ListenAndServe(":8080", router) // TODO: configure host, port, TLS
}