Only use GET and POST

Kent C. Dodds
Kent C. Dodds

In this video, we explore the limitations of using HTTP methods other than GET and POST for form submissions. The browser can only handle GET and POST requests, which can lead to issues when using methods like DELETE. We discuss how this can affect the user experience, especially on slow network connections. We also provide a solution using progressive enhancement and distinguishing form submissions based on the data. If you're a web developer, this video will help you understand the importance of sticking to GET and POST for form submissions.


00:00 You should use only get and post for form submissions. Let's talk about it. Request.method equals delete here in our action. So we're handling delete submissions on this page for this delete button. The UI for that is right here.

00:14 We're saying form method equals delete. And so if I click on this delete, then we should get a delete post. So let's, or a delete request. So let's hit delete. And we're not getting anything deleted.

00:25 What's going on here? Let's look at, oh, right here, that method, that is a post. Why is that a post? That's weird. Let's look at the elements right here.

00:35 And if we take a look at our form, that method is post. Why is that? Like, I think Remix is doing something wrong with our form thing here. We're saying the method is delete, but Remix is making a post. Actually, what's happening is I have the scripts blocked on this page.

00:52 Now, our users don't typically block scripts. If they do, they should expect things to not work on the web. So let's turn that off, and let's just make sure that our framework is capable of handling a very simple HTTP method set right here. And if it doesn't, then it should be giving us a warning of some kind, right? So now that method is still post, I do have JavaScript on the page now.

01:16 If I hit delete, boom, skiing adventure is deleted. So that's exactly what should happen if I look over at my network, we'll be able to find that delete happening right there. So Remix is totally capable of deleting things. Like that's totally a thing that Remix can do. That's not a problem for Remix.

01:35 What is a problem is the fact that the browser cannot do anything other than a GET or a POST from a form. And so, While our framework is totally capable of doing other HTTP methods, and that's not a problem, the browser is not until our framework shows up on the page. This is a big problem for me because what if, let's say I'm a user, I wanted to delete this note, and so I'm going to go like kind of simulate this I'm going to pull this up over here we're going to say throttles to a slow 3G and I'm deciding hey I want to go to this note and I want to delete it right away so we're but we're on a mobile device luckily we server render and so we're going to get the UI as fast as possible. But I'm going to hit that Delete button, and nothing is going to happen. Not the right thing, at least.

02:25 We're getting that post request right there. It's a post request, because the browser is the one that's making that request. My framework hasn't showed up on the page yet, and so that's why this interaction isn't going to work at all. And what ends up happening is we get that POST request, which will result in re-rendering the HTML document for me with the note that I tried to delete in the first place. So I'm going to delete again.

02:50 And that's going to do another POST request. And every time I'm going to be a really angry user on a slow network connection hitting delete over and over again and it doesn't work. And that is not the fault of the framework, that's just a web platform limitation. And so, you should only use post and get for forms, period. Do not use any, like, put, patch, delete, whatever.

03:13 Those methods are awesome, you should totally use it for, like, talking between APIs and stuff, that's totally fine. But when it comes to forms, you should only ever use get and post. And so that's what we're going to do. I'm going to say post right here. And instead of this action that I have in place that listens to the request.method.

03:33 We've got this other action, our real action, that is going to handle the post request and it parses this form.body. Now, the reason that we're parsing the form.body is in case we ever decide to add some additional API endpoint or forms to this one page, we can differentiate them by the form body. And so that's why in our UI right here, we have our button, our submit button has a name and a value. This is how we distinguish between which form is being submitted. We also have a hidden input for the note ID, and you can have other hidden inputs to control different things for multiple form submissions.

04:14 We also have our CSRF protection token right there. But with that in place now, it doesn't matter whether the JavaScript is finished loading and your framework is ready to start making regular requests or if it hasn't showed up yet at all. The browser will still submit the form exactly the same as your framework will. So progressive enhancement is an important aspect of a positive user experience. And for that reason, we have to go to the lowest common denominator, which is just get and post.

04:42 And then we can differentiate between the different possible things that you can do based on the submission data. And so when I come over here and I say, hey, I want to delete this, we're going to get a post right there and our payload will include the intent which will allow us to switch off of what the user is trying to do. This is a platform limitation. It kind of stinks. I agree.

05:06 It would be nice to use other HTTP methods, but the fact is that you can't. Not if you care about progressive enhancement and the user's experience when they're first loading your page or whatever. Now, the profile page that we've got right here, if we go to our profile and edit profile, we've got a bunch of different things that you can do on here, including delete all of your data. And that's what's going on right here. We're using a method post and then we have a type or a name and a value right here.

05:37 And then we use that value, that intent value to switch off of which action the user's performing. I think that's a perfectly reasonable solution to this problem and that's what I recommend that you do. So I hope that is helpful to you. Use GET or POST. Don't use anything else when it comes to form submissions.

05:57 Peace!

More Tips