2
Designing an API for its users

This chapter covers

  • Which perspective to focus on when designing APIs
  • Approaching API design like designing a user interface
  • How to accurately determine an API’s real goals

If you were eager to jump right into the programming interface design battlefield, I’m deeply sorry, but you will have to wait for the next chapter. In this chapter, we look at the API’s users’ needs.

When you want to build or create something, you need a plan. You need to determine what you want to do before actually doing it. API design is no exception.

An API is not made to blindly expose data and capabilities. An API, like any everyday user interface, is made for its users in order to help them achieve their goals. For a social networking API, some of these goals could be to share a photo, to add a friend, or to list friends. These goals form the functional blueprint required to design an effective API, and that’s why identifying goals is a crucial step in the API design process. These goals—what users can achieve using your API—must make sense for the users, and none should be missed.

Determining a relevant and comprehensive list of goals demands a focus on the consumer’s perspective: the point of view of the API’s users and the software consuming the API. This perspective is the cornerstone of API design, and it is what must guide the API designer throughout the design process. Sticking to this perspective not only requires you to understand it, but you must also be aware of another perspective that can hinder API design—the provider’s perspective (the organization’s point of view and the software exposing the API).

2.1 The right perspective for designing everyday user interfaces

API designers have much to learn from the design of everyday user interfaces, whether they are interfaces of physical or virtual objects. From everyday physical interfaces (doors, kitchen appliances, or TV remote controls) to everyday virtual interfaces (websites or mobile applications), all share common design principles that must be applied to the design of APIs too. Choosing the right point of view, the right perspective, is one of the most crucial aspects of design for all of these interfaces and for APIs.

When designing APIs, separating these two perspectives and understanding them isn’t always easy at first. But transposed into the real world, all this becomes blatantly obvious, and how these two perspectives can affect API design becomes easier to grasp.

2.1.1 Focusing on how things work leads to complicated interfaces

Let me introduce, with fanfare, the Kitchen Radar 3000 (shown in figure 2.1). According to the advertisement, this kitchen appliance brings “state-of-the-art military-grade components into your kitchen so you will never ruin any recipe and will become the fastest cook in town.” Whoa, totally thrilling, isn’t it? Well, not really.

02-01.png

Figure 2.1 The Kitchen Radar 3000

What on earth is a Kitchen Radar 3000? Its name does not help us to decipher its purpose. Maybe its control panel can give us some clues … or maybe not.

As you can see in figure 2.1, there’s a single Magnetron On button. What is a magnetron? What happens when it’s turned on? This device is a total mystery.

But look, there’s a sticker on the glass door that invites us to read the user manual (figure 2.2). Maybe we will find some useful information there to help us understand this strange kitchen appliance’s purpose and how to use it.

02-02.png

Figure 2.2 The Kitchen Radar 3000’s (insane) user manual

OK, according to the user manual, the Kitchen Radar 3000 seems to be a new type of oven that uses radio microwaves, or simply microwaves, to heat food. It was invented by someone who was working on radars, hence the name. What a terrible idea: naming something based on its history and totally hiding its real purpose!

So how does it work? When users push and hold the Magnetron On button, it turns a component called the magnetron on. This component’s job is to generate radio microwaves. These microwaves generate heat when they pass through the food put inside the Kitchen Radar 3000’s cavity. Once the food is cooked, users can release the button to turn the magnetron off.

This control panel is not really convenient—users have to time themselves while pressing the button! And that’s when users want to use the full heating power of the oven. What happens if they want to use only a fraction of that power? They have to press and release the Magnetron On button at a certain pace, corresponding to the desired heating power. Doing so turns the magnetron on and off, generating fewer microwaves and, therefore, less heat than holding the button down continuously. This is totally insane! Who would use such a device willingly? Probably nobody.

Frankly, this device has not really been designed. It’s only exposing its inner workings (the magnetron) and history (the radar) to its users. The device’s purpose is hard to decipher. Not only do users have to be aware of how a magnetron operates, but the provided control panel is just a nightmare to use. This appears to be a case where the designer, focusing on how things work, created a device that’s not only hard to understand but also hard to use. Was this inevitable? Of course not! Let’s see how we can fix this design disaster.

2.1.2 Focusing on what users can do leads to simple interfaces

How could we improve the Kitchen Radar 3000 to make it easier to understand and easier to use? Well, if this device was designed by focusing on how it works, what about trying to redesign it by thinking the opposite way? Let’s focus on the users' needs and redesign the device’s control panel accordingly.

This kitchen appliance is basically an oven, sort of. And what do users want to do when they use an oven regardless of the technology it uses? They want to heat or cook food. We could simply rebrand the Kitchen Radar 3000 as a microwave oven and replace the Magnetron On button label with Heat or Cook, as shown in figure 2.3.

02-03.png

Figure 2.3 Rebranding the Kitchen Radar 3000 as a microwave oven

Well, that’s better. By simply changing some labels, we’ve made it easier for users to understand what this device is for: an oven is obviously made to heat things, and the button obviously starts the heating process.

But this microwave oven still provides a terrible user experience, especially when it comes to heating food at a fraction of the full heating power. Users still have to master the button push/release pace to heat something more slowly. Figure 2.4 shows how we could simplify that.

02-04.png

Figure 2.4 Simplifying use by redesigning the control panel

How do people usually heat food using an oven or other cooking device? They heat it for a given duration at a given power. We could replace the Heat push button with some controls that allow users to provide a duration in seconds and minutes and also specify a low, medium, or high heating power. Some circuitry behind the control panel will handle the magnetron and turn it on and off according to the user’s inputs.

This is perfect! This kitchen appliance is now easy to understand and easy to use thanks to this brand-new control panel. This new interface is no longer a cryptic direct access to the device’s inner workings. It does not give any hint about what’s really happening inside the box; it only focuses on the user’s needs. It is a user-friendly representation of what can be achieved with the oven. The details of the inner workings stay hidden inside the circuitry behind the control panel and won’t bother the user.

We’ve just redesigned a kitchen appliance’s control panel—so what? What does all this have to do with API design? Everything! We have created an interface that is an easy-to-understand and easy-to-use representation of what users can do with a device, without bothering them with irrelevant inner-working concerns. If you keep this mindset when designing APIs, you will be a great API designer! Why? Because an API is basically a control panel for software and must obey the same rules as any everyday interface.

2.2 Designing software’s interfaces

An API is the labels and buttons of software—its control panel. It can be understood at first sight or stay a total mystery, even after days of investigation. It can be a real pleasure to use or a total misery, just like some real-world objects.

Creating an API that is an easy-to-use and easy-to-understand interface requires us to design it while being focused on the good point of view, the right perspective: what users can do. Focus on how the software operates and it will end in a total disaster. Focus on what users can do with it and everything will go smoothly—just like when designing a real-world object.

2.2.1 Viewing an API as software’s control panel

When you use a microwave oven, or any other everyday object, you interact with it through its control panel, its interface. You read labels, push buttons, or turn knobs. It’s exactly the same when you want to interact programmatically with software: you use its API. As mentioned, an API is software’s control panel. But what does this mean, exactly? Let’s turn our redesigned Kitchen Radar 3000, our microwave oven, into software (as shown in figure 2.5) to answer this question.

02-05.png

Figure 2.5 Comparing a microwave oven to software

The whole microwave oven becomes the software, the control panel becomes the software’s API, and the circuitry behind the control panel becomes the implementation.

The API is what users see; it is a representation of what they can do. The implementation is the code running behind the API. It’s how things are really done, but it stays invisible to the user.

An API provides a representation of goals that can be achieved by using it. The microwave oven’s API allows its users to heat food. To be achieved, a goal may need some information (inputs). Users have to provide a power setting and a duration to heat their food. The goal’s implementation uses the information provided through the API to operate. In this case, the implementation turns the magnetron on and off at a given pace according to the provided power for the provided duration. And when the goal is achieved, it can return some information.

So, an API is a control panel made to interact programmatically with software to achieve goals. But just like with everyday interfaces, those goals might be expressed from the provider’s perspective (turn magnetron on) rather than the consumer’s (heat food). Is this as big a problem for APIs as it is for everyday interfaces?

2.2.2 Focusing on the consumer’s perspective to create simple APIs

To understand the consequences of designing an API from the provider’s perspective (unduly exposing inner workings), let’s compare the pseudocode needed to use the Kitchen Radar 3000 API and the Microwave Oven API.

The Kitchen Radar 3000 API proposes two goals: turn magnetron on and turn magnetron off. The following listing shows how to use these controls to heat food.

Listing 2.1 Using the Kitchen Radar 3000 API

if <power> is high  
  turn magnetron on
  wait for <duration>
  turn magnetron off
else
  if <power> is medium  
    cycle = 7s
  else if <power> is low
    cycle = 11s
  else if <power> is thaw
    cycle = 13s
  end if
  for <duration>  
    turn magnetron on
    wait for <cycle>
    turn magnetron off
  end for
end if

①   No on/off cycle if power is high

②   Calculate on/off cycle waiting time based on power

③   Alternating on/off cycle

If developers want to create a program to heat food using this API, they will have to turn the magnetron on, wait for a given time (duration), then turn the magnetron off. But that’s the simple use case when they want to use the full heating power. If they want to heat something at a fraction of full power, they will have to turn the magnetron on and off at a pace that will achieve the desired heating magnitude.

Just like its real-world equivalent, the Kitchen Radar 3000 API is a nightmare to use. Developers need to write complex code in their software in order to use it. They can even make mistakes. There’s a bug in the pseudocode, by the way. Did you spot it? The next listing shows how to fix it.

Listing 2.2 Fixing the bug

  // alternating on/off cycle
  for <duration>
    turn magnetron on
    wait for <cycle>
    turn magnetron off
    wait for <cycle>  
  end for

①   This line was missing.

The alternating on/off cycle for loop misses a wait for <cycle>, which is definitely not the best code, but it works. Let’s now see how to do the same thing using the Microwave Oven API, which provides a single heat food goal. Heating food with this is simple, as shown in the following listing.

Listing 2.3 Using the Microwave Oven API

heat food at <power> for <duration>

Developers only need to write a single line of pseudocode; it can’t be simpler than that. As a developer who wants to provide software to heat food, which API would you prefer to use: the one that needs complicated, error-prone code, or the one that needs a single error-proof line of code? This is, of course, a rhetorical question.

Just like a control panel, the complexity or simplicity of an API depends above all on the perspective you focus on when designing it. Did you know anything about magnetrons and the microwave oven’s invention before reading this book? Probably not. Why? Because a microwave oven’s control panel is designed from its users' perspective. It does not expose irrelevant inner workings. It does not require the user to be a magnetron or radar expert to use it. It can be used by anyone who wants to heat food. And did this lack of knowledge interfere with your use of a microwave oven? Absolutely not. Why? Because when you use it, you just want to heat food. You don’t care about exactly how it will be done.

This is how any API must be designed. An API must be designed from its consumer’s perspective and not its provider’s. Figure 2.6 contrasts these two perspectives.

02-06.png

Figure 2.6 The consumer’s versus provider’s perspective

An API designed from the provider’s perspective is only a window showing inner workings and, therefore, presenting goals that make sense only for the provider. As you saw with the Kitchen Radar 3000 API, such an API will unavoidably be complicated to use, and consumers will not be able to do what they want to do simply. In contrast, an API designed from the consumer’s perspective is a display screen hiding inner workings. It only shows goals that make sense for any consumer and lets them achieve what they want to do simply. Focusing on this perspective will put an API on the right path to ensure its usability.

OK, when designing an API, we need to think about the consumer first. And, by doing so, it seems important to clearly identify the goals that consumers can achieve when using an API in order to ensure the creation of an easy-to-understand and easy-to-use API. But how do we do that accurately and exhaustively?

2.3 Identifying an API’s goals

Based on our microwave oven experiment, I hope you are now convinced that the very first step in the API design process is to determine what its users can achieve by using it—to identify the API’s real goals. For our Microwave Oven API, it was simply heat food; but, for a social networking API, it could be goals like share a photo, add a friend, or list friends. But such simple descriptions are not precise enough. How does a user add a friend, exactly? What is needed to do that? What does the user get in return? It is fundamental in designing an API to have a deep, accurate, and precise knowledge of

  • Who can use the API
  • What they can do
  • How they do it
  • What they need to do it
  • What they get in return

These pieces of information are the foundations of your API, and you need those to be able to design an accurate programming interface. The method and the API goals canvas described in this chapter are simple but powerful tools that will help you acquire all the information you need.

The goal of designing software (or anything else) that fulfills users' needs is not something new. It has been a goal as long as software has existed. Numerous methods have been and are still being invented in order to collect users' needs, to get a deep and accurate understanding of them, and finally to create some software that fulfills their goals more or less efficiently and accurately. These methods can all be used to identify an API’s goals. Feel free to use the one you are familiar with or adapt the method presented in this book as you see fit, as long as you know who your users are, what they can do, and how they can do it. The following sections describe these principles.

2.3.1 Identifying the whats and the hows

When we redesigned the Kitchen Radar 3000 into a microwave oven, we answered two questions, as shown in figure 2.7. The first question was, “What do people want to do when they use an oven?” The answer was, “They want to heat food.” This answer led to a second question: “How do people heat food?” The answer was, “They heat food at a given power for a given duration.” This simple questioning helped us identify the information we needed to design a simple and user-friendly heat food goal for the Microwave Oven API—the whats and the hows. This example shows two of the fundamental questions to ask when determining an API goals list:

02-07.png

Figure 2.7 How we redesigned the Kitchen Radar 3000’s control panel

  • What can users do?
  • How do they do it?

With these questions, we roughly describe what can be done with the API (the whats) and decompose them into steps (the hows), with each step becoming a goal of the API.

But, in this example, the whats and the hows are basically the same thing, so do we really need to do this decomposition? Definitely. Unfortunately, the microwave oven example is too simplistic to illustrate that. We need a more complex use case, so let’s work on an API for an online shopping website or mobile application. What would be the whats and the hows of a Shopping API? Figure 2.8 shows these.

02-08.png

Figure 2.8 The Shopping API whats and hows

What do people do when they shop online? Well, they buy products. And how do they buy these products? They add them to their shopping cart and then check out.

So, buying products is a two-step process that can be represented by these goals: add product to cart and check out cart. Without doing the decomposition, we could have wrongly listed a single buy product goal. That’s why we must decompose the whats into hows: if we don’t do that, we might miss some goals.

Great, we’re done! To identify an API’s goals, we just need to roughly list what users can do and decompose these actions into steps by examining how they do them. Each step corresponds to a goal. So, let’s take the next step and design the programming interface corresponding to these goals. But wait … I think we missed something.

When we redesigned the microwave oven, we did more than just identify a heat food goal. We implicitly identified the power and duration as the user’s inputs. That helped us to redesign the Kitchen Radar 3000’s control panel, so it could be interesting to identify goal inputs and outputs.

2.3.2 Identifying inputs and outputs

A goal might need some inputs to be achieved. For our Microwave Oven API, the heat food inputs were the power and duration. These inputs helped us to design the microwave’s control panel and API. A goal can even return some outputs when achieved. These outputs also impact the API design. So, let’s identify these goals for our Shopping API, as shown in figure 2.9.

02-09.png

Figure 2.9 The whats, the hows, and their inputs and outputs

What do people do when they shop online? Well, they buy some products. And how do they buy these products? They add them to their shopping cart and then check out. Nothing new for these two first questions. Let’s now dig into each step to determine its inputs and outputs.

We’ll start with the add products to the cart goal. What do people need to add a product to a cart? They obviously need a product and a cart. Good, and do they get something in return when they add a product to their cart? No. Well, these new questions do not seem to give us any really useful information; the answers are quite obvious. Maybe we will get something more interesting for the check out step

Do people need something to check out a cart? Clearly, a cart. Still an obvious answer. And do they get something in return? Yes, an order confirmation. (This one was not so obvious.)

Could we have guessed that the API would manipulate some orders by just looking at the check out cart goal? Maybe with such a simple API, but maybe not with a more complex one.

To design an accurate software control panel comprising all the needed buttons and labels, we need to have an accurate vision not only of the goals, but also of what we need to achieve them and what we get in return. Identifying an API’s goals isn’t only about what can be done with it, but also what data can be manipulated through it. This is why we need to add two more questions to our list:

  • What can users do?
  • How do they do it?
  • New question to identify inputs: What do they need to do it?
  • New question to identify outputs: What do they get in return?

Great, now we really are done! Let’s go to the next step and design the programming interface corresponding to these goals. But wait … we missed something again! How does a user get a product to add to the shopping cart? It seems that this obvious question can be of interest when detecting some missing goals after all.

2.3.3 Identifying missing goals

How does a user get a product to add to the shopping cart? This is a mystery. It seems we missed one goal, and maybe more. How could we avoid that? There is no silver bullet, but by examining the sources of the inputs and usage of the outputs, we might be able to detect some missing whats or hows and, therefore, some missing or unidentified goals.

So how do users get a product to add to the shopping cart? They probably search for it by its name or description before adding it to the cart. So, we can add a new search for products step in the buy products what. We must not forget to apply our questioning to this new step, as shown in figure 2.10.

02-10.png

Figure 2.10 Adding a missing how

What do users need to search for a product? Well, it’s a free text query; it can be a name or a description, for example. What does this search return? A list of products matching the query. How do users get the search query? They provide the search query themselves. How is the list of products used? Users pick one of them to add to the cart.

We’ve now dug into all the inputs and outputs until the answers led us to the API’s users or an already identified goal. This way, we’re sure there are no more missing steps on this path. Great. One problem solved. Let’s investigate the next step, check out cart, as shown in figure 2.11.

02-11.png

Figure 2.11 Adding a missing what

It needs a cart and returns an order. We will not investigate where the cart comes from (you can do that as an exercise), but what is done with the order? Why do we return it to the user? Maybe so the user can check the order’s status? Interesting, but I sense there’s more. Users will probably need to manage their orders. I think we have just spotted a missing what! So, let’s add a new manage orders answer to our “What can users do?” question and start our investigation.

How do users manage their orders? They should be able to list their orders in chronological order to check their status. So we have two steps to investigate. The resulting Shopping API goals list is shown in figure 2.12.

02-12.png

Figure 2.12 Shopping API goals list with the new user’s manage their orders what

First, list orders: What input is needed to list orders? Nothing. What is returned? A list of orders. Where do the inputs come from? We don’t need any input to list orders, so we don’t need to think about where the inputs come from. What is done with the outputs? Users can pick one of the orders in the list to check its status. Now we’re done with the first step of managing orders.

The second step, check order status: What input is needed to check an order’s status? An order. What is returned? An order status. Where does the order come from? From the check out cart or the list orders step. What is done with the order’s status? We want to provide this data to inform users, nothing more.

Fantastic. A new what, two more hows, and goals identified. So let’s enhance our questioning with two more questions to identify inputs sources and outputs uses:

  • What can users do?
  • How do they do it?
  • What do they need to do it?
  • What do they get in return?
  • New question to identify missing goals: Where do the inputs come from?
  • New question to identify missing goals: How are the outputs used?

Investigating input sources and output uses definitely helps to spot missing API goals. But we are still not ready to design the programming interface. The goals list is still incomplete because I intentionally made yet another mistake. Do you know what it is? If you apply our questioning to our latest goals list, you should be able to find it. To tell the truth, there are many missing goals; we have only scratched the surface of the Shopping API’s goals. But the one I have in mind concerns the products returned by the search for products goal. The next section addresses that answer.

2.3.4 Identifying all users

We’ve said that users can search for products and add them to their carts, but where do those products come from? They come from the products catalog, of course! But these products don’t magically appear by themselves in this catalog. Someone must have put them there. As a customer, you don’t add products to the catalog yourself; some admin user does that. You see?

By simply applying our usual line of questioning, we’ve again spotted a hole in our Shopping API goals list. This is great! But instead of waiting to discover these users by investigating inputs and outputs, we could be more efficient by adding a new dimension in our questioning, as shown in figure 2.13.

02-13.png

Figure 2.13 Investigating the whos, whats, hows, inputs, and outputs to identify goals

Identifying the different types of users is mandatory when building an exhaustive API goals list. So we must add another inquiry to our line of questioning in order to explicitly identify them all:

  • New question to identify all users and avoid missing whats: Who are the users?
  • What can they do?
  • How do they do it?
  • What do they need to do it?
  • What do they get in return?
  • Where do the inputs come from?
  • How are the outputs used?

If we first identify the different types of users of our API, we can build a comprehensive goals list more easily. Note that the term user is used in a broad sense here; it can be an end user using the application consuming the API, the consumer application itself, or end user’s or consumer application’s roles or profiles. And remember, we can still rely on examining inputs and outputs to make sure we spot all users.

That makes a lot of questions to handle. Let’s see how we can make this questioning easier with an API goals canvas.

2.3.5 Using the API goals canvas

Now that we know which questions to ask and why we must ask them in order to identify an API’s comprehensive and precise list of goals, let’s see how we can handle this investigative process with an API goals canvas, as shown in figure 2.14.

02-14.png

Figure 2.14 The API goals canvas

The API goals canvas is nothing more than a table composed of six columns, matching the process we have discovered through the previous sections:

  • Whos —Where you list the API’s users (or profiles)
  • Whats —Where you list what these users can do
  • Hows —Where you decompose each of the what’s into steps
  • Inputs (source) —Where you list what is needed for each step and where it comes from (to spot missing whos, whats, or hows)
  • Output (usage) —Where you list what is returned by each step and how it is used (to spot missing whos, whats, or hows)
  • Goals —Where you explicitly and concisely reformulate each how + inputs + outputs

02-15.png

Figure 2.15 The Shopping API goals canvas (partial view)

Figure 2.15 shows a partial view of the API goals canvas for our Shopping API. The API goals canvas and its underlying questioning method help you envision who uses the API, what they can do with it, how they do it, what they need, and what they get in return. These are the fundamental pieces of information you need to design the programming interface representing the identified goals.

You might have noticed that we did not talk about fine-grained data and errors. We will talk about those later in chapter 3 (section 3.3) for fine-grained data and in chapter 5 (section 5.2) for errors. The API goals canvas is only a high-level view; you should not dive too much into details at this stage.

Be warned that even without diving too much into such details, filling an API’s goals can be quite difficult in some complex contexts. There can be many users/profiles or too many whats use cases to deal with. This isn’t specific to API design; this happens when designing any software solution. Do not try to cover all use cases in one shot. Instead, focus on a small set of use cases. If a what contains many steps or many branches, focus on the main path and, after that, check if there are variations leading to new goals in other paths. The same goes for users: trying to explore all whats for all users or profiles can be difficult. Focus on the main user or profile, and after that check if there are variations for others.

Listing an API’s goals is an iterative process. You have to proceed step by step—not trying to do everything at once. And you will also have to refine and modify this list based on some considerations or constraints like usability, performance, or security. You will discover those throughout the rest of this book.

Unfortunately, this method does not guarantee that your API goals list will be defined from the consumer’s perspective. Yes, the first question (“Who are the users?”) doesn’t prevent the provider’s perspective from surfacing in your API’s goals. To be sure you don’t fall into one of its traps while building your API goals list, we need to investigate the various facets of the treacherous provider’s perspective.

2.4 Avoiding the provider’s perspective when designing APIs

Whether you’re designing your API from scratch or basing it upon existing systems, the provider’s perspective will inevitably show up in every stage of its design. Being aware of its various facets is fundamental for any API designer who hopes to stay on the consumer’s perspective path and design easy-to-understand and easy-to-use APIs.

Do you remember our Kitchen Radar 3000 API? Its name laden with history, and its user-unfriendly Turn magnetron on/off goals. Exposing the inner workings was a blatant example of API design heavily influenced by the provider’s perspective. Unfortunately, this perspective is not always so obvious, but there’s an adage popular among people working in software design that brings into the light the dark corners of the provider’s perspective. It is known as Conway’s law, and it is often quoted to explain how a system’s design can be influenced by its inner workings. It states that

“Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.”

Mel Conway"How Do Committees Invent?"Datamation, April 1968

This adage can be applied to a wide range of systems, from human organizations to software systems and, of course, APIs. It means that an API’s design can be influenced by the communication structure of the organization providing it, as shown in figure 2.16.

02-16.png

Figure 2.16 The different facets of the provider’s perspective

Data, code and business logic, software architecture, and human organization shape the communication structure of a company and, therefore, can influence the design of its APIs.

2.4.1 Avoiding data influences

An API is fundamentally a way to exchange data between two pieces of software—a consumer and a provider. Therefore, it is unfortunately common to see API designs that mirror the underlying data organization. How data is structured or named can influence the design of the API, as shown in figure 2.17.

02-17.png

Figure 2.17 Exposing the data organization through the API

Let’s say our Shopping API implementation handles customer information in two tables called CUSA and CUSB (don’t ask me why!). An API design influenced by such a data structure could bluntly expose two goals: read CUSA and read CUSB. Such an API is hard to understand. What do CUSA and CUSB mean exactly? (I’ll also let you imagine the tables' cryptic column names that might be directly exposed to the consumer.) It is also hard to use! Consumers have to use two goals to retrieve all customer data.

Frankly, exposing your database model is more often than not a terrible idea and can lead to an unappealing user experience. Hopefully, figure 2.18 shows how we could fix such a problem.

02-18.png

Figure 2.18 Fixing data organization exposure

Renaming the read CUSA and read CUSB goals as read customer information A and read customer information B is one idea, but that doesn’t really improve the user experience. Such goals, even if their meaning is easier to understand, are still exposing the provider’s perspective. It would be better to replace these two fine-grained, data-oriented goals with a single, higher-level get customer’s information goal that is more consumer-oriented and both easy to understand and use.

Mapping data organization and names to API goals and data can make the API hard to understand and use. Using the API goals canvas and focusing on what users can do should allow you to easily avoid such design problems, but they still can happen. So, while you are identifying the API’s goals, you should always check that you are not bothering the consumers by unnecessarily exposing your data model through whats, hows, inputs, or outputs.

Exposing the data model is the most obvious sign of the provider’s perspective, but this is not the only way it can manifest. How we manipulate the data can also be exposed through an API, and this too is a terrible idea.

2.4.2 Avoiding code and business logic influences

The code that manipulates data—the implementation’s business logic—can influence API design. Exposing such logic through the API can bother not only the consumer but also the provider. Figure 2.19 shows such an example.

02-19.png

Figure 2.19 Exposing business logic through the API

Let’s say that for our Shopping API’s implementation, each customer has a single active address. But addresses in the system are never deleted; instead, their status is set to inactive when the customer moves. An API design influenced by this business logic could provide these provider-oriented goals:

  • List customer’s addresses (active and inactive)
  • Add an address for customer
  • Update an address status (to active or inactive)

The words used to describe these goals are understandable, but the overall purpose of the goals might not be obvious to a consumer who doesn’t know exactly how the system handles addresses. These goals expose how the data is processed internally; figure 2.20 shows how they have to be used.

02-20.png

Figure 2.20 Fixing business logic exposure

The left side of figure 2.20 shows how to change a customer’s address using this API. Consumers have to list the existing addresses to spot the active one, update it to set its status to inactive, and then add a new active address. Quite simple, no? Not at all! It is awfully complex and such a process could easily go wrong. What if consumers do not set the previous address to inactive? This could be terrible for data integrity—the provider is at risk here.

Thankfully, there is a simple solution shown on the right side of figure 2.20. This whole complex and dangerous mess could be replaced by a simple update customer’s address goal. The implementation could do the rest, just like when we let the underlying circuitry handle the magnetron on/off cycle for our Kitchen Radar 3000 API.

Exposing internal business logic can make the API hard for the consumer to use and understand, and can be dangerous for the provider. Again, using the API goals canvas and focusing on what users can do should let you easily avoid such design problems, but they still can happen.

We were only dealing with a single software component here. How might things go if we want to build APIs based upon a more complex system involving multiple applications interacting with each other? The provider’s perspective is a problem here too.

2.4.3 Avoiding software architecture influences

Partly thanks to APIs, it’s very common to build systems based on different pieces of software that communicate with each other (remember section 1.1.2 in chapter 1). Such a software architecture can influence API design in the same ways as internal business logic. Figure 2.21 shows such an example.

02-21.png

Figure 2.21 Exposing software architecture through the API

Let’s say that, for our shopping system, we’ve decided to handle product descriptions and product pricing in two different backend applications. There are many good (and bad) reasons to do that, but that’s not the issue here. Whatever the reasons, it means that product information is hosted in two different systems: Catalog Description and Catalog Pricing. A Shopping API designed from the provider’s perspective can bluntly expose those two systems with a search for products goal that only retrieves product descriptions and a get product’s price goal that returns a product’s price. What does this mean for the consumers? Nothing good. Let’s look at that in figure 2.22.

02-22.png

Figure 2.22 Fixing software architecture exposure

The left side shows that in order to search for products and show relevant information to a customer (like description and price), a consumer might first have to use the search for products goal to get the descriptions, and then retrieve each found product’s price using the get product’s price goal to gather all the relevant information. That’s not really consumer-friendly.

Consumers don’t care about your software architecture choices. What they care about is seeing all the information they need about products when they search for them. It would be better to provide a single search for products goal and let the implementation gather the necessary information from the underlying Catalog Description and Catalog Pricing systems, as shown on the right side of the figure.

Mapping the API design to the underlying software architecture can make the API hard for consumers to understand and use. Once again, using the API goals canvas and focusing on what users can do should allow you to easily avoid such design problems, but they still can happen. So while you are identifying the API’s goals, you should always check that your whats and hows are not the result of your underlying software architecture.

We’re almost done with our exploration of the different facets of the provider’s perspective. After data, code and business logic, and software architecture, there’s only one left. It’s the most treacherous one: human organization.

2.4.4 Avoiding human organization influences

As long as there is more than one person in an organization providing APIs, you will be confronted with the human organization aspect of the provider’s perspective. This is the fundamental source of Conway’s law, mentioned earlier. People are grouped in departments or teams. All these different groups interact and communicate in various ways, using various processes that will inevitably shape all the different systems inside the organization, including APIs.

Let’s say our organization that provides the Shopping API is split into three different departments: the Order department that handles customer orders, the Warehouse department that handles the product warehouse and packaging, and the Shipment department that handles the shipment of packages to customers. Figure 2.23 shows the resulting Shopping API designed from provider’s and consumer’s perspectives.

02-23.png

Figure 2.23 Avoiding human organization exposure

If designed from the provider’s perspective, our API can expose goals matching this human organization. The problem with these API goals is that they will expose the organization’s inner workings in a way that is totally irrelevant to people outside the organization.

If consumers want to order goods for customers, they will have to use the add product to cart, check out cart, prepare order, and ship order goals. We are again exposing things that are not the consumer’s business. What reason is there for a consumer to use the goals prepare order and ship order? Absolutely none. From a consumer’s point of view, everything should stop at the check out cart goal. When a consumer uses the check out cart goal, the implementation should deal with the Warehouse department to trigger the order’s preparation, and the Warehouse department should deal with the Shipment department to trigger the order’s shipping. The rest of the process should be handled internally.

Mapping API design to the underlying human organization can make the API hard to understand, hard to use, and even totally irrelevant. Using the API goals canvas and focusing on what users can do should, as before, let you easily avoid such design problems—but they still can happen. So, while you are identifying the API’s goals, you should always check if your whats and hows are really the consumer’s business.

In the end, all the different aspects of the provider’s perspective relate to exposing aspects that are not the consumer’s business through the API. Let’s see how we can include this matter in our API goals canvas.

2.4.5 Detecting the provider’s perspective in the API goals canvas

You have learned that to identify an API’s goals, you need to dig into the whos, whats, hows, inputs and their sources, and, finally, outputs and their usage. With this method, you should be able to avoid the most obvious intrusions of the provider’s perspective without thinking too much about it. But you also saw that the provider’s perspective can be treacherous and not so obvious. Fortunately, our investigations into the provider’s perspective showed us its different facets and how it can be spotted by simply considering if what we have identified is really the consumer’s business. Figure 2.24 shows a final update to our API goals canvas in order to be fully ready to build a comprehensive and consumer-oriented API goals list.

02-24.png

Figure 2.24 The updated API goals canvas

As you can see, all we need to do is add the final question: “Is all this really the consumer’s business?” With this question, as you have seen, we will check if any element comes from the provider’s perspective (data, code and business logic, software architecture, or human organization). An API goals list established with this canvas will be a strong foundation for the design of the programming interface. In the next chapter, you’ll discover how to design such a programming interface based on an API goals list.

Summary

  • To be easy for consumers to understand and use, an API must be designed from the consumer’s perspective.
  • Designing an API from the provider’s perspective by bluntly exposing inner workings (data, code and business logic, software architecture, and human organization) inevitably leads to hard-to-understand and hard-to-use APIs.
  • A comprehensive and consumer-oriented API goals list is the strongest foundation for an API.
  • Identifying users, what they can do, how they do it, what they need to do it, and what they get in return is the key to building a comprehensive API goals list.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset