Integrating backend in Vue applications with a proxy

Integrating backend in vue applications with a proxy

In this post, we will see how to integrate a backend in a Vue application and set the backend under a proxy url.

By the end of this post, you should understand

  • How to integrate backend in a vue application?
  • How to setup proxy url in the vue configuration?
  • Understand and solve the 404 error in the proxy configuration

The backend

I’m a .NET developer so I’m creating a .net core backend application and I’ve added necessary configuration to run the app.

Your backend could be of any technology. All you’ve to do is make it run and copy the url.

Here’s the endpoint code to return a list of items.

[HttpGet("getalltodos")]
public IActionResult GetAllTodoItems()
{
    var todoItems = new List<string> { "Write a Blog post", "Do work out for an hour", "Get the stuff out of refridgerator" };
    return new OkObjectResult(todoItems);
}

And this is the response of the endpoint, an array of todo items.

.net core api response

The front end

Here is my Todo.vue component that makes a call to our API to get a list of items and renders in an unordered list.

<template>
  <ul>
      <li v-for="item in todoItems" :key="item">
          {{ item }}
      </li>
  </ul>
</template>
<script>
import todoService from 'services/todoService.js'
export default {
    name: 'Todo',
    data () {
        return {
            todoItems: []
        };
    },
    async created () {
        const todoData = await todoService.getAllTodoItemsAsync();
        this.todoItems = todoData.data;
    }
}
</script>

Here is my todoService.js file

import axios from 'axios'
export default {
    getAllTodoItemsAsync () {
        return axios({
            method: 'get',
            url: '/services/todoService/getalltodos'
        });
    }
}

So, we got todo items from the backend API and we will store them in an array and display them in template section of the vue file.

Take a look at the url in the todoService.js file (/services/todoService/getalltodos). The path until getalltodos (/services/todoService) is the proxy url which we will configure soon.

Integrating .net core backend endpoint in vue project

To integrate backend and front end, we’ve to create a vue.config.js file in our Vue project.

The vue.config.js file is an optional file which we may not see when we create vue project. If you don’t see it, create one. Make sure you create it on the root directory of the vue project. (it should not be in the src folder)

Here is my vue.config.js file

module.exports = {
    devServer: {
        proxy: {
            '/services/todoService': {
                target: 'http://localhost:5000', // paste the copied API url here
                ws: true
            }
        }
    }
};

We gave our backend API url in the target. So, the scheme://host:port in the url will be substitued with our http://localhost:5000.

Our backend is running on http://localhost:5000 and if we do npm run serve on our front end, then our front end should run at http://localhost:8080.

With the above proxy configuration if we try to load the page, we will get 404 (Not found) error and we cannot see our list of todo items on the page. Here’s the network request of our bad request.

404 bad request on vue js proxy request

We don’t see any http://localhost:5000 in the network request because we are behind the proxy that we configured.

Why the proxy request in our vue.config throws 404 (not found)?

When we request for http://localhost:8080/services/todoService/getalltodos behind the scenes the request will be converted into http://localhost:5000/services/todoService/getalltodos and sent to our backend API. But, our backend does not have that endpoint for services/todoService/getalltodos so we got 404 error.

If we can check the asp.net core hosting diagnostics, we can see the request comes in and ends up in 404 error.

.net core hosting diagnostics for the api request

If we can replace the proxy url (services/todoService) in the proxy object, then we can hit our http://localhost:5000/getalltodos endpoint. To do this, we have to add pathRewrite to the proxy object. After adding the pathRewrite, our vue.config.js will looks like this.

module.exports = {
    devServer: {
        proxy: {
            '/services/todoService': {
                target: 'http://localhost:5000',
                ws: true,
                pathRewrite: {
                    '^/services/todoService': '/'
                }
            }
        }
    }
};

So, if our request is http://localhost:8080/services/todoService/getalltodos behind the scenes it will be transformed (with our pathRewrite configuration) and sent as http://localhost:5000/getalltodos.

And we can see our list of items in our application.

working vue application

Source Code on GitHub

Here is the source code of front end and backend.

After downloading the source code, run the backend first to make sure the API is available and then run the front end.

If your backend port is other than http://localhost:5000 then copy the url and replace http://localhost:5000 in the target in the vue.config file with your backend url.

For front end, you’ve to run npm install before running npm run serve.

References