By Nic Benders
To provide data to our customers quickly, the New Relic engineering team has to build and deploy great software fast. As our business grows we need to constantly rethink and rebuild our architecture to make sure that we’re keeping up with the growth. At the same time, we also need to make sure we don’t slow down that cycle of building and deploying great software. In recent years, we have embraced the microservices approach, but along the way we learned some important lessons.
It turns out that the APIs between services may be the most important thing in the whole system. To ensure that you set your APIs right, you need to think like a designer and start with the customer in mind.Why microservices matter
To understand how we use microservices, it helps to think about why we got interested in them in the first place. Like many companies, New Relic started with a single monolithic app. As the company grew, the app grew. By 2010 this app had been broken up into a handful of coarse-grained services. The company continued to grow. Soon, the two main services had too much code and served too many masters. Engineering teams were stepping on each other’s toes when submitting features. Maintenance costs were high. Small problems could rapidly become big problems.
We wanted clear ownership boundaries, a system that was simpler to understand, explicit interfaces, reduced maintenance costs, and improved safety. While these things were achievable through several approaches, a move to microservices seemed to offer the most promise. So in early 2014 we launched a major effort to break apart the monolith.
Bumps in the road
Ultimately we were able to make it work, but there were some big (and unnecessary) bumps along the way. Our tooling didn’t really support our developers, who it turned out were eager to start building services. Where we expected dozens, we got hundreds. And the services those developers built didn’t really support other developers. Their APIs were awkward to use and integrating with them often required lots of hands-on collaboration.
These two failings shared a common theme: They were both failures of design, not of execution. Both the tooling and service developers fell into the trap of “inside-out” design. They built solutions based on what they wanted to give people, not what they wanted people to be able to accomplish with them. The services were shaped around the developers’ internal data models and the tools were built as thin wrappers around technologies.A 3-step design process
We were able to make things better by applying the same design process that we use for our customer-facing software to our internal software and tools. That design process can be summed up in three steps:
- What problem is the user trying to solve?
- How will they use “the product” to solve it?
- Test your assumptions with real users.
By following those three steps and practicing “outside-in” design, we started to again design our APIs before building our services.How to design better interfaces
Don’t panic, this isn’t some kind of big up-front design exercise. The idea is that those APIs are going to be the most expensive thing to fix later, so let’s start iterating on them first before getting too deep into what the service or tool will actually do. There are a couple of good tricks that I’ve found for doing this:
- Write the docs first. This puts you in the mind-set of a user instead of an author. It’s also much cheaper to argue about and change documentation than it is to discover your usability problems after the implementation is done.
- Try your APIs early by just writing client code that isn’t hooked up to anything, or by using a simple server to stub the API.
We also took a few techniques directly from our design team:
- Run UX experiments. Here is where internal tools and services have a huge advantage over externally facing products. Your users work at the same company, so go watch them. Ask them to think out loud while they are working and see how they attempt to interact with your API. Resist the urge to help them. Your users aren’t stupid, so if they can’t figure it out on their own, your job isn’t done.
- Remember that great artists steal from others. What are the current interfaces you enjoy using? Build your systems using the same principles. This has the added advantage of creating a system that will be immediately familiar to others.
- Give people who use your services or tools an easy way to provide feedback. No matter how open your organization is, if you don’t reach out and open an explicit channel for feedback, people will wait until they have a big problem before they bring up any issues.
You’ll still need to use your good judgment, but by taking the UX of your tool or service seriously and applying a few of these tricks, you can build better interfaces. And if you get a better interface, a lot of other things will get easier. Remember, just because you’re not pushing pixels doesn’t mean you’re not a designer.
About the Author
Nic Benders is Chief Architect & VP, Engineering at New Relic. View posts by Nic Benders.