loading...
Cover image for Remembering the difference between GET and POST 💡

Remembering the difference between GET and POST 💡

dmahely profile image Doaa Mahely ・4 min read

I was reminded recently of the difference between GET and POST requests, after joining a colleague of mine on a project that uses Express, while knowing exactly nothing about Express. I thought this write-up will serve as a good reminder of the differences between those two HTTP methods and how to use them.

Going in blind

Developer focusing

Being a learn-by-doing type, I got to work seeing the existing code and trying to follow along. My first task was to retrieve a user's profile details. This was obviously a GET method since we'll just be retrieving data and not creating anything new. I went to the users route file and added the following endpoint router.get('/profile', users.getProfile);

Then, I went to the users controller and created the following getProfile function, which was basically copied and pasted from an existing POST endpoint:

getProfile: async (req, res) => {
    let user_id = req.body.id;
    if(!user_id) 
        res.send("Invalid id");

    let profile;
    try {
        profile = await User.getProfile(user_id);
    } catch (error) {
        res.send(500, error);
    }

    res.send(profile);
}

In this function, we first get the user's id from the request's body, then pass it to the model which will check for it in the database and hopefully return some data to us. Next I tried to connect to this endpoint by providing a valid user id using Postman.

Sending a GET request to /profile using Postman, on Body tab
Notice how I'm sending data in the GET request's body, we'll come back to this later.

and I got the following response:

{
    "id": "11",
    "mobile": "050-5555555",
    "email": "example@example.com",
    "full_name": "Jane Doe",
    "bio": "Live Laugh Love!"
}

Great! 👏 Naturally, the next step is to show this data in the view layer.

<script>
    $(document).ready(function() { 
        let id = '11';
        $.ajax({
            url: '/users/profile',
            type: 'GET',
            data: {id: id},
            async: false,
            success: function (data) {
                console.log(data);
            }
        });
    });
</script>

Now when I refresh the page, this AJAX request should hit the endpoint we specified and log the data. Perhaps unsurprisingly, this logs Invalid id. Let's try to send the id another way.

<script>
    $(document).ready(function() { 
        let id = '11';
        $.ajax({
            url: '/users/profile?id=' + id,
            type: 'GET',
            async: false,
            success: function (data) {
                console.log(data);
            }
        });
    });
</script>

Hmmm, this also logs Invalid id. Weird. At this point, and because I was in a hurry, I just changed the route method from GET to POST, and changed it in the AJAX request as well, and I started seeing a result in the console.

router.post('/profile', users.getProfile); // changed to post
<script>
    $(document).ready(function() { 
        let id = '11';
        $.ajax({
            url: '/users/profile',
            type: 'POST', // changed to post
            data: {id: id},
            async: false,
            success: function (data) {
                console.log(data);
            }
        });
    });
</script>

Since this worked and I was short on time, I moved on to other endpoints which incidentally were all retrieving data but ended up being written as POST requests. A couple of weeks later, I had some time off and I was still thinking about this behavior, so I decided to revise HTTP methods and properly learn Express.

Learning

Lightbulb moment

What I had forgotten was the main difference between GET and POST methods. Per MDN, GET requests should not have a body. Instead, the data should be sent in the request URL, in contrast to POST requests which hide the data in the request body and are therefore more secure. This great example from freeCodeCamp illustrates the concept:

// GET request using query strings
route_path: '/library'
actual_request_URL: '/library?userId=546&bookId=6754' 
req.query: {userId: '546', bookId: '6754'}

// GET request using route parameters
route_path: '/user/:userId/book/:bookId'
actual_request_URL: '/user/546/book/6754' 
req.params: {userId: '546', bookId: '6754'}

// POST request
route_path: '/library'
actual_request_URL: '/library'
req.body: {userId: '546'}

However, Postman allowed us to embed data in a GET request's body which caused the confusion. Let's see the correct way to pass data with a GET request in Postman.

Sending a GET request to /profile using Postman, on Params tab

Note: make sure you're on the 'Params' tab instead of the 'Body' tab which I was on earlier. Force of habit!

Refactoring

Light the fire

Now, let's refactor our function to use a GET request as it was intended to. First, let's turn back our AJAX request to use the GET method.

<script>
$(document).ready(function() {
    let id = '11'; 
    $.ajax({
        url: '/users/profile',
        type: 'GET', // change this back to GET
        data: {id: id},
        async: false,
        success: function (data) {
            console.log(data);
        }
    });
});
</script>

And update our route to use GET as well:

router.get('/profile', users.getProfile);

Next, on to our controller

getProfile: async (req, res) => {
    let user_id = req.query.id; // use req.query, instead of req.body
    if(!user_id) 
        res.send("Invalid id");

    let profile;
    try {
        profile = await User.getProfile(user_id);
    } catch (error) {
        res.send(500, error);
    }

    res.send(profile);
}

And voila! We're successfully getting a response in our AJAX GET request 🎉

{
    "id": "11",
    "mobile": "050-5555555",
    "email": "example@example.com",
    "full_name": "Jane Doe",
    "bio": "Live Laugh Love!"
}

TL;DR

  • GET requests do not have request bodies while POST requests do.
  • Be careful when testing a GET endpoint using Postman. Make sure you pass the data in the 'Params' tab instead of the 'Body' tab that is used with POST requests.
  • Use req.query to view the data sent with the GET request, if you're not using route parameters or named segments. If you are using route parameters, use req.params to view your data.

Thanks for reading! Let me know how I can make this article better. Until next time 👋
Cover photo by Samson on Unsplash. Other photos from Undraw.

Resources

Discussion

pic
Editor guide
Collapse
vlasales profile image
Vlastimil Pospichal

POST is for send data, GET is for receive data.