update d1-blog-server example to use encoding/json

This commit is contained in:
syumai 2023-06-24 09:59:05 +09:00
parent 9d3ebbea7d
commit 77c9c5c681
8 changed files with 10 additions and 374 deletions

View File

@ -11,10 +11,6 @@ build:
deploy:
wrangler deploy
.PHONY: generate
generate:
go generate ./...
.PHONY: init-db
init-db:
wrangler d1 execute d1-blog-server --file=./schema.sql

View File

@ -12,9 +12,9 @@
### Create blog post
```
$ curl --location --request POST 'https://d1-blog-server.syumai.workers.dev/articles' \
--header 'Content-Type: application/json' \
--data-raw '{
$ curl -X POST 'https://d1-blog-server.syumai.workers.dev/articles' \
-H 'Content-Type: application/json' \
-d '{
"title":"example post",
"body":"body of the example post"
}'
@ -60,15 +60,12 @@ This project requires these tools to be installed globally.
* wrangler
* tinygo
* [easyjson](https://github.com/mailru/easyjson)
- `go install github.com/mailru/easyjson/...@latest`
### Commands
```
# development
make init-db-preview # initialize preview DB (remove all rows)
make generate # generate easyjson models
make dev # run dev server
make build # build Go Wasm binary

View File

@ -2,16 +2,16 @@ package app
import (
"database/sql"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
"time"
"github.com/mailru/easyjson"
"github.com/syumai/workers/_examples/d1-blog-server/app/model"
"github.com/syumai/workers/cloudflare/d1"
_ "github.com/syumai/workers/cloudflare/d1" // register driver
"github.com/syumai/workers/examples/d1-blog-server/app/model"
)
type articleHandler struct{}
@ -53,7 +53,7 @@ func (h *articleHandler) handleErr(w http.ResponseWriter, status int, msg string
func (h *articleHandler) createArticle(w http.ResponseWriter, req *http.Request, db *sql.DB) {
var createArticleReq model.CreateArticleRequest
if err := easyjson.UnmarshalFromReader(req.Body, &createArticleReq); err != nil {
if err := json.NewDecoder(req.Body).Decode(&createArticleReq); err != nil {
h.handleErr(w, http.StatusBadRequest,
"request format is invalid")
return
@ -90,7 +90,7 @@ VALUES (?, ?, ?)
}
w.Header().Set("Content-Type", "application/json")
if _, err := easyjson.MarshalToWriter(&res, w); err != nil {
if err := json.NewEncoder(w).Encode(res); err != nil {
fmt.Fprintf(os.Stderr, "failed to encode response: %w\n", err)
}
}
@ -123,7 +123,7 @@ ORDER BY created_at DESC;
}
w.Header().Set("Content-Type", "application/json")
if _, err := easyjson.MarshalToWriter(&res, w); err != nil {
if err := json.NewEncoder(w).Encode(res); err != nil {
fmt.Fprintf(os.Stderr, "failed to encode response: %w\n", err)
}
}

View File

@ -1,7 +1,5 @@
//go:generate easyjson .
package model
//easyjson:json
type Article struct {
ID uint64 `json:"id"`
Title string `json:"title"`
@ -9,18 +7,15 @@ type Article struct {
CreatedAt uint64 `json:"createdAt"`
}
//easyjson:json
type CreateArticleRequest struct {
Title string `json:"title"`
Body string `json:"body"`
}
//easyjson:json
type CreateArticleResponse struct {
Article Article `json:"article"`
}
//easyjson:json
type ListArticlesResponse struct {
Articles []Article `json:"articles"`
}

View File

@ -1,343 +0,0 @@
// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT.
package model
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
)
// suppress unused package warning
var (
_ *json.RawMessage
_ *jlexer.Lexer
_ *jwriter.Writer
_ easyjson.Marshaler
)
func easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(in *jlexer.Lexer, out *ListArticlesResponse) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "articles":
if in.IsNull() {
in.Skip()
out.Articles = nil
} else {
in.Delim('[')
if out.Articles == nil {
if !in.IsDelim(']') {
out.Articles = make([]Article, 0, 1)
} else {
out.Articles = []Article{}
}
} else {
out.Articles = (out.Articles)[:0]
}
for !in.IsDelim(']') {
var v1 Article
(v1).UnmarshalEasyJSON(in)
out.Articles = append(out.Articles, v1)
in.WantComma()
}
in.Delim(']')
}
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(out *jwriter.Writer, in ListArticlesResponse) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"articles\":"
out.RawString(prefix[1:])
if in.Articles == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v2, v3 := range in.Articles {
if v2 > 0 {
out.RawByte(',')
}
(v3).MarshalEasyJSON(out)
}
out.RawByte(']')
}
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v ListArticlesResponse) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v ListArticlesResponse) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *ListArticlesResponse) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *ListArticlesResponse) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel(l, v)
}
func easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(in *jlexer.Lexer, out *CreateArticleResponse) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "article":
(out.Article).UnmarshalEasyJSON(in)
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(out *jwriter.Writer, in CreateArticleResponse) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"article\":"
out.RawString(prefix[1:])
(in.Article).MarshalEasyJSON(out)
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v CreateArticleResponse) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v CreateArticleResponse) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *CreateArticleResponse) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *CreateArticleResponse) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel1(l, v)
}
func easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(in *jlexer.Lexer, out *CreateArticleRequest) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "title":
out.Title = string(in.String())
case "body":
out.Body = string(in.String())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(out *jwriter.Writer, in CreateArticleRequest) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"title\":"
out.RawString(prefix[1:])
out.String(string(in.Title))
}
{
const prefix string = ",\"body\":"
out.RawString(prefix)
out.String(string(in.Body))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v CreateArticleRequest) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v CreateArticleRequest) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *CreateArticleRequest) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *CreateArticleRequest) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel2(l, v)
}
func easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(in *jlexer.Lexer, out *Article) {
isTopLevel := in.IsStart()
if in.IsNull() {
if isTopLevel {
in.Consumed()
}
in.Skip()
return
}
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
in.WantColon()
if in.IsNull() {
in.Skip()
in.WantComma()
continue
}
switch key {
case "id":
out.ID = uint64(in.Uint64())
case "title":
out.Title = string(in.String())
case "body":
out.Body = string(in.String())
case "createdAt":
out.CreatedAt = uint64(in.Uint64())
default:
in.SkipRecursive()
}
in.WantComma()
}
in.Delim('}')
if isTopLevel {
in.Consumed()
}
}
func easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(out *jwriter.Writer, in Article) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"id\":"
out.RawString(prefix[1:])
out.Uint64(uint64(in.ID))
}
{
const prefix string = ",\"title\":"
out.RawString(prefix)
out.String(string(in.Title))
}
{
const prefix string = ",\"body\":"
out.RawString(prefix)
out.String(string(in.Body))
}
{
const prefix string = ",\"createdAt\":"
out.RawString(prefix)
out.Uint64(uint64(in.CreatedAt))
}
out.RawByte('}')
}
// MarshalJSON supports json.Marshaler interface
func (v Article) MarshalJSON() ([]byte, error) {
w := jwriter.Writer{}
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(&w, v)
return w.Buffer.BuildBytes(), w.Error
}
// MarshalEasyJSON supports easyjson.Marshaler interface
func (v Article) MarshalEasyJSON(w *jwriter.Writer) {
easyjsonC80ae7adEncodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(w, v)
}
// UnmarshalJSON supports json.Unmarshaler interface
func (v *Article) UnmarshalJSON(data []byte) error {
r := jlexer.Lexer{Data: data}
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(&r, v)
return r.Error()
}
// UnmarshalEasyJSON supports easyjson.Unmarshaler interface
func (v *Article) UnmarshalEasyJSON(l *jlexer.Lexer) {
easyjsonC80ae7adDecodeGithubComSyumaiWorkersExamplesD1BlogServerAppModel3(l, v)
}

View File

@ -2,11 +2,6 @@ module github.com/syumai/workers/_examples/d1-blog-server
go 1.19
require (
github.com/mailru/easyjson v0.7.7
github.com/syumai/workers v0.9.0
)
require github.com/syumai/workers v0.9.0
replace github.com/syumai/workers => ../../
require github.com/josharian/intern v1.0.0 // indirect

View File

@ -1,4 +0,0 @@
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=

View File

@ -4,7 +4,7 @@ import (
"net/http"
"github.com/syumai/workers"
"github.com/syumai/workers/examples/d1-blog-server/app"
"github.com/syumai/workers/_examples/d1-blog-server/app"
)
func main() {