Dynamic Routes & Route Parameters
Okay then my friends, so we've seen how to make a basic server route and we've called that API endpoint from the front end in the about component. And we know that whatever we call the file in this API folder dictates what the endpoint URL is. In this case, it's /api/ninja because the file name is ninja. But just like front-end routes, we can do a few extra things.
First, we can make subfolders in the API folder and that folder name will be added to the route path. For example, I can make a folder called currency and then any file I create inside this folder will have this word currency in the endpoint URL.
Second, we can also have what is essentially route parameters or dynamic parts to the route. And we declare them in the same way we would a front-end route parameter as well. So say for example, I want to make an endpoint which has the path /currency and then / whatever the currency code I want to get information about is. So that could be USD for US dollars or GBP for Great British pound or INR for Indian rupee, etc. So that country currency code would be the second part of this server route and it would be changeable, but for each of those codes we'd still want to fire the same request handler function where we can access that code.
So just like in the pages folder on the front end, I can unwrap a file name in square brackets to denote that this particular part of the route is a route parameter and it can be essentially anything. And I'm going to call this inside the brackets code because it's ultimately the currency code that we want, but you can call it something different if you wish.
Implementing the Event Handler
Now inside this file, we still need to export a default value which is a function called defineEventHandler. And inside this function, we can then pass our custom event handler function. And in our case, since we're going to make a request from inside this function, we want to place the async keyword in front of it. And then just like before, as an argument to the function, we get the event object with information about the request events.
Now from that, we want to grab the route parameter, the currency code, right? And we can do that very easily by destructuring it from the event object. So we'd say event.context.params. And this params property contains any route parameters in the request path. Now we call our parameter code in the file name, so what we're destructuring has to be called the same as that: code. And now we have that parameter, and we can use it to make a request to the currency API to get information about that currency.
Securing API Keys with Environment Variables
So let's first of all construct the URI for that request. So I'll make a new constant called uri and I'm going to set that equal to a string using backticks so that we can output a variable inside it. So that base URL is this, which I'm just going to paste in. And this comes from the documentation for this currency API, by the way, in case you're wondering where it came from; I'm not just pulling it from any old hole.
And now after that, we need to add some query parameters to this URI, as per the documentation as well. The first one is going to be the currencies parameter to specify to the API what currencies we want information about. And we know which one we want, it's stored in the code variable now. So we can just say currencies is equal to, and then dollar sign curly braces to output a variable, and code, which is the parameter, the route parameter, right?
And then we need to tack on another query parameter, which is the API key. So we say the key is equal to some value. Now we use that private key in the last lesson inside the ninja route. So I'm going to go over there, and I'm going to copy it. But this time, instead of just pasting it into this variable, how about we add it as an environment variable? So that if we needed to push this up to a remote repository, it's not exposing that private key in the repository, because we wouldn't push up an environment variable.
Using Nuxt Runtime Config
So then how do we add environment variables in a Nuxt 3 application? Well, it's dead simple. First of all, we need to make a .env file in the root of the application. This is where we're going to define any environment variables to begin with. So I'm going to create one called, in all uppercase, CURRENCY_API_KEY and I'm going to paste in the API key as a value to that.
So that's the environment variable defined and now we want to use it. So in Nuxt, we expose our environment variables to the application via the nuxt.config file. So open that up, and the way we expose it is by adding a property called runtimeConfig, which is an object. And then any keys we add directly inside this object will be exposed to server-side routes like the one we're creating or the one we've already created. So we can add a property called currencyKey right here for example, and we could set the value of that to be process.env and then . whatever our environment variable was called. In our case, that's CURRENCY_API_KEY, right?
So Nuxt will now attach that environment variable to this runtimeConfig object, which is then basically exposed to our server route so that we can access it. And these keys here directly nested in the runtimeConfig object won't be exposed to the front end, so we can't use them there. However, if you do want to expose certain variables to the front end, you can do that by placing them inside a nested property called public and then placing the key in there. In our case, we don't want to do that, so just get rid of it.
So now we can use this key in our server route that we created. So the way we get access to our variables here from runtimeConfig is by saying up here, const, we want to destructure something, and we want to destructure currencyKey, which is what we called this particular property right here. So we want to extract that, and we set it equal to a function which Nuxt gives us called useRuntimeConfig like so. So this allows us to get any of these variables right here that we specify. So now over here, if we go back to the function, we can use this currencyKey variable over here. So dollar sign and then curly braces and paste in the currencyKey. All right, simple as that.
Fetching Data & Testing the Endpoint
So now we're making that request, and we should get data back. In fact, we're not making that request, we're just setting up the URI. Let's make the request. So const data is equal to $fetch and then paste in the uri like so. And that's all we need to do.
So now we are making that request. We want to get the data back. We need to await this, and we can do that because this is asynchronous. Then we can return the data. So return the data. And over in the About component over here, we could make a request to /api/ this right here, then /currency because we want to go inside the currency folder now, and then / some kind of code, some kind of currency code. So I'm just going to start with GBP, Great British Pound. So let me save this out.
Fingers crossed this all works. And you might need to restart your server for this to work, by the way. Let's do that. Control+C, yes, and then npm run dev, just because we've made changes to this Nuxt config as well. So now if we preview this in the browser, hopefully it should work. All right, so now if we go to the about page, we can see we get this back right here. This is the response. So GBP, the code, and also the value as compared to the US dollar. Awesome, so this is working.
So that my friends is how we create dynamic server routes. In the next lesson, I'm going to show you how we can deploy this to Netlify.