From aaab06e14c8c1625fd54dbb7a9a60f3997c7434b Mon Sep 17 00:00:00 2001 From: Braeden Sowinski Date: Wed, 28 Sep 2022 13:10:29 -0700 Subject: [PATCH] update responses and add query search endpoint --- api/handlers/api.go | 6 ++++- api/handlers/cow.go | 41 +++++++++++++++++++++++++++++----- models/cow.go | 18 +++++++-------- models/{responses.go => io.go} | 13 ++++++++--- 4 files changed, 59 insertions(+), 19 deletions(-) rename models/{responses.go => io.go} (70%) diff --git a/api/handlers/api.go b/api/handlers/api.go index 9855164..d38b9eb 100644 --- a/api/handlers/api.go +++ b/api/handlers/api.go @@ -7,6 +7,7 @@ import ( "github.com/SowinskiBraeden/SulliCartShare/api" "github.com/SowinskiBraeden/SulliCartShare/models" + "github.com/go-playground/validator/v10" "github.com/gorilla/mux" "go.uber.org/zap" @@ -14,6 +15,8 @@ import ( "github.com/SowinskiBraeden/SulliCartShare/databases" ) +var validate = validator.New() + // App stores the router and db connection so it can be reused type App struct { Router *mux.Router @@ -33,7 +36,8 @@ func (a *App) New() *mux.Router { apiCreate := r.PathPrefix("/api/v1").Subrouter() apiCreate.Handle("/cow/{cow_id}", api.Middleware(http.HandlerFunc(cow.CowByIDHandler))).Methods("GET") // By Object ID not CowCode - apiCreate.Handle("/cows", api.Middleware(http.HandlerFunc(cow.CowHandler))).Methods("GET") + apiCreate.Handle("/cows", api.Middleware(http.HandlerFunc(cow.CowHandler))).Methods("GET") // Returns all cows + apiCreate.Handle("/cows", api.Middleware(http.HandlerFunc(cow.CowHandlerQuery))).Methods("POST") // Returns list of cows based of query apiCreate.Handle("/cows/new", api.Middleware(http.HandlerFunc(cow.NewCowHandler))).Methods("POST") apiCreate.Handle("/cows/update/{cow_id}", api.Middleware(http.HandlerFunc(cow.UpdateCowHandler))).Methods("POST") // By Object ID not CowCode diff --git a/api/handlers/cow.go b/api/handlers/cow.go index 3b79561..4a702a4 100644 --- a/api/handlers/cow.go +++ b/api/handlers/cow.go @@ -10,22 +10,16 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" - "github.com/go-playground/validator/v10" - "github.com/SowinskiBraeden/SulliCartShare/config" "github.com/SowinskiBraeden/SulliCartShare/databases" "github.com/SowinskiBraeden/SulliCartShare/models" ) -var validate = validator.New() - // Cow exported for testing purposes type Cow struct { DB databases.CowDatabase } -// TODO: update api return messages - // CowHandler returns all cows func (c Cow) CowHandler(w http.ResponseWriter, r *http.Request) { dbResp, err := c.DB.Find(context.TODO(), bson.M{}) @@ -47,6 +41,41 @@ func (c Cow) CowHandler(w http.ResponseWriter, r *http.Request) { w.Write(b) } +// CowHandlerQuery is the same as CowHanlder, but queries a specific list of objects by Name +func (c Cow) CowHandlerQuery(w http.ResponseWriter, r *http.Request) { + var query models.Query // Json data will represent the query model + + // validate the request body + if err := json.NewDecoder(r.Body).Decode(&query); err != nil { + config.ErrorStatus("failed to unpack request body", http.StatusInternalServerError, w, err) + return + } + + // use the validator library to validate required fields + if validationErr := validate.Struct(&query); validationErr != nil { + config.ErrorStatus("invalid request body", http.StatusBadRequest, w, validationErr) + return + } + + dbResp, err := c.DB.Find(context.TODO(), bson.M{"Detials.Name": query.Name}) // Search by cow name + if err != nil { + config.ErrorStatus("failed to get cows", http.StatusNotFound, w, err) + return + } + + // If len == 0 then we will just return an empty data object + if len(dbResp) == 0 { + dbResp = []models.Cow{} + } + b, err := json.Marshal(dbResp) + if err != nil { + config.ErrorStatus("failed to marshal response", http.StatusInternalServerError, w, err) + return + } + w.WriteHeader(http.StatusOK) + w.Write(b) +} + // CowByIDHandler returns a cow by ID func (c Cow) CowByIDHandler(w http.ResponseWriter, r *http.Request) { cowID := mux.Vars(r)["cow_id"] diff --git a/models/cow.go b/models/cow.go index 037f74d..cd96dfb 100644 --- a/models/cow.go +++ b/models/cow.go @@ -12,18 +12,18 @@ type Cow struct { // BookDetails holds the checkout details type BookDetails struct { - Author string `json:"Author" bson:"Author"` // User who booked - Devices []string `json:"Devices" bson:"Devices"` // Array of device mongo ID's - Block string `json:"Block" bson:"Block"` // Block that is booked - Date primitive.DateTime `json:"Date" bson:"Date"` // Date this booking occurs + Author string `json:"author" bson:"author"` // User who booked + Devices []string `json:"devices" bson:"devices"` // Array of device mongo ID's + Block string `json:"block" bson:"block"` // Block that is booked + Date primitive.DateTime `json:"date" bson:"date"` // Date this booking occurs } // CowDetails holds the structure for the inner cow structure as // defined in the cow collection in mongo type CowDetails struct { - CowCode string `json:"CowCode" bson:"CowCode"` // eg. CA-01 - CollectionType string `json:"CollectionType" bson:"CollectionType"` // eg. Laptop, Ipad, etc - TotalDevices int `json:"TotalDevices" bson:"TotalDevices"` // # of devices in that cart collection - Bookings []BookDetails `json:"Bookings" bson:"Bookings"` // An array of all active bookings (send top 10) - Devices []string `json:"Devices" bson:"Devices"` // Array of device mongo ID's + Name string `json:"name" bson:"name"` // eg. CA-01 + Collection string `json:"collection" bson:"collection"` // eg. Laptop, Ipad, etc + TotalDevices int `json:"totalDevices" bson:"totalDevices"` // # of devices in that cart collection + Bookings []BookDetails `json:"bookings" bson:"bookings"` // An array of all active bookings (send top 10) + Devices []string `json:"devices" bson:"devices"` // Array of device mongo ID's } diff --git a/models/responses.go b/models/io.go similarity index 70% rename from models/responses.go rename to models/io.go index e0a2dfd..6e584fc 100644 --- a/models/responses.go +++ b/models/io.go @@ -1,5 +1,7 @@ package models +// This is io.go (input/output) for json queries and responses + // HealthCheckResponse returns the health check response duh type HealthCheckResponse struct { Alive bool `json:"alive"` @@ -14,11 +16,16 @@ type UserResponse struct { // ErrorMessageResponse returns the error message response struct type ErrorMessageResponse struct { - Response MessageError + Response MessageError `json:"response"` } // MessageError contains the inner details for the error message response type MessageError struct { - Message string - Error string + Message string `json:"message"` + Error string `json:"error"` +} + +// Query for search queries by name +type Query struct { + Name string `json:"name"` }