diff --git a/codec/context.go b/codec/context.go index 360a752..1ffedb6 100644 --- a/codec/context.go +++ b/codec/context.go @@ -2,6 +2,7 @@ package codec import ( "context" + "io" "net/http" ) @@ -13,6 +14,6 @@ type Context interface { type Codec interface { Mime() string - EncodeResponse(ctx Context, v any) error - DecodeRequest(ctx Context, v any) error + Encode(ctx context.Context, w io.Writer, v any) error + Decode(ctx context.Context, r io.Reader, v any) error } diff --git a/codec/default.go b/codec/default.go index 8736d55..cb2f3ae 100644 --- a/codec/default.go +++ b/codec/default.go @@ -1,7 +1,9 @@ package codec import ( + "context" "encoding/json" + "io" "gopkg.in/yaml.v3" ) @@ -12,12 +14,12 @@ func (JSON) Mime() string { return "application/json" } -func (JSON) DecodeRequest(ctx Context, v any) error { - return json.NewDecoder(ctx.Request().Body).Decode(v) +func (JSON) Decode(ctx context.Context, r io.Reader, v any) error { + return json.NewDecoder(r).Decode(v) } -func (JSON) EncodeResponse(ctx Context, v any) error { - return json.NewEncoder(ctx.ResponseWriter()).Encode(v) +func (JSON) Encode(ctx context.Context, w io.Writer, v any) error { + return json.NewEncoder(w).Encode(v) } type YAML struct{} @@ -26,12 +28,12 @@ func (YAML) Mime() string { return "application/yaml" } -func (YAML) DecodeRequest(ctx Context, v any) error { - return yaml.NewDecoder(ctx.Request().Body).Decode(v) +func (YAML) Decode(ctx context.Context, r io.Reader, v any) error { + return yaml.NewDecoder(r).Decode(v) } -func (YAML) EncodeResponse(ctx Context, v any) error { - encoder := yaml.NewEncoder(ctx.ResponseWriter()) +func (YAML) Encode(ctx context.Context, w io.Writer, v any) error { + encoder := yaml.NewEncoder(w) defer encoder.Close() return encoder.Encode(v) diff --git a/codec/module.go b/codec/module.go index 6b70272..116d221 100644 --- a/codec/module.go +++ b/codec/module.go @@ -67,3 +67,11 @@ func (c *Codecs) getCodec(ctx Context, head string) Codec { return ret } + +func (c *Codecs) DecodeRequest(ctx Context, v any) error { + return c.Request(ctx).Decode(ctx, ctx.Request().Body, v) +} + +func (c *Codecs) EncodeResponse(ctx Context, v any) error { + return c.Response(ctx).Encode(ctx, ctx.ResponseWriter(), v) +} diff --git a/examples_test.go b/examples_test.go index f2937c4..06ac7ba 100644 --- a/examples_test.go +++ b/examples_test.go @@ -1,10 +1,14 @@ package espresso_test import ( + "bytes" + "encoding/json" "fmt" "net/http" + "net/http/httptest" "github.com/googollee/go-espresso" + "github.com/googollee/go-espresso/codec" ) type Book struct { @@ -38,9 +42,11 @@ func ExampleEspresso() { return espresso.Error(http.StatusNotFound, fmt.Errorf("not found")) } - if err := codec.Response(ctx).Encode(ctx, &book); err != nil { + if err := codec.Module.Value(ctx).EncodeResponse(ctx, &book); err != nil { return err } + + return nil }) espo.Handle(func(ctx espresso.Context) error { @@ -49,16 +55,60 @@ func ExampleEspresso() { return err } + codecs := codec.Module.Value(ctx) + var book Book - if err := codec.Request(ctx).Decode(ctx, &book); err != nil { + if err := codecs.DecodeRequest(ctx, &book); err != nil { return espresso.Error(http.StatusBadRequest, err) } book.ID = len(books) books[book.ID] = book - if err := codec.Response(ctx).Decode(ctx, &book); err != nil { + if err := codecs.EncodeResponse(ctx, &book); err != nil { return err } + + return nil }) + + svr := httptest.NewServer(espo) + defer svr.Close() + + func() { + var book Book + resp, err := http.Get(svr.URL + "/book/1") + if err != nil { + panic(err) + } + defer resp.Body.Close() + + if err := json.NewDecoder(resp.Body).Decode(&book); err != nil { + panic(err) + } + + fmt.Println("book(1) title:", book.Title) + }() + + func() { + arg := Book{Title: "The New Book"} + + var buf bytes.Buffer + if err := json.NewEncoder(&buf).Encode(&arg); err != nil { + panic(err) + } + + resp, err := http.Post(svr.URL+"/book/1", "application/json", &buf) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + var ret Book + if err := json.NewDecoder(resp.Body).Decode(&ret); err != nil { + panic(err) + } + + fmt.Println(ret.Title, " id:", ret.ID) + }() }