From b76496e0963987ba11ad7c7cd9e6281a76d976aa Mon Sep 17 00:00:00 2001 From: Maxime Delporte Date: Fri, 7 Nov 2025 11:57:04 +0100 Subject: [PATCH] Updating updateMovieHandler to be able to update only some fields (patch instead of put). Update routes with the correct verb. --- cmd/api/movies.go | 29 ++++++++++++++++++++--------- cmd/api/routes.go | 2 +- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/cmd/api/movies.go b/cmd/api/movies.go index e8b5fe2..195f75e 100644 --- a/cmd/api/movies.go +++ b/cmd/api/movies.go @@ -109,11 +109,12 @@ func (app *application) updateMovieHandler(w http.ResponseWriter, r *http.Reques } // Declare an input struct to hold the expected data from the client + // Use pointers for the Title, Year and Runtime fields : so we can see if a client has provided a particular key/value pair in the JSON. var input struct { - Title string `json:"title"` - Year int32 `json:"year"` - Runtime data.Runtime `json:"runtime"` - Genres []string `json:"genres"` + Title *string `json:"title"` + Year *int32 `json:"year"` + Runtime *data.Runtime `json:"runtime"` + Genres []string `json:"genres"` } // Read the JSON request body data into the input struct @@ -123,11 +124,21 @@ func (app *application) updateMovieHandler(w http.ResponseWriter, r *http.Reques return } - // Copy the values from the request body to the appropriate fields of the movie record. - movie.Title = input.Title - movie.Year = input.Year - movie.Runtime = input.Runtime - movie.Genres = input.Genres + // If the input.Title value is nil, then we know that no corresponding "title" key/value pair was provided in the JSON request body. So we move on and leave the movie record unchanged. Otherwise, we update the movie record with the new title value. Importantly, because input.Title is now a pointer to a string, we need to dereference the pointer using the * operator to get the underlying value before assigning it to our movie record. + if input.Title != nil { + movie.Title = *input.Title + } + + // We also do the same for the other fields in the input struct. + if input.Year != nil { + movie.Year = *input.Year + } + if input.Runtime != nil { + movie.Runtime = *input.Runtime + } + if input.Genres != nil { + movie.Genres = input.Genres // We don't need to dereference a slice. + } // Validate the updated movie record, sending the client a 422 Unprocessable Entity response if any checks fail. v := validator.New() diff --git a/cmd/api/routes.go b/cmd/api/routes.go index 17c2bac..f066228 100644 --- a/cmd/api/routes.go +++ b/cmd/api/routes.go @@ -24,7 +24,7 @@ func (app *application) routes() http.Handler { router.HandlerFunc(http.MethodGet, "/v1/healthcheck", app.healthcheckHandler) router.HandlerFunc(http.MethodPost, "/v1/movies", app.createMovieHandler) router.HandlerFunc(http.MethodGet, "/v1/movies/:id", app.showMovieHandler) - router.HandlerFunc(http.MethodPut, "/v1/movies/:id", app.updateMovieHandler) + router.HandlerFunc(http.MethodPatch, "/v1/movies/:id", app.updateMovieHandler) router.HandlerFunc(http.MethodDelete, "/v1/movies/:id", app.deleteMovieHandler) // Return the httprouter instance.