Sending POST, PUT, and PATCH Requests with Fetch API and VueJS

Part 2 of 4 in Using Fetch API with VueJS
Dan Pastori avatar
Dan Pastori November 15th, 2021

In the last tutorial, we covered the differences between the Fetch API and Axios when sending a GET request. Let’s take it up another notch and send POST, PUT, and PATCH requests with the Fetch API and compare how these methods operate compared to an Axios request.

If you want to jump ahead and see the answer, check out the Github repo for this component here. You can see the differences right away. If you want to see how this works, keep reading!

Step 1: Overview

For this tutorial, we are going to send data to an API endpoint. We are going to use our publicly available ROAST API. I’ll walk through how we send data to an endpoint, apply authorization (these methods require authorization 99.9% of the time) and the differences between the Fetch API and Axios. The endpoint we will be using will be for adding a Brew Method (https://api.roastandbrew.coffee/api/v1/brew-methods) and one for Updating a Brew Method (https://api.roastandbrew.coffee/v1/brew-methods/{methodID}).

Not to disappoint, but these are protected endpoints and will not create data unless a valid access token is provided. Most endpoints implemented through POST, PUT, and PATCH are protected. These endpoints serve as great examples though and will show in detail the differences between the Fetch API and Axios.

Step 2: Creating Your POST API Request

To show the differences between the Fetch API and Axios, I created the same request twice, one with each tool. The POST requests below are:

Fetch API POST Request

fetch( 'https://api.roastandbrew.coffee/api/v1/brew-methods', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer '+this.token,
        'Accept': 'application/json',
        'Content-Type': 'application/json;charset=utf-8'
    },
    body: JSON.stringify( this.form )
} )
.then( function( response ){
    if( response.status != 201 ){
        this.fetchError = response.status;
    }else{
        response.json().then( function( data ){
            this.fetchResponse = data;
        }.bind(this));
    }
}.bind(this));

And with Axios:

Axios POST Request

axios.post('https://api.roastandbrew.coffee/api/v1/brew-methods', this.form, {
    headers: {
        'Authorization': 'Bearer '+this.token,
    }
} )
.then( function( response ){
    this.axiosResponse = response.data;
}.bind(this))
.catch( function( error ){
    this.axiosError = error;
}.bind(this));

Just at first glance you can see that the Fetch API requires a little more configuration than Axios out of the box. Right away I start to think that if we are using the Fetch API in our application, we will have to abstract some of these settings to an object so the code is a little cleaner. Let’s dive into the method signatures.

Step 3: Differences Between Fetch API and Axios POST Request

Right away, the two methods look different. The Fetch API is much more complex. This is because Axios provides some standard defaults for what to send and what to expect from the server. As I mentioned above, I think that in order to keep using the Fetch API, we will have to make an easily configurable settings module ourselves. Otherwise, we will end up with what looks like spaghetti code everywhere and more possibilities for errors.

Before even diving into the method signature, I had to include

import axios from 'axios'

In order to use Axios. While on the topic of Axios, let’s start with the Axios POST method:

axios.post('https://api.roastandbrew.coffee/api/v1/brew-methods', this.form, {
    headers: {
        'Authorization': 'Bearer '+this.token,
    }
} )

I love how Axios provides an explicit .post() method that allows you to pass parameters directly to it. I find this to be super easy to read and explicit. Axios does have a signature similar to the Fetch API where you can pass the method as an option, but honestly, I never use it.

The POST method accepts the URL as the first parameter. This is the endpoint we will be hitting with data. The second parameter, this.form is the data we are sending to the endpoint. For now, this will just be JSON. When we get to files, it will be slightly different to send. The third parameter is any other options we wish to send with the request. In this case, we added an Authorization: Bearer {token} header. Like I mentioned before, these methods usually require some sort of authorization to run. If you want to see this component in full where this.form and this.token are defined, check out the GitHub repo.

That’s it for the Axios request! We can now send this request to our endpoint and it will include the data and proper authorization.

Moving on to the Fetch API, we start to really see differences with the methods:

fetch( 'https://api.roastandbrew.coffee/api/v1/brew-methods', {
    method: 'POST',
    headers: {
        'Authorization': 'Bearer '+this.token,
        'Accept': 'application/json',
        'Content-Type': 'application/json;charset=utf-8'
    },
    body: JSON.stringify( this.form )
} )

Like the Axios POST request, the first parameter is the URL of the endpoint we are sending data to. After that, everything changes. The second parameter in this request is an object that configures everything about the request. First, we define the method as a POST request in the settings using method: 'POST'. This is different from using Axios where the method is explicitly available with the .post() method.

Next, we define our headers. The first header we include is the Authorization: Bearer {this.token} header similar to Axios. Next, using our API, we have to define the Accept and Content-Type headers. Axios has these pre-defined, but the Fetch API does not. Your API may differ, but for standard JSON APIs, this is what is required. When we discuss uploading files, this will be different since we will be sending everything as form data.

Finally, we have our POST body which is defined as body: JSON.stringify( this.form ). Unlike Axios where you can pass JSON as the second parameter, you have to define the body explicitly.

Step 4: Handling a POST Request Response Using the Fetch API

Similar to how we handle a GET request response, we handle our responses depending on the status:

if( response.status != 201 ){
    this.fetchError = response.status;
}else{
    response.json().then( function( data ){
        this.fetchResponse = data;
    }.bind(this));
}

The only difference is POST requests should return a 201 response code instead of a 200.

Step 5: Sending PUT and PATCH requests Using the Fetch API

Both of these requests have the exact same signature as a POST request when using the Fetch API. The only difference is you have to change the method: setting in your request to either PUT or PATCH. With Axios, you’d call either axios.put() or axios.patch().

Upon response, the status code may be different as well such as an empty response which would be a 204 that you’d have to check for.

Conclusion

After running through the examples with both Fetch API and Axios, I’m definitely seeing the need to make some sort of standardized settings if I want to continue with the Fetch API. Axios makes this extremely easy using their configuration set up. I do like the idea of removing another unnecessary library if I don’t need it, but I love Axios and honestly it will be hard to switch. I’ll run through a few more examples with the Fetch API and see what other differences come up.

Keep Reading
View the course View the Course Using Fetch API with VueJS
Up Next → File Uploads using Fetch API and VueJS

Support future content

The Ultimate Guide to Building APIs and Single-Page Applications with Laravel + VueJS + Capacitor book cover.

Psst... any earnings that we make off of our book is being reinvested to bringing you more content. If you like what you read, consider getting our book or get sweet perks by becoming a sponsor.

Gold Sponsor SnapShooter Backups

Written By Dan

Dan Pastori avatar Dan Pastori

Builder, creator, and maker. Dan Pastori is a Laravel certified developer with over 10 years experience in full stack development. When you aren't finding Dan exploring new techniques in programming, catch him at the beach or hiking in the National Parks.