I planned to call this blog post "Don't expose your back end", but I decided against it. It is still the topic this post will cover though, and it's pretty easy to do.
If you have a static site that does anything involving databases or servers, you probably use the JAMstack. That's Javascript, API's, and Markup.
With static sites, your front end is separate from your backend. So you use JavaScript and API calls to connect to backend services. And these services might be external, like Firebase or a server hosted somewhere like Digital Ocean or Heroku. Or they might be serverless functions, like AWS Lambda or Netlify Functions.
Why hide your back end?
Wherever your back end is, you will probably have an API call to connect to it. You'll hit that route and get data back.
First, let's look at a couple of reasons why you would want to hide your back end in the first place. After all, you don't want to write extra code just for the sake of it.
Security
The first reason it's a good idea to hide your back end is security. Hackers gonna hack.
Hiding your back end infrastructure isn't a golden bullet by any means. Some would probably argue it has minimal security benefits. But it at least makes it less obvious what service you are using on the back end.
For example, imagine you are using a particular service, and they have a security issue. Nightmare! But you might have a little more time to protect your site if it's not immediately obvious that you are using that service.
Access
I've known situations where users behind strict firewalls or other security apps have been unable to access a website's features because the API calls are to another domain that they don't know about.
Having your API requests and your static site run through the same domain, you can avoid running into this issue.
And proxying will also help you to avoid CORS issues if it's not supported by the other service.
Future Proof
You future proof your code against API changes a little bit by proxying (more on that in a bit) your requests. By having control over the API routes you use in your code, if the API changes, or if you want to move to another backend service, you only need to update one file.
Let's say you have a server hosted on Heroku and you call that for your API requests, for example:
https://your-server.herokuapp.com/api/user-data
But then you start to move to serverless functions on Netlify. Now your API requests are more like:
/.netlify/functions/user-data
You've got to go through your code and update them all. And not just for that request that might be in one place. For all your requests that have changed. And there could be loads.
Using Netlify redirects
Wouldn't it be good if your front end API calls could be /api/whatever-you-need
? And if you change your back end, you only need to update one file? Or even one line of code?
No one would know where your back end is just by looking at the API calls. It looks neater. And everything is served from your one domain, which is super professional.
And, should you need to change things on the back end in the future, your front end doesn't need to worry about it. It makes changes simple for you. And even better if you have separate front end and back end teams.
So how do you do it?
You can set up a custom domain on the external service, like api.yourdomain.com
but this might not always be possible. I like to use Nelify redirects to proxy the requests.
You can do this with Netlify redirects in a _redirects
file:
# proxy to api
/api/* https://your-server.herokuapp.com/api/:splat 200
And by using a splat, instead of redirecting each individual API route, if you want to change the location for all your API calls, you can just update the proxy.
# proxy to api
/api/* /.netlify/functions/:splat 200
Or, instead of using a _redirects
file, you can add redirect rules to your netlify.toml
file.
# resolve the "new" URL to a function
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/:splat"
status = 200
That's it, your front end and back end code are totally separate, even your API calls.