122 lines
3.1 KiB
Go
122 lines
3.1 KiB
Go
package server
|
|
|
|
import (
|
|
"awesomeProject/server/middleware"
|
|
"awesomeProject/store"
|
|
"context"
|
|
"encoding/json"
|
|
"github.com/gorilla/mux"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
type BookStoreServer struct {
|
|
s store.Store
|
|
srv *http.Server
|
|
}
|
|
|
|
func NewBookStoreServer(addr string, s store.Store) *BookStoreServer {
|
|
srv := &BookStoreServer{s: s, srv: &http.Server{Addr: addr}}
|
|
router := mux.NewRouter()
|
|
router.HandleFunc("/book", srv.createBookHandler).Methods("POST")
|
|
router.HandleFunc("/book/{id}", srv.updateBookHandler).Methods("POST")
|
|
router.HandleFunc("/book/{id}", srv.getBookHandler).Methods("GET")
|
|
router.HandleFunc("/book", srv.getAllBooksHandler).Methods("GET")
|
|
router.HandleFunc("/book/{id}", srv.delBookHandler).Methods("DELETE")
|
|
srv.srv.Handler = middleware.Logging(middleware.Validating(router))
|
|
return srv
|
|
}
|
|
|
|
func (bs *BookStoreServer) Shutdown(ctx context.Context) error {
|
|
return bs.srv.Shutdown(ctx)
|
|
}
|
|
|
|
func (bs *BookStoreServer) createBookHandler(w http.ResponseWriter, req *http.Request) {
|
|
dec := json.NewDecoder(req.Body)
|
|
var book store.Book
|
|
if err := dec.Decode(&book); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
if err := bs.s.Create(&book); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (bs *BookStoreServer) updateBookHandler(w http.ResponseWriter, req *http.Request) {
|
|
dec := json.NewDecoder(req.Body)
|
|
var book store.Book
|
|
if err := dec.Decode(&book); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
if err := bs.s.Update(&book); err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (bs *BookStoreServer) getAllBooksHandler(w http.ResponseWriter, req *http.Request) {
|
|
books, err := bs.s.GetAll()
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
response(w, books)
|
|
}
|
|
|
|
func (bs *BookStoreServer) getBookHandler(w http.ResponseWriter, req *http.Request) {
|
|
id, ok := mux.Vars(req)["id"]
|
|
if !ok {
|
|
http.Error(w, "no id found in request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
err := bs.s.Delete(id)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (bs *BookStoreServer) delBookHandler(w http.ResponseWriter, req *http.Request) {
|
|
id, ok := mux.Vars(req)["id"]
|
|
if !ok {
|
|
http.Error(w, "no id found in request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
book, err := bs.s.Get(id)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
response(w, book)
|
|
}
|
|
|
|
func response(w http.ResponseWriter, v interface{}) {
|
|
data, err := json.Marshal(v)
|
|
if err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if _, err := w.Write(data); err != nil {
|
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func (bs *BookStoreServer) ListenAndServe() (<-chan error, error) {
|
|
var err error
|
|
errChan := make(chan error)
|
|
go func() {
|
|
err = bs.srv.ListenAndServe()
|
|
errChan <- err
|
|
}()
|
|
select {
|
|
case err = <-errChan:
|
|
return nil, err
|
|
case <-time.After(time.Second):
|
|
return errChan, nil
|
|
}
|
|
}
|