00:05
Now, within APIs, it's typically a good idea to do some form of versioning, so that if you have a breaking change in one of your endpoints,
00:13
it doesn't immediately break for everybody who's interfacing with your API. Instead, you can change the version of the API endpoint for that breaking change,
00:23
so that the prior version still work the same as they did before, but the new version consists of that breaking change, so that your clients can migrate to the new version as they see fit,
00:33
and then you can cut off old versions at a set date and time in the future, following a more traditional production-based approach for your API there.
00:42
Let's take a second to set that up to get it working within our current structure. First and foremost, within our API route definitions,
00:50
on each route group prefix, we can easily specify a version for the group by doing slash API, slash, and then whatever that version is.
00:58
Typically, you would prefix a version with V to indicate that it is the version number that you're specifying followed by the version number itself, which in this case, is just going to start at one.
01:08
Now, our organization endpoint is slash API, slash V1, slash organization. Down the road, if we had a breaking change to this route,
01:18
we can move that to version two by doing slash API, slash V2, slash organization, where this one would contain the breaking change.
01:27
In order for our controllers to behave the same in version one, despite the breaking change in version two, we're going to need to separate that logic accordingly.
01:37
We're also going to want versioning on the API controllers as well. Within our API controller directory, let's add in a new folder with that same version number.
01:47
Then we'll move our organization's controller into that version number, confirm that move, and we can go ahead and have it update our imports accordingly. Now, within our API file here,
01:56
we can see that our controller is now at API version one, organization's controller. That's how we're going to ensure that the organization controller we're
02:04
targeting matches the version for the route group that the route is defined within. Furthermore, I'm sure you could imagine that as our routes grow and as our versions increment,
02:14
this file is going to grow quite a bit. We could specify one API file per version that we're targeting with the routes defined within the group.
02:23
Let's go ahead and do that. Let's scroll down to our start routes and let's change the structure of our API a little bit. Let's first create a new folder called API.
02:33
We'll keep all of our APIs versions in separate files within this API directory, and then we'll import and manage them within an index, which is currently our api.ts file.
02:42
We're going to have that update the imports there. Let's also rename it. Rename from api.ts to instead just index.ts.
02:50
We can update the import yet again for that. That import has been updated within our adonisrc.ts file within our preload section. If we scroll down to our preloads,
03:00
there it is right there being referenced. We want to make sure that this file is saved so that that gets updated accordingly, and we close that out. Now, we no longer want this route group defined within
03:09
our index.ts but rather a version1.ts. Since this file is not meant to be imported by anything other than the index,
03:17
I'm going to go ahead and prefix it with an underscore. I'm going to do underscore version1.ts for its full file name. Then from our index.ts,
03:25
just give everything there a copy and a cut and paste it within our new version1 file, just like so. Now, in order for this route group to get run, to define all of the routes defined within it,
03:34
which is currently just our organization route, we just need to import it from our index.ts, which is being imported and registered from
03:41
our adonisrc.ts preloads file when our application boots. So import./version1.js, just like so.
03:50
Now, our routes defined the exact same as it was before whenever it was directly within this file. At this point, we should have everything fully versioned. As we need to move on to version 2,
04:00
we'd create a new file within our API directory called underscore version2, add an import within our api_index.ts file to define the routes there,
04:09
mimicking the group that we currently have here, incrementing the version1 then to version2. We would mimic that same structure then within our controllers and
04:18
any actions that that controller would need to use as well for its resourceful actions.
04:23
So we'd later on have an API/version2 with an organization's controller inside of it, that the version2 route group would use for its organization route controller.
04:33
For now, everything's going to be nice and simple because we're just going to have that version1 to worry about. Before we wrap up, let's switch back over to Hopscotch just to make sure that everything works correctly here.
04:43
Again, since we've changed the route definition, if we were to try and send this out, looks like since I changed the preload, the server actually stopped as well.
04:51
So let's jump into our terminal once more. I'm sure enough, there it is. We can clear that out. Let's get our server back up and running. Sometimes whenever you're changing those preload files,
05:00
hot module reloading loses track of things. So now we have that back up and running. Again, if we were to try and send this, we're going to get back a 404 not found because we
05:08
no longer have a route at /api/organization. Furthermore, we're getting back an actual web response here because we don't have a route defined for it that's
05:17
matching our forced JSON content negotiation. Now, typically you would want your clients to specify that they accept application JSON within their requests so that
05:27
whenever that does send out, they get back a JSON response using content negotiation there. So our client should always be specifying that regardless.
05:36
That forced content negotiation on our registered routes is just a little helper on our behalf. Regardless, all we need to do to fix our route now
05:44
is add a version 1 to its path. So if we send this out now, now we're getting back our organization information and we can update our environment variable as
05:53
well to simplify how we're targeting this. So let's get rid of the version 1 within the URL and just go back to /organization and let's change our API environment variables. Let's jump into our variables here,
06:03
go into our development and switch API to version 1.
06:08
Then for version 1, we'll target HTTP localhost 3333/api/version1. Give that a save. Our API variable is going to go
06:17
back to red because it can no longer be found. Let's switch that to version 1. Now, if we send the test out again, we're still getting back our organization AOK.
06:25
Now, we need to update this within our collection so that it is updated accordingly. So let's just hit "Save" there to sync that. Now, if we close this request out,
06:34
open it back up from our organization collection, It's the exact same as it was before. And it works the exact same too.