Request Model: How to Architect Your Apps for Networking 

 January 5, 2016

by Jon Reid


Objects are like horses. The less they know about their chaotic surroundings, the easier it is to control them. We don't want our objects to be spooked when there's a lot going on. So let's give our horses blinders, by building ignorance and isolation into our systems.

But how? We typically write mobile apps with these things at the center:

Code snippet sample

Improve your test writing “Flow.”

Sign up to get my test-oriented code snippets.

  • Communication with web services
  • User interface
  • Object persistence

These frameworks bore into our apps like warts with deep roots. Web-centric, UI-centric, and persistence-centric knowledge spreads through our apps, making our code tightly coupled. And then we wonder why it's hard to write unit tests!

Is there an alternative?

Our code is tightly coupled. And then we wonder why it's hard to write unit tests!

Click to Tweet

Clean Architecture and Hexagonal Architecture offer a different way. Instead of being at the core, things like web communication and even the UI can become plug-ins. They live at the edges of the app. Use cases and business logic become the center of the app.

[This post is part of the series TDD Sample App: The Complete Collection …So Far]

First, a Naive Client

Let's explore just one facet: communication with web services. And let's only look at sending the requests; we won't worry about handling responses for now. A naive approach for the Marvel Browser sample app looks like this:

The Marvel Comics API is out in the cloud. The Marvel Service class handles all communication with it.

The app calls Marvel Service, so there’s an arrow there. But why did I draw another arrow, from Marvel Service back to the rest of the app? Because in my experience, it’s typical for web service classes to know about the app’s model classes.

For example, we might represent Marvel comic characters with a Character class. If the Marvel Service knows about Characters, that’s a dependency. Thus, the arrow going from Marvel Service back to the rest of the app.

Can we get rid of that arrow?

Request Model: a Big Step Forward

Let’s not pass Characters, or any model object at the core of our app, to the Service. Let’s not have the Service poke around in the Character to extract any data it needs to make a request. Instead, the caller can give the Service what it needs, and no more. We can do this with a Request Model:

Web request: Request Model

A Request Model encapsulates everything needed for a particular request. The caller creates it and passes it to the Service. By making it a Value Object, the Request Model contains no references to the app’s model objects.

The Service is now ignorant. It knows what it’s told, and that’s all.

DIP Towards Clean Architecture

That’s a big step, but we’re not done. The “rest of the app” still has a dependency on the Marvel Service. This makes it hard to change anything about the way we fetch the data. In particular, it complicates unit testing. If only there were a way to reverse that arrow’s direction, but keep the Service ignorant about most of the app.

Well, there’s this thing called the Dependency Inversion Principle—the D of SOLID.

The classic way to invert a dependency is to extract a protocol. (If you’re an Android developer, when you see “protocol,” think “interface.”) We’ll call it the Marvel Gateway. In the following diagram, it’s marked with <P> to show that it’s a protocol:

Web request: Clean Architecture

The Marvel Service will (eventually) implement the Marvel Gateway protocol. The protocol acts as a contract. Thanks to Dependency Inversion, the rest of the app can now be ignorant. It knows about the contract, but not about any class that satisfies that contract.

We just derived our way to the heart of Clean Architecture! Anything that implements the protocol can be plugged in. The Marvel Gateway serves as a Boundary. Everything to the left of the dotted lines can be sliced off and replaced without affecting the core of our app. This makes it easy to replace the Marvel Service with whatever we want to use for unit tests.

Totally Worth It

Separating things in this way may look like more work. But ignorance is bliss! Loose coupling brings huge benefits at a low cost.

Next time, I’ll show you how AppCode can help us quickly create an Objective-C Value Object to serve as our Request Model.

Have you felt the pain of objects that know too much? How has tight coupling slowed you down? Leave a comment below.

[This post is part of the series TDD Sample App: The Complete Collection …So Far]

Jon Reid

About the author

Programming was fun when I was a kid. But working in Silicon Valley, I saw poor code lead to fear, with real human costs. Looking for ways to make my life better, I learned about Extreme Programming, including unit testing, test-driven development (TDD), and refactoring. Programming became fun again! I've now been doing TDD in Apple environments for 20 years. I'm committed to software crafting as a discipline, hoping we can all reach greater effectiveness and joy. Now a coach with Industrial Logic!

  • Hi Jon, thank you for the post! I’ve been using VIPER (https://www.objc.io/issues/13-architecture/viper/) for a while now which splits the Massive View Controller into 5 components that communicate with each other through interfaces applying the same Dependency Inversion Principle. It really makes unit test easing although in my opinion it increases complexity and can be cumbersome for very simple use cases. What architectural approach do you usually use?

  • {"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}