Axios PUT Verb And Why I Suck
So this is one of those posts where I had such a hard time I just wanted to document it so I would have a note for myself in the future.
Here's the issue I was having:
We have a project that uses React for the frontend and Azure Functions for the API. One of our Azure functions for submitting an order required, GET, PUT, POST, DELETE.
I got the function setup and all of the backend code was working using Postman to submit requests to the API.
When I started working on the front end everything was working except for the PUT verb.
The DELETE verb code looked like this:
const handleOrderDelete = async (orderId) => {
const token = await getTokenSilently()
var response = axios.delete(`http:localhost:3000/${orderId}`, {
headers: {
Authorization: `Bearer ${token}`,
'content-type': 'application/json',
'x-functions-key': "AZURE FUNCTION KEY HERE",
},
})
if (response.statusCode === 200) {
console.log(response)
} else {
console.error(response)
}
}
The PUT verb code looked like this:
const handleOrderEdit = async (orderId) => {
const token = await getTokenSilently()
var response = axios.put(`http:localhost:3000/${orderId}`, {
headers: {
Authorization: `Bearer ${token}`,
'content-type': 'application/json',
'x-functions-key': "AZURE FUNCTION KEY HERE",
},
})
if (response.statusCode === 200) {
console.log(response)
} else {
console.error(response)
}
}
Now at this point it's important to note that I copied the handleOrderEdit
code from the handleOrderDelete
code. They are VERY similar, the only main difference being the .put
and .delete
verbs themselves.
Now if you're astute and you are familiar with Axios you may already see the issue. If not see if you can figure it out.
So the DELETE was working, but when I ran the PUT I was getting a 401 on the Network tab in chrome devtools. In my C# console I was getting the error, NO TOKEN. ERROR
.
When I looked at the request payload I saw that I had a token, "Bearer 8df7saf8d7sa8f9dsa7f89saf6798saf" or whatever. Most importantly my breakpoint I set in Visual Studio right on the opening bracket of the PUT method was not being hit.
I replaced the axios.put
call with a fetch call since they use a similar API. I had narrowed my search down to some issue with axios at this point because it was working in Postman.
I added the fetch like so:
fetch(`http://localhost:3000/${orderId}`, {
headers: {
Authorization: `Bearer ${token}`,
'content-type': 'application/json',
'x-functions-key': 'AZURE FUNCTION KEY HERE',
},
})
and it worked just fine. I started looking a bit closer and I noticed something. When I submitted my request with axios the Bearer token was in the Payload, not in the Request Header. Hmm.
So, to make a long story short, (too late amirite???), I didn't realize that the PUT verb requires a body. We're not sending a body because all we're doing is setting the order back to a different status but we're using the PUT because all of the other verbs are being used.
Typically you would ALWAYS send a body with a PUT because you're updating a record and you need to send the information your replacing. Ours is a unique usecase and since we're sending the orderId
in the url then we didn't need to send a body.
The code that fixed this whole thing is:
const handleOrderSign = async (orderId) => {
const token = await getTokenSilently()
var response = axios.put(
`${api.order.url}/${orderId}`,
{orderId}, // < -- this
{
headers: {
Authorization: `Bearer ${token}`,
'content-type': 'application/json',
'x-functions-key': api.order.key,
},
}
)
if (response.statusCode === 200) {
console.log(response)
} else {
console.error(response)
}
}
Even though I don't need to send a body I'm sending the orderId
in the body just so I better conform to the axios standard.
So this is either one of those things that everyone knows and I'm just slow on the uptake, or this is something that happened because we're not using the tool the way it was intended, or it's a lack of documentation on axios' side.
Anyway,
Thanks for reading and that's all y'all.
Top comments (9)
First of all I said the code is very similar. Meaning that my two code blocks are exactly the same except for
axios.put(
axios.delete(
But thank you SO very much for explaining to me that .put will send an HTTP PUT and .delete will perform an HTTP DELETE.
I really appreciate the fact that you explain basic principles to someone that has been writing software since 1986.
Itโs just really shitty when you break down basic concepts to someone that took the time to write a post.
I clearly say that I copy/pasted the two methods and that they are identical except for the line where the verb is. ๐คท๐ปโโ๏ธ
And then you start in with:
.put() is for an HTTP PUT.
You would think that maybe you would give someone the benefit of the doubt and not just assume that everyone is a moron and so far beneath you that you have to explain basic concepts to them.
Maybe just assume that everyone knows everything that you know. ๐คท๐ปโโ๏ธ
๐
I know exactly that DELETE is supposed to delete a resource. I mentioned in the article that I was probably not using it correctly but we don't have a choice. I AM deleting a resource for the user but I'm just moving it from a status of 'submitted' to a status of 'rejected'.
I had to obfuscate a lot of the details of what I'm doing because I work for a healthcare company and I can just be dropping IP on dev.to.
It is a good example of why it's important for APIs to have the same argument, when it might be expected by the consumer.
While it's unlikely that you'll send a request body with a
GET
or aDELETE
request and that makes it understandable that those are omitted, the question is if there might be an even better way to construct the Axios API so it doesn't lean into issues like these.Same principles apply to application code.
It was my understanding that the body isn't necessarily required but it is common for the
PUT
request to have one. Putting that aside, a different fix for your problem would be to nullify the body:Mostly because axios needs to have that parameter set. Alternatively you could use the request config instead of using the
.put()
method.I feel you. You might not believe it, but I ran into pretty much the same fail today as well (token somehow ended up in the data - prop, wtf was I thinking)
My lesson learned here (hopefully) was:
Thank you!