Now that we've worked through fetching and creating products, it's time to cover making changes to a product that already exists. Suppose we have just found out the price for one of the products in the system (Purple Pen 2.0) is too low. We need to update this product's price to $1.50. While we're at it, we need to also change the name to be more eye catching to drive up sales.
Let's take a look at the current state of that product and see what we need to change. We could look back to see what the id
of that product is by scrolling back in the terminal (or going back a few pages in this book), but it is just as easy to fetch all of the products and take a look at what is there. On a system with a lot of data this wouldn't be practical, but it will be fine in this case since the web store only has a handful of products.
$ http GET https://web-store.onrender.com/v1/products
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-Ray: 8e806c423be8e295-BEG
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 25 Nov 2024 08:56:00 GMT
Server: cloudflare
Transfer-Encoding: chunked
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: 7ec8b09f-0cd2-48ae
status: 200 OK
x-render-origin-server: Render
[
{
"id": 1,
"name": "Red Pen",
"price": 100,
"sku": "redp100"
},
{
"id": 2,
"name": "Blue Pen",
"price": 100,
"sku": "blup100"
},
{
"id": 3,
"name": "Black Pen",
"price": 100,
"sku": "blap100"
},
{
"id": 4,
"name": "Purple Pen",
"price": 100,
"sku": "purp100"
},
{
"id": 5,
"name": "Purple Pen 2.0",
"price": 100,
"sku": "purp101"
}
]
It looks like the product that needs to be updated has an id
of 5
. Making a change to this product is going to be very similar to creating a product, with two main differences:
PUT is the correct HTTP method for updating the value of a resource and sending all of its values back to the server. PUT tells the server to put this resource in this place. According to the HTTP spec, PUT requests must take a complete representation of the resource being updated. This means that if a parameter was required to create the resource, it is required to be sent in any PUT requests modifying that resource. This also means that any parameter left out of a PUT request is assumed to have an empty value (usually null or nil). Most APIs don't strictly follow this requirement, however, and provide a much simpler behavior by updating any parameters sent in a PUT request, and not modifying any other parameters that are already on the resource. This is technically the behavior of another HTTP method, PATCH, which we won't get into in this book as it is new and not yet widely used.
The web store follows the PUT convention of not requiring all parameters to be sent when updating a product. Let's take advantage of this and update just the price of the product. A product's price is represented in cents, so instead of sending a value of 1.50
, we will use 150
(make sure you use the correct id
value at the end of the request path (/5
) for the Purple
Pen. Check the output you saw above -- it may not be item 5
):
$ http PUT https://web-store.onrender.com/v1/products/5 Authorization:"token AUTH_TOKEN" price=150
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-Ray: 8e806e70693ee295-BEG
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 25 Nov 2024 08:57:29 GMT
Server: cloudflare
Transfer-Encoding: chunked
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: e8c99075-0baf-4807
status: 200 OK
x-render-origin-server: Render
{
"id": 5,
"name": "Purple Pen 2.0",
"price": 150,
"sku": "purp101"
}
We can see from the response that the name
and sku
of the product remain unchanged and the price
has been updated to 150
. Multiple values can be changed at once by sending them at the same time (don't forget to use the current id
number):
$ http PUT https://web-store.onrender.com/v1/products/5 Authorization:"token AUTH_TOKEN" name="New and Improved Purple Pen" sku="newp100"
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-Ray: 8e806fa53885e291-BEG
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 25 Nov 2024 08:58:18 GMT
Server: cloudflare
Transfer-Encoding: chunked
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: 48c6fe3e-4169-4b7c
status: 200 OK
x-render-origin-server: Render
{
"id": 5,
"name": "New and Improved Purple Pen",
"price": 150,
"sku": "newp100"
}
Fetching the product shows that the new values we have sent to the server have been stored successfully (don't forget to use the correct id
):
$ http GET https://web-store.onrender.com/v1/products/5
HTTP/1.1 200 OK
CF-Cache-Status: DYNAMIC
CF-Ray: 8e80708e8b3871a6-BEG
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 25 Nov 2024 08:58:55 GMT
Server: cloudflare
Transfer-Encoding: chunked
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: 31988916-4cb7-4704
status: 200 OK
x-render-origin-server: Render
{
"id": 5,
"name": "New and Improved Purple Pen",
"price": 150,
"sku": "newp100"
}
Now that the updates have been made to the New and Improved Purple Pen
, it is time to remove the older product Purple Pen
from our system. Deleting a resource is very similar to fetching a resource, with one difference: Using the DELETE HTTP method instead of GET. Otherwise, everything else should look very familiar. On the web store API, delete requests need to be authenticated, so those arguments to http
should be included:
$ http DELETE https://web-store.onrender.com/v1/products/4 Authorization:"token AUTH_TOKEN"
HTTP/1.1 204 No Content
CF-Cache-Status: DYNAMIC
CF-Ray: 8e8071bb3875e292-BEG
Connection: keep-alive
Date: Mon, 25 Nov 2024 08:59:43 GMT
Server: cloudflare
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: 611e245f-fc8f-4b41
status: 204 No Content
x-render-origin-server: Render
204 No Content
is in the format 2xx, which means the request was processed successfully. 204 No Content
is commonly used when it doesn't make sense to return anything in the response body, and deleting a resource is one such case. If there is no longer a resource at the path being accessed, there isn't anything to send back.
Although we have no reason not to trust the web store API, we can attempt to fetch the product that was just deleted to see if there is still a resource at its path:
$ http GET https://web-store.onrender.com/v1/products/4
HTTP/1.1 404 Not Found
CF-Cache-Status: DYNAMIC
CF-Ray: 8e8072a53c7ce294-BEG
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Mon, 25 Nov 2024 09:00:20 GMT
Server: cloudflare
Transfer-Encoding: chunked
Vary: Origin, Accept-Encoding
alt-svc: h3=":443"; ma=86400
rndr-id: 9cda9704-3b48-4c28
status: 404 Not Found
x-render-origin-server: Render
{
"message": "Couldn't find WebStore::Product with 'id'=4",
"status_code": 404
}
It looks like the product is gone, which is exactly what we would expect.
Now that we've gone over what web APIs do and how they operate, it is time to apply these concepts to a real API.