not tested

This commit is contained in:
GenZmeY 2021-03-19 20:24:02 +03:00
parent 8b3aad50b0
commit 2a566ae019
8 changed files with 119 additions and 23 deletions

View File

@ -21,3 +21,6 @@ check-build:
clean:
rm -rf $(BINDIR)
run: check-build
$(BIN)

Binary file not shown.

View File

@ -17,20 +17,51 @@ import (
"fmt"
"net/http"
"context"
"os"
"os/signal"
"syscall"
"go-jsonapi-example/internal/model"
"go-jsonapi-example/internal/resource"
"go-jsonapi-example/internal/storage"
"github.com/manyminds/api2go"
"github.com/juju/gnuflag"
)
func main() {
port := 8080
baseURL := fmt.Sprintf("http://localhost:%d", port)
api := api2go.NewAPIWithBaseURL("v1", baseURL)
carStorage := storage.NewCarStorage()
api.AddResource(model.Car{}, resource.CarResource{CarStorage: carStorage})
host := gnuflag.String("host", "localhost", "host")
port := gnuflag.Int("port", 8080, "port")
gnuflag.Parse(true)
fmt.Printf("Listening on :%d", port)
http.ListenAndServe(fmt.Sprintf(":%d", port), api.Handler())
addr := fmt.Sprintf("%s:%d", *host, *port)
baseURL := fmt.Sprintf("http://%s", addr)
api := api2go.NewAPIWithBaseURL("v1", baseURL)
api.AddResource(model.Car{}, resource.CarResource{CarStorage: storage.NewCarStorage()})
server := &http.Server{Addr: addr, Handler: api.Handler()}
closeHandler(server)
fmt.Printf("Listening on %s\n", addr)
if err := server.ListenAndServe(); err != http.ErrServerClosed {
fmt.Printf("error: %s\n", err)
os.Exit(1)
} else {
fmt.Println(err)
os.Exit(0)
}
}
func closeHandler(server *http.Server) {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM)
go func() {
<-interrupt
if err := server.Shutdown(context.Background()); err != nil {
fmt.Printf("error: %s\n", err)
}
}()
}

1
go.mod
View File

@ -4,5 +4,6 @@ go 1.14
require (
github.com/gorilla/mux v1.8.0 // indirect
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d
github.com/manyminds/api2go v0.0.0-20210211132652-5457038544fa
)

2
go.sum
View File

@ -28,6 +28,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d h1:c93kUJDtVAXFEhsCh5jSxyOJmFHuzcihnslQiX8Urwo=
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=

View File

@ -3,6 +3,9 @@ package model
import (
"errors"
"net/http"
"github.com/manyminds/api2go"
"github.com/manyminds/api2go/jsonapi"
)
@ -10,47 +13,97 @@ type Car struct {
ID string `json:"-"`
Brand string `json:"brand"`
Model string `json:"model"`
Price uint `json:"price"`
Status string `json:"status"`
Price uint64 `json:"price"`
Status string `json:"status"` // OnTheWay, InStock, Sold, Discontinued
}
func (c Car) Verify() (bool, api2go.HTTPError) {
var verifyErrors []api2go.Error
var httpError api2go.HTTPError
if c.Brand == "" {
newErr := newVerifyError(
"Invalid Attribute",
"attribute cannot be empty",
"/data/attributes/brand")
verifyErrors = append(verifyErrors, newErr)
}
if c.Model == "" {
newErr := newVerifyError(
"Invalid Attribute",
"attribute cannot be empty",
"/data/attributes/model")
verifyErrors = append(verifyErrors, newErr)
}
if c.Status != "OnTheWay" &&
c.Status != "InStock" &&
c.Status != "Sold" &&
c.Status != "Discontinued" {
newErr := newVerifyError(
"Invalid Attribute",
"attribute must be one of: OnTheWay, InStock, Sold, Discontinued",
"/data/attributes/brand")
verifyErrors = append(verifyErrors, newErr)
}
ok := len(verifyErrors) == 0
if !ok {
httpError := api2go.NewHTTPError(
errors.New("Invalid content"),
"Invalid content",
http.StatusBadRequest)
httpError.Errors = verifyErrors
}
return ok, httpError
}
func newVerifyError(title string, detail string, pointer string) api2go.Error {
var newError api2go.Error
newError.Title = title
newError.Detail = detail
newError.Source = &api2go.ErrorSource{Pointer: pointer}
return newError
}
// GetID to satisfy jsonapi.MarshalIdentifier interface
func (u Car) GetID() string {
return u.ID
func (c Car) GetID() string {
return c.ID
}
// SetID to satisfy jsonapi.UnmarshalIdentifier interface
func (u *Car) SetID(id string) error {
u.ID = id
func (c *Car) SetID(id string) error {
c.ID = id
return nil
}
// GetReferences to satisfy the jsonapi.MarshalReferences interface
func (u Car) GetReferences() []jsonapi.Reference {
func (c Car) GetReferences() []jsonapi.Reference {
return []jsonapi.Reference{}
}
// GetReferencedIDs to satisfy the jsonapi.MarshalLinkedRelations interface
func (u Car) GetReferencedIDs() []jsonapi.ReferenceID {
func (c Car) GetReferencedIDs() []jsonapi.ReferenceID {
return []jsonapi.ReferenceID{}
}
// GetReferencedStructs to satisfy the jsonapi.MarhsalIncludedRelations interface
func (u Car) GetReferencedStructs() []jsonapi.MarshalIdentifier {
func (c Car) GetReferencedStructs() []jsonapi.MarshalIdentifier {
return []jsonapi.MarshalIdentifier{}
}
// SetToManyReferenceIDs sets the sweets reference IDs and satisfies the jsonapi.UnmarshalToManyRelations interface
func (u *Car) SetToManyReferenceIDs(name string, IDs []string) error {
func (c *Car) SetToManyReferenceIDs(name string, IDs []string) error {
return errors.New("There is no to-many relationship with the name " + name)
}
// AddToManyIDs adds some new sweets that a users loves so much
func (u *Car) AddToManyIDs(name string, IDs []string) error {
func (c *Car) AddToManyIDs(name string, IDs []string) error {
return errors.New("There is no to-many relationship with the name " + name)
}
// DeleteToManyIDs removes some sweets from a users because they made him very sick
func (u *Car) DeleteToManyIDs(name string, IDs []string) error {
func (c *Car) DeleteToManyIDs(name string, IDs []string) error {
return errors.New("There is no to-many relationship with the name " + name)
}

View File

@ -122,6 +122,10 @@ func (s CarResource) Create(obj interface{}, r api2go.Request) (api2go.Responder
return &Response{}, api2go.NewHTTPError(errors.New("Invalid instance given"), "Invalid instance given", http.StatusBadRequest)
}
if ok, httpErr := car.Verify(); !ok {
return &Response{}, httpErr
}
id := s.CarStorage.Insert(car)
car.ID = id
@ -141,6 +145,10 @@ func (s CarResource) Update(obj interface{}, r api2go.Request) (api2go.Responder
return &Response{}, api2go.NewHTTPError(errors.New("Invalid instance given"), "Invalid instance given", http.StatusBadRequest)
}
if ok, httpErr := car.Verify(); !ok {
return &Response{}, httpErr
}
err := s.CarStorage.Update(car)
return &Response{Res: car, Code: http.StatusNoContent}, err
return &Response{Code: http.StatusOK}, err
}

View File

@ -8,9 +8,7 @@ type Response struct {
func (r Response) Metadata() map[string]interface{} {
return map[string]interface{}{
"author": "GenZmeY",
"license": "wtfpl",
"license-url": "http://www.wtfpl.net",
"author": "GenZmeY",
}
}