From 19a844ea2e07768a2c71e8867d1e5ad0deace901 Mon Sep 17 00:00:00 2001 From: Maxime Delporte Date: Thu, 6 Nov 2025 17:10:33 +0100 Subject: [PATCH] Updating Insert MovieModel's method inserting a new record in the movies table. Updating createMovieHandler to use Insert MovieModel's method. --- cmd/api/movies.go | 18 ++++++++++++++++-- internal/data/movies.go | 13 ++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/cmd/api/movies.go b/cmd/api/movies.go index cc7fd56..11fb383 100644 --- a/cmd/api/movies.go +++ b/cmd/api/movies.go @@ -42,8 +42,22 @@ func (app *application) createMovieHandler(w http.ResponseWriter, r *http.Reques return } - // Dump the contents of the input struct in a HTTP response. - fmt.Fprintf(w, "%+v\n", input) + // Call the Insert() method on our movies model, passing in a pointer to the validated struct. This will create a record in the database and update the movie struct with the system-generated information + err = app.models.Movies.Insert(movie) + if err != nil { + app.serverErrorResponse(w, r, err) + return + } + + // When sending a HTTP response, we want to include a location header to let the client know which URL they can find the newly-created resource at. We make an empty http.Header map and then use the Set() method to add a new location header, interpolating the system-generated ID for our new movie in the URL. + headers := make(http.Header) + headers.Set("Location", fmt.Sprintf("/v1/movies/%d", movie.ID)) + + // Write a JSON response with a 201 Created status code, the movie data in the response body, and the Location header + err = app.writeJSON(w, http.StatusCreated, envelope{"movie": movie}, headers) + if err != nil { + app.serverErrorResponse(w, r, err) + } } // "GET /v1/movies/:id" diff --git a/internal/data/movies.go b/internal/data/movies.go index fda2ae5..409d685 100644 --- a/internal/data/movies.go +++ b/internal/data/movies.go @@ -2,6 +2,7 @@ package data import ( "database/sql" + "github.com/lib/pq" "time" "greenlight.craftr.fr/internal/validator" @@ -51,7 +52,17 @@ type MovieModel struct { // Insert : Inserting a new record in the movies table func (m MovieModel) Insert(movie *Movie) error { - return nil + // Define the SQL query for inserting a new record in the movies table and returning the system-generated data. + query := ` + INSERT INTO movies (title, year, runtime, genres) + VALUES ($1, $2, $3, $4) + RETURNING id, created_at, version` + + // Create an args slice containing the values for the placeholder parameters from the movie struct. Declaring this slice immediately next to our SQL query helps to make it nice and clear *what values are being used where* in the query + args := []any{movie.Title, movie.Year, movie.Runtime, pq.Array(movie.Genres)} + + // Use the QueryRow() method to execute the SQL query on our connection pool, passing in the args slice as a variadic parameter and scanning the system-generated id, created_at and version values into the movie struct. + return m.DB.QueryRow(query, args...).Scan(&movie.ID, &movie.CreatedAt, &movie.Version) } // Get : Fetching a specific record from the movies table