Jason Harmon, head of APIs at engaging forms tool Typeform, and namesake of the JSON schema, gave a fantastic proactive talk at a recent APIdays conference about “the things that break stuff in production.” Three things in fact.
API lifesaver #1: How to use HTTP POST instead of GET
Using HTTP POST may not be the common route because GET tends to be more popular than POST for retrieving data. GET often results in confusingly long URLs, but they’re no different than the majority of queries, so GET has become the defacto method for building filtered queries using HTTP. (It’s also good to note that long URLs tend to be more discoverable by Google, so they are good for search engine optimization.)
But Web apps that work through the browser can encounter a problem by using GET. According to Harmon, because browsers (particularly Chrome) are good at caching, if the browser sees a seemingly repeated GET—like hitting back—you might get two landing pages for one submission. At Typeform, Harmon and his team realized the pages were getting dumped, marked by the browser as duplicates.
“Even if you get by a browser, you have caching proxies on your provider, especially with hotels and ISPs, and they will redirect cached GETs even if you tell them not to,” Harmon said. “You often don’t know what they will and will not cache.”
To overcome that problem, Harmon recommends changing your GETs to POSTs because in the HTTP spec, POSTs don’t cache.
If you are getting cached API calls and you don’t know why, Harmon recommends you start looking for the GET:
- Add POST where possible (keep in mind that changing from GET to POST could result in a breaking change to your API’s contract)
- Add the following code to any GETs (as one way of maintaining the contract’s status quo if breaking changes will be too difficult on your developer community)
?cache_buster= [random]
These measures should help you get control over that caching.
API lifesaver #2: How to compress APIs that poll a lot
When an API consumer like a Web application calls an API over and over again, it is said to be “polling” the API. This typically happens when the API consumer expects some data to change on a regular basis and is looking to get the latest version of that data. For example, in the case of Typeform, customers with integrated forms might regularly poll the API so that they can get the results of their forms. API consumers might use Zapier for a lot of point-and-click integrations and, if customers are calling on average once every five minutes, the net result could be a huge number of calls.
Harmon offers these questions to identify this problem:
- Do you have a large dataset?
- Are the queries expensive?
- Is your data frequently changing?
- Do you have a lot of clients?
“A quick solution for us was to set up webhooks, which are a kind of a reverse API. Instead of them asking, we send them a POST when there is something new,” said Harmon.
He described the difference in traffic as dramatic.
“As a client of webhooks I’m going to want to call the API once overnight,” Harmon said, in order to ensure no webhook deliveries were missed. He went on to say that webhooks don’t really stand alone, but they work well with APIs because they reduce the number of calls needed.
Beyond webhooks, he offered these other options:
- caching (but he said caching is hard)
- a read-only database replica
API Lifesaver #3: How to use group calls to take advantage of common chains of calls
Harmon offered the microservices structured version of Typeform’s forms as an example of how to architect an API when not everything has to be updated in one shot. In Typeform’s case, updating everything at once required seven separate API calls, which would bottleneck performance. One solution now under consideration is to drop REST for a GraphQL-driven approach. In the meantime, Harmon said they developed the following workaround.
As you can see in the photo above, the team broke the form up into a microservice-like structure that bound certain commonly chained back-end activities together in order to more efficiently service the the front-end and weed out unnecessary API chatter. Forming a backend-for-frontend (BFF), a layer of server-side JavaScript (Node.js) deals with the orchestration when responding to calls. This is a way to turn a rigid resource structure to your advantage.
The point in this situation, like in many others, is to think about how your client is going to perform calls and how your tool will be used. Typeform’s team recognized the pattern you see above where they could cluster calls into a single chain, like Form > Design > Background > Image. Harmon said to focus on what he calls N+1 calls, like when the client can call a parent, which in turn calls for the related or child items. If you can identify behavior patterns like that, chances are you will reduce the number of API calls taking place, which will, in turn, improve performance.
Harmon also said this microservices-BFF structure makes adding in live scenarios easier. However, he warned that you need to get the user experience designers involved early because “if you are in native mobile, it is hard because once it’s out there you are stuck with it because no one is going to update it anyway.”
Build APIs for the user first
“When you are building APIs, think about how people use it. We call it API design, but we tend to think like engineers,” Harmon said. “Have some empathy for the people that are going to use it. And when you really do this you can figure out quickly the problems ahead of time.”
This is the crux of developer experience, which doesn’t just mean that you have better customer retention, but you have the better ability catch and fix things ahead, building a product your API consumers will actually want to use.
Harmon went on to say that this process is not just about listening to your customers, but it’s about making sure the core of your API is strong, secure, and flexible when fulfilling these needs.
Harmon emphasized that API design isn’t just about the spec at the start of the project. It can also be used to put out fires, including “cheap fixes” like the ones he shared above. All of these fixes are based first and foremost on logic.
“Think about what’s going to end up in the logs after these calls happen a bajillion times. How are you going to read the story that it writes in your logs?” Harmon asked.
Like all good customer service and user experience creation, developer experience comes down to two things—listening to what your API consumers are and aren’t saying and then using logic to address their biggest issues.
This article first appeared on ProgrammableWeb.