go-jsonapi-example/internal/resource/resource_car.go

145 lines
3.5 KiB
Go
Raw Normal View History

2021-03-18 18:52:41 +00:00
package resource
import (
"errors"
"net/http"
2021-03-21 11:25:23 +00:00
"sort"
2021-03-18 18:52:41 +00:00
"strconv"
"go-jsonapi-example/internal/model"
"go-jsonapi-example/internal/storage"
"github.com/manyminds/api2go"
)
// CarResource for api2go routes
type CarResource struct {
CarStorage *storage.CarStorage
}
// FindAll to satisfy api2go data source interface
func (s CarResource) FindAll(r api2go.Request) (api2go.Responder, error) {
2021-03-21 11:03:35 +00:00
return &Response{Res: s.CarStorage.GetAll()}, nil
2021-03-18 18:52:41 +00:00
}
// PaginatedFindAll can be used to load cars in chunks
func (s CarResource) PaginatedFindAll(r api2go.Request) (uint, api2go.Responder, error) {
var (
2021-03-21 11:25:23 +00:00
result storage.Cars
2021-03-18 18:52:41 +00:00
number, size, offset, limit string
)
cars := s.CarStorage.GetAll()
2021-03-21 11:25:23 +00:00
sort.Sort(cars)
2021-03-18 18:52:41 +00:00
numberQuery, ok := r.QueryParams["page[number]"]
if ok {
number = numberQuery[0]
}
sizeQuery, ok := r.QueryParams["page[size]"]
if ok {
size = sizeQuery[0]
}
offsetQuery, ok := r.QueryParams["page[offset]"]
if ok {
offset = offsetQuery[0]
}
limitQuery, ok := r.QueryParams["page[limit]"]
if ok {
limit = limitQuery[0]
}
if size != "" {
sizeI, err := strconv.ParseUint(size, 10, 64)
if err != nil {
return 0, &Response{}, err
}
numberI, err := strconv.ParseUint(number, 10, 64)
if err != nil {
return 0, &Response{}, err
}
start := sizeI * (numberI - 1)
for i := start; i < start+sizeI; i++ {
if i >= uint64(len(cars)) {
break
}
2021-03-21 11:25:23 +00:00
result = append(result, cars[i])
2021-03-18 18:52:41 +00:00
}
} else {
limitI, err := strconv.ParseUint(limit, 10, 64)
if err != nil {
return 0, &Response{}, err
}
offsetI, err := strconv.ParseUint(offset, 10, 64)
if err != nil {
return 0, &Response{}, err
}
for i := offsetI; i < offsetI+limitI; i++ {
if i >= uint64(len(cars)) {
break
}
2021-03-21 11:25:23 +00:00
result = append(result, cars[i])
2021-03-18 18:52:41 +00:00
}
}
return uint(len(cars)), &Response{Res: result}, nil
}
2021-03-21 11:25:23 +00:00
2021-03-18 18:52:41 +00:00
// FindOne to satisfy `api2go.DataSource` interface
func (s CarResource) FindOne(ID string, r api2go.Request) (api2go.Responder, error) {
2021-03-21 11:03:35 +00:00
intID, err := strconv.ParseUint(ID, 10, 64)
if err != nil {
return &Response{}, api2go.NewHTTPError(err, err.Error(), http.StatusNotFound)
}
car, err := s.CarStorage.GetOne(intID)
2021-03-18 18:52:41 +00:00
if err != nil {
return &Response{}, api2go.NewHTTPError(err, err.Error(), http.StatusNotFound)
}
return &Response{Res: car}, nil
}
// Create method to satisfy `api2go.DataSource` interface
func (s CarResource) Create(obj interface{}, r api2go.Request) (api2go.Responder, error) {
car, ok := obj.(model.Car)
if !ok {
return &Response{}, api2go.NewHTTPError(errors.New("Invalid instance given"), "Invalid instance given", http.StatusBadRequest)
}
2021-03-19 17:24:02 +00:00
if ok, httpErr := car.Verify(); !ok {
return &Response{}, httpErr
}
2021-03-18 18:52:41 +00:00
id := s.CarStorage.Insert(car)
car.ID = id
return &Response{Res: car, Code: http.StatusCreated}, nil
}
// Delete to satisfy `api2go.DataSource` interface
func (s CarResource) Delete(id string, r api2go.Request) (api2go.Responder, error) {
2021-03-21 11:03:35 +00:00
intID, err := strconv.ParseUint(id, 10, 64)
if err == nil {
err = s.CarStorage.Delete(intID)
}
2021-03-18 18:52:41 +00:00
return &Response{Code: http.StatusNoContent}, err
}
//Update stores all changes on the car
func (s CarResource) Update(obj interface{}, r api2go.Request) (api2go.Responder, error) {
car, ok := obj.(model.Car)
if !ok {
return &Response{}, api2go.NewHTTPError(errors.New("Invalid instance given"), "Invalid instance given", http.StatusBadRequest)
}
2021-03-19 17:24:02 +00:00
if ok, httpErr := car.Verify(); !ok {
return &Response{}, httpErr
}
2021-03-18 18:52:41 +00:00
err := s.CarStorage.Update(car)
2021-03-19 17:24:02 +00:00
return &Response{Code: http.StatusOK}, err
2021-03-18 18:52:41 +00:00
}