Skip to content
loading...

Architecting HTTP clients in Vue.js applications for efficient network communication

Musthaq Ahamad on October 20, 2019

Modern web apps highly rely on network communication with API servers and external services. From real-time data to static assets, everything is do... [Read Full]
markdown guide
 

in the axios intance is baseURL not baseUrl


const httpClient = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL,
    headers: {
        "Content-Type": "application/json",
        // anything you want to add to the headers
    }
});

Thanks!

 
 

If you could update the post, that'd be great! I was banging my head for a bit until I figured out the typo :)

 

Hi,

Can you explain to me this mapping? My first thought was the getUsers is the function, but it is an array instead?

    computed: {
        ...mapGetters('Users', ['getUsers'])
    },
    methods: {
        ...mapActions('Users', ['fetchUsers'])
    },
    mounted: {
        // Make network request if the data is empty
        if ( this.getUsers.length === 0 ) {
            // set loading screen
            this.isLoading = true;

            this.fetchUsers().then(() => {
                this.isLoading = false;
            }).catch(err => {
                // show error screeen
            });
        }
    }
 

It's the getter defined in the store. Getters acts as computed properties so they're not called like a function.

 

I know how a simple getter works, you pass in an array and it maps the getters. In your example, there is also the 'Users' before the array element.

When we create modules in a Vuex store, that is; you split your store into smaller stores. It's a good idea to namespace them. Eg, if you have an application that has a store, you can create modules inside it for User data, Post data and so on. When you have modules, you need to pass the module name (or the namespace) to get the getter/action from that module to mapping functions. You can read more about this from my previous Article "Architecting Vuex store for large scale Vue.js application".

In simple words, if you want to access the methods in a store module namespaced as Users, you would use Users/getUsers to access the getter. Instead of that, you can simply pass the module name as the first argument for mapGetters/mapActions to access methods from that module as I have used in the example :)

mapGetters(['Users/getUsers'])

is same as

mapGetters('Users', ['getUsers'])

Now it's clear, I used the mapGetters(['Users/getUsers']) notation for modules, not the other one

Awesome! Hope this helped you and hope you learned something handy :)

 
 

Thank you for share it with us !
Great approach/practices about Vue component, making more clear code and scalable.

Vue and Nuxt are great frameworks I like a lot.

I hope that you continues to sharing more content like this. I'm excited to see your next post.

 

Hi, fellow! Thanks for such a valuable post! Saved it for future ;)

I've some questions though)

  1. Making network requests inside Vuex actions

Isn't it better to use async/await for clearer and more declarative code?
Some code above could be written like this:

const actions = {
    fetchUsers: async function ({ commit }) {
        const response = await getAllUsers();
        commit('SET_USERS', response.data);
    }
}

sure it needs try/catch around ;)

  1. Managing Auth Credentials using interceptors

Saving tokens or some other credentials/auth data to LS is bad, as spoken clearly here:
https://dev.to/rdegges/please-stop-using-local-storage-1i04
Do you still use this LS approach? Or you just used it as an easy example?

  1. Caching and Throttling

About this lines and idea:
"All the subsequent calls after the first call will be responded from the cache.

getUsers(); // actual network request and response gets cached
getUsers(); // from cache
getUsers(); // from cache...

"

What if in between these requests server's data has actually changed? Thus client will get wrong (cached) data. I believe caching is more server stuff to do, via response headers, telling browser what caching strategy to use, because server does better knowledge about information it stores, and about ways and frequency of data changes. So why not do caching on server-browser?

Thanks in advance!)

 

Great Observation! Thanks for the suggestions, I have updated the article with your feedback. And for the part where I used Local Storage, it's just for an easy example, adding to that using cookies instead of localStorage doesn't make much difference since both use the same security policy. Totally agree with implementing robust security in place without using localStorage but If your website is vulnerable to XSS, both the cases should be deemed to be flawed. Storing JWT in localStorage can be made more secure by issuing short term tokens. But yeah, choosing security and ease of implementation is always a matter of trade-offs between both. Thanks for your suggestions, hope it will help the readers alot! :)

 

Nice article!
Actually, this applies also to React.

 
 
 

Your error handling does not work in the event of a network error (server offline) as it does not have a response object (error.response)

 

Hey, thanks for letting me know :)
This is a fairly simple fix to just check if error.response is present before switch-casing the error.response.status.

Will update the post with these changes.
Thank you.

 
 
 
 
code of conduct - report abuse