Vue API calls in a smart way
For a very long time, I wanted to expose different ways to make calls to our API. In this chapter, I will talk about the pattern that worked best for me, so allow me to introduce you to the RepositoryFactory.
I love this approach because it scales very well, and at least for me, it has worked almost always.
Let me explain why:
On the one hand, we will use the repository pattern to access our resources in a decoupled way, without any logic other than to return the data.
And on the other hand, we’ll use the factory pattern to instantiate, or the repositories that we need in each case, as well as the logic of the environment. With the advantage that the factory could decide whether to instantiate a mock repository or a production repository if necessary.
How many times have you seen examples with an instance of axios in each component?
Every time I see that I wonder the same thing: 🤔
- What happens if you need to reuse a call?
- What happens if the endpoint changes?
- What happens if I want to reuse the API calls to another project?
- What happens if you need to refactor some call or move it to a Vuex actions?
- I have more than one resource, now need to define 4 different endpoints?
- How I can handle mocks or different endpoints to test it?
It’s easier to change a single file rather than 30, right? 🤯
The right way:
There are also people who use the term service or directly API but, it seems to me that Repository is the one that best defines its function.
Then, we will need to declare a resource for each entity of your project.
For this example, let’s say that you have a blog. So you have the entity posts therefore you can define all your CRUD operations on its own repository file.
This is how the postsRepository looks like:
And now go with the simplest factory ever…
As you can see this is a simple object that return the requested resource.
At this point, you’ve noticed that you can handle more than one environment and import even mocked repositories adding more logic on your get() method.
For example, on my current company Snap.hr we need some different environments and depending on the environment, we change to mocks or corresponding endpoint. With this I mean that it as complex as you want.
But for this example let’s keep it simple 🙃
I’ll now show how to use it on your .vue sfc:
Since we have completely decoupled logic, you can even use another endpoint with a different paradigm as GraphQL.
As always, the silver bullet does not exist. This pattern has worked for me in almost all my projects, but it does not mean that it’s the one that best suits your own projects.
However, I think it has some advantages such as:
- This pattern allows you to perform testable code in a very simple way.
- Your components look cleaner.
- Easy extendable, isn’t it?
- Keeps your code DRY.
I’ve created a working example on Codesandbox to see this approach in action and I’d love to hear if you’re already using this kind of this technique! 👋
Do you any suggestion or question? Hit the comments section below or feel free to contact me via Twitter!
If you're looking for your next job as a software engineer, have companies apply to you by adding your profile to Snap.hr.