Switching from Staging URL to Production URL

November 29, 2011 — 6 Comments

How to switch from staging URL to production URL?

How do you switch your app between a staging URL (for development and testing) and a production URL (for real world use)? I’ve changed my mind about my approach, because one size doesn’t fit all.

In 9 Code Smells of Preprocessor Use, I originally suggested that instead of using the preprocessor, it would be better to use a plist. Here’s the preprocessor code smell:

#if STAGING
static NSString *const fooServiceURL = @"https://dev.foo.com/services/fooservice";
#else
static NSString *const fooServiceURL = @"https://foo.com/services/fooservice";
#endif

I wrote, “Instead of defining these URLs in your code, treat them as resource definitions and place them in a plist, organized by type.”

<dict>
    <key>Staging</key>
    <dict>
        <key>fooServiceURL</key>
        <string>https://dev.foo.com/services/fooservice</string>
    </dict>
    <key>Production</key>
    <dict>
        <key>fooServiceURL</key>
        <string>https://foo.com/services/fooservice</string>
    </dict>
</dict>

I still think this is a good approach for a complicated app that talks to many services. Putting all the URLs in a plist makes them easy to find and manage.

But for a simple app, I’ve found this to be overkill. Instead, I create a class for the URLs, and access them through methods:

- (NSString *)fooURLString
{
    DebugSettings *debugSettings = [self debugSettings];
    if ([debugSettings usingStaging])
        return @"https://dev.foo.com/services/fooservice";
    else
        return @"https://foo.com/services/fooservice";
}

The plist approach also makes it harder to switch between staging and production on the fly, because all the URLs have to be reloaded. With the “define it in code” approach, all I have to do to switch URLs is change a property in DebugSettings.

What about you? How do you switch your app between a staging URL and a production URL?

Photo by Niels Linneberg (license)

Jon Reid

Posts Twitter Facebook Google+

I'm passionate about not just improving our code, but improving the way we code.

6 responses to Switching from Staging URL to Production URL

  1. I would request you don’t return NSString objects from a method named -fooURL. Instead, return an NSURL object, or name it -fooURLString

  2. Hello Jon,
    just stumbled across your Blog. Very nice work and thanks alot for sharing!
    Determining configuration data during compile time is always a pain. It’s like turning software to hardware. Though I have to admit, that I start a new project this way when things are very simple :)
    Regards
    Nick

    • Hi Nick,

      I’m glad you found your way here. :)

      Engineering is often the art of balancing trade-offs. I started one project with compile-time #if’s, and that was fine as long as I was the only one who was using the staging services. But when it became important for other people to be able to switch from production to staging, I converted to a runtime switch.

      One of the best parts about having a good suite of unit tests is the ability to change your mind and rewrite something!

  3. This is an interesting read, but I have a question about security. In the scenario where the URLs are placed in a plist, wouldn’t this leave an unnecessary security risk by potentially exposing the location of the staging server, or any other item that would not be necessary in the final released version? Wouldn’t conditional build statements prevent unwanted data from being included in the final build?

    For example:

    #ifdef DEBUG
    URL = @"http://devserver.com";
    #elif STAGING
    URL = @"https://staging.com";
    #else
    URL = @"https://realserver.com";
    #endif
    • Mike, that’s a good point. In my work, all staging servers are hidden behind the corporate firewall — but not everyone has that.

      Also, I’ve found it helpful to allow switching between environments on the fly. Our testers don’t like the idea of qualifying one binary but releasing a different binary.

      But as far as hiding unwanted data, I wonder if there’s any way to have different build configurations load different plists. Otherwise, yeah, that’s a valid use of conditional build statements.

Leave a Reply

*

Text formatting is available via select HTML.

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> 

Have you Subscribed yet? Don't miss a post!