Lesson 5
Updating and Deleting Resources with PUT, PATCH, and DELETE in Go
Updating and Deleting Resources with PUT, PATCH, and DELETE

Welcome to this lesson focusing on enhancing your skills in interacting with RESTful APIs by updating and deleting resources. In previous lessons, you learned how to retrieve and create resources using the GET and POST methods. Now, you will explore the PUT, PATCH, and DELETE methods, which are crucial for modifying existing resources or removing them when they are no longer needed.

Understanding PUT, PATCH, and DELETE Methods

To effectively manage resources within an API, it's essential to understand how to use the following methods:

  • PUT: This method is used for completely updating a resource. You replace the current resource with the new data you provide in the request body. For example, if you're updating a to-do item, you'll include all the new details of the item in the body of the request and specify the resource ID in the request path to indicate which item you are updating.

  • PATCH: Use this method to make partial updates to a resource. You only need to include the specific fields you're updating in the request body. For instance, if you're only changing the description of a to-do item, you'll pass just the new description in the body. The resource ID is specified in the request path to identify which item is being modified.

  • DELETE: This straightforward method removes a resource from the server. You specify which resource to delete by including its identifier in the request path. No request body is needed since you're not sending any data, just instructing the server to remove the resource corresponding to that ID.

Successful requests using these methods typically return status codes of 200 (OK) or 204 (No Content). A 200 status code means the operation was successful and also returns content, such as a representation of the updated resource. In contrast, a 204 status code indicates success but with no content returned, meaning the server successfully processed the request but isn't providing any additional information. These methods are crucial for performing full CRUD (Create, Read, Update, Delete) functionality in API management.

Setting Up the Go Environment

Before executing HTTP requests, let's set up our Go environment by importing the necessary Go packages and defining the base URL for our API interactions:

Go
1package main 2 3import ( 4 "bytes" 5 "fmt" 6 "io" 7 "net/http" 8) 9 10// Base URL for the API 11const baseUrl = "http://localhost:8000"

With this setup in place, you're well-prepared to explore PUT, PATCH, and DELETE operations for resource management.

Using `http.NewRequest` for Custom HTTP Requests

So far, we’ve used http.Get and http.Post to interact with APIs. These functions work well for simple requests, but sometimes we need more control—especially when using PUT, PATCH, and DELETE, which don’t have built-in helper functions in Go.

For these cases, Go provides the http.NewRequest function, which allows us to create a customizable HTTP request.

Why Use `http.NewRequest`?
  • Supports all HTTP methods (GET, POST, PUT, PATCH, DELETE, etc.).
  • Allows us to set headers (like "Content-Type": "application/json").
  • Gives more control over the request body.
Creating a Custom HTTP Request

Here’s an example of how to create a request using http.NewRequest:

Go
1req, err := http.NewRequest(http.MethodPut, "http://example.com/resource", nil) 2if err != nil { 3 log.Fatalf("Failed to create request: %v", err) 4}

Once the request is created, we send it using an http.Client:

Go
1client := &http.Client{} 2resp, err := client.Do(req) 3if err != nil { 4 log.Fatalf("Failed to send request: %v", err) 5}

Since PUT, PATCH, and DELETE require us to send structured data, we use http.NewRequest to define these requests, then send them using an http.Client.

Next, let’s see http.NewRequest in action as we update resources with the PUT method.

Updating Resources with PUT

The PUT method is utilized when you need to update an entire resource. Imagine you have a to-do item that needs a complete overhaul, such as updating the task description, adding more details, or marking it as completed. The PUT request replaces the current resource representation with the new one you provide.

Here's an example of how to send a PUT request to update a to-do item:

Go
1func updateTodoWithPut(todoID int) { 2 // Updated todo data for PUT 3 updatedTodo := `{ 4 "title": "Buy groceries and snacks", 5 "done": true, 6 "description": "Milk, eggs, bread, coffee, and chips." 7 }` 8 9 // Send PUT request 10 request, err := http.NewRequest(http.MethodPut, baseUrl+"/todos/"+fmt.Sprint(todoID), bytes.NewBufferString(updatedTodo)) 11 if err != nil { 12 fmt.Println("Error creating request:", err) 13 return 14 } 15 request.Header.Set("Content-Type", "application/json") 16 17 client := &http.Client{} 18 response, err := client.Do(request) 19 if err != nil { 20 fmt.Println("Error sending request:", err) 21 return 22 } 23 24 // Check if the request was successful 25 if response.StatusCode == http.StatusOK { 26 body, _ := io.ReadAll(response.Body) 27 fmt.Println("Todo updated successfully with PUT!") 28 fmt.Println(string(body)) 29 } else { 30 // Handle potential errors 31 fmt.Println("Error updating the todo with PUT") 32 fmt.Printf("Status Code: %d\n", response.StatusCode) 33 body, _ := io.ReadAll(response.Body) 34 fmt.Println("Error Details:", string(body)) 35 } 36}

In this code, we specify the complete new data for the to-do item and send the request using Go's http.NewRequest method. Upon receiving a 200 status code using http.StatusOK, you know the update was successful, and you can print the new representation of the to-do item. It's important to note that for our API, a PUT request requires all fields (title, description, and done) to be provided. If any field is missing, the request will fail and return a status code of 400. In cases where you only need to update specific fields, rather than the entire resource, the PATCH method is more suitable.

Partial Updates with PATCH

Unlike PUT, the PATCH method is specifically designed for partial updates. When you need to modify only a specific field of a resource, PATCH ensures system efficiency and data integrity without the need to send a full representation.

Here's an example of performing a PATCH request on a resource:

Go
1func updateTodoWithPatch(todoID int) { 2 // Partial updated data 3 patchData := `{ 4 "description": "Updated description" 5 }` 6 7 // Send PATCH request 8 request, err := http.NewRequest(http.MethodPatch, baseUrl+"/todos/"+fmt.Sprint(todoID), bytes.NewBufferString(patchData)) 9 if err != nil { 10 fmt.Println("Error creating request:", err) 11 return 12 } 13 request.Header.Set("Content-Type", "application/json") 14 15 client := &http.Client{} 16 response, err := client.Do(request) 17 if err != nil { 18 fmt.Println("Error sending request:", err) 19 return 20 } 21 22 // Check if the request was successful 23 if response.StatusCode == http.StatusOK { 24 body, _ := io.ReadAll(response.Body) 25 fmt.Println("Todo updated successfully with PATCH!") 26 fmt.Println(string(body)) 27 } else { 28 // Handle potential errors 29 fmt.Println("Error updating the todo with PATCH") 30 fmt.Printf("Status Code: %d\n", response.StatusCode) 31 body, _ := io.ReadAll(response.Body) 32 fmt.Println("Error Details:", string(body)) 33 } 34}

In this scenario, only the description field is updated. After sending the PATCH request using Go's http.NewRequest method, we can check the response status code to confirm success. Successful updates with a status code of 200 allow you to view the updated resource fields, while any errors are managed by inspecting and printing error details.

Deleting Resources with DELETE

After learning how to update resources using PUT and PATCH, let's move on to deleting resources with the DELETE method. This method is straightforward - it's used to remove a resource from the server, which is important for keeping your data clean and relevant.

Here's how you can perform a DELETE request:

Go
1func deleteTodoWithDelete(todoID int) { 2 // Send DELETE request 3 request, err := http.NewRequest(http.MethodDelete, baseUrl+"/todos/"+fmt.Sprint(todoID), nil) 4 if err != nil { 5 fmt.Println("Error creating request:", err) 6 return 7 } 8 9 client := &http.Client{} 10 response, err := client.Do(request) 11 if err != nil { 12 fmt.Println("Error sending request:", err) 13 return 14 } 15 16 // Check if the request was successful 17 if response.StatusCode == http.StatusNoContent { 18 fmt.Println("Todo deleted successfully!") 19 } else { 20 // Handle potential errors 21 fmt.Println("Error deleting the todo") 22 fmt.Printf("Status Code: %d\n", response.StatusCode) 23 body, _ := io.ReadAll(response.Body) 24 fmt.Println("Error Details:", string(body)) 25 } 26}

In this example, we're sending a DELETE request to remove a specific to-do item by specifying its ID in the request path. When the server successfully deletes the resource, you will typically receive a 204 status code using http.StatusNoContent. This code means "No Content," indicating that the deletion was successful, but there's no additional data to send back.

However, it's important to note that some services might return a 200 status code along with some content, such as a message. This can vary depending on how the service is designed, so always check the API documentation for specifics on how it handles deletions.

Summary and Preparation for Practice Exercises

This lesson provided you with a comprehensive understanding of the PUT, PATCH, and DELETE methods, enhancing your ability to modify and manage resources through API interactions using Go. You learned how to update complete resources with PUT, make partial modifications with PATCH, and delete resources using DELETE. Understanding these operations is key to mastering CRUD functionality in RESTful API management using Go.

As you proceed to the practice exercises, you're encouraged to apply these concepts to reinforce your understanding and learn through practice. Each operation is a building block towards becoming proficient in interacting with APIs using Go. Keep up the great work as you progress through the exercises, further cementing your knowledge and skills in API resource management!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.