Organizing your Api Endpoints

A tip to make working with multiple environments easy.

In my day to day job working, I’m lucky enough to work with a really great set of people that do an awesome job making easy to consume APIs. For our app we have both Development and Production endpoints, and we switch between them as we are working on each new release.

So, I have a few goals in switching between api endpoints:

  1. Make it EASY. It shouldn’t be complicated or time consuming
  2. Eliminate as many ways of making typos as possible.
  3. Make it so that if there are multiple different API services (Image Recognition, Database, Payment Solution), that we are able to switch between all of them at the same time.
  4. Make the place where the switch occurs as readable as possible for others looking at the code.

So, as a developer, I like to be as DRY as possible, and my goal was to try to hit all four of these goals. I’ve made a way of doing it that I’ve found helpful, and maybe you will find it helpful as well. (Also, if you have an idea for a better way or a different way of doing it, please share!)

First, I start by making a new enum EnvironmentType . For many cases, it might be as simple as this:

If your team uses more endpoints than this, or you have other options, or you want to be able switch between different versions, obviously feel free to tweak it as needed. (This could be something like developmentV1, developmentV2, productionV1 for the different cases if you need it.)

After creating that, I create a class to manage the Environment. It’s pretty simple and straightforward.

I’ve made a couple of choices here. Let me walk through them.

  1. I’ve made the environment current implicitly unwrapped. This is to make sure that the configure function MUST be called before using the class. If it isn’t called, the app is going to crash on launch.
  2. I’ve created a function configure to set up the current environment variable.

Okay, so we’ve got a few pieces setup, now let’s talk a little bit about how to setup the class responsible for making your web calls. Here’s the setup I use for making sure that it uses the correct information:

So, now we’ve set up our api so that we can write just one variable baseUrlString and use that as part of all of our different urls in our api class. From here, we would just go ahead and configure all of the different web calls to use that same api string.

I’m sure that we all have our favorite ways of actually building and using the API itself (and that’s a bit beyond the scope of this article).

Okay, now the last piece that makes everything work.

  1. Let’s add a variable to hold the current environment in the app delegate to keep it available for the app (so that it stays in scope for the duration of the app).
  2. Call the Environment.configure function to set the current environment.

Okay, now that everything is done, our app and our api will use the correct paths for the development environment.

So, here are the things I like about this way of doing things.

  1. Setting this up for the first time isn’t hard.
  2. Both of the endpoints are already in the network api class(es), and so after you add them and make sure that there are no typos, you don’t have to ever change them (unless of course the actual endpoint urls change).
  3. Switching from .production to .environment is only 1 value, and that value is checked at compile time.
  4. If you have multiple different API endpoints as part of your app, this changes all of them in one call. (Let say you have an API providing your user data, something like intercom powering your customer service, and something managing your payments.) You change this in one place and it changes it for all of them.
  5. You use only one variable baseUrlString to create all of your urls in your API class, so you minimize typos and repetition.

So, I’ve found this useful for myself. What do you think?