We are all confronted with APIs in our everyday actions. But what do APIs mean for each and every one of us? Are they a vehicle for integration projects, as part of an ETL (Extract, Transform, Load) journey? Or are we talking about APIs in terms of digital products for potential internal and external consumers? These different perceptions and perspectives need to be understood and taken into account if you want to develop successful APIs.
In the context of API Experience, I basically focus on digital products. But what do we mean by a digital product? Unlike analog products, digital products only have to be created once and can then be duplicated at will with minimal effort. Depending on the use case, they can also be scaled. These can be digitized goods such as images or books. But services and data can also be provided. What all products have in common is that they represent value for the customer and are at the core of a company’s value creation. However, the concept of a product is very technical – particularly in the case of APIs.
API as a product
When I talk about an API product, I mean a package of multiple endpoints or APIs. With monetization in mind, there is also a revenue model behind each API product. I described other characteristics of an API product in a previous blog post and we will touch on these throughout the article. For an API to be successful, it needs consumers who want to use the data product behind the endpoint in a variety of ways. Thus, the first thing to do is to understand the market and the corresponding customers.
Customer / Consumer
In connection with APIs, the term “developer experience” appears very often. Unfortunately, this only describes the possible users of an API in a very biased way. After all, the classic developers, especially with the product idea in the background, do not have to be the actual users of an API. Thus, it is important to focus on the actual customers, whoever they are or will be, during the entire API lifecycle. Because as an API provider, we rely on their direct feedback in terms of good API design.
But when do we talk about good API design? In order to clarify this question, we must now leave our dusty IT cosmos for a while and approach the concept of design from a different perspective.
Ten principles for good design
In the 1970s, it was Dieter Rams , a German industrial designer, who subsumed his ideas on good design into rules and finally formulated them into theses. To be more precise: ten of them. Rams very clearly notes that good design is in a state of constant development.
#1 Good Design is innovative.
#2 Good Design makes a product useful.
#3 Good Design is aesthetic.
#4 Good Design makes a product understandable.
#5 Good Design is unobtrusive.
#6 Good Design is honest.
#7 Good Design is long-lasting.
#8 Good Design is thorough down to the last detail.
#9 Good Design is environmentally friendly.
#10 Good Design is as little design as possible.
These principles already form a foundation for an understanding of good design and can be applied to the design of an API with relatively little effort.
Ten Heuristics from Nielsen and Molich
Moving forward in time looking for principles of well-designed interfaces, one comes across two gentlemen in 1995: Jakob Nielsen and Rolf Molich. The two created ten usability heuristics for user interface design and highlighted aspects that designers should focus on when aiming to improve the usability of their products.
#1 Visibility of system status
The design should keep users informed of the current state of progress by providing appropriate feedback within a reasonable period of time.
#2 Match between system and real world
The design should speak the language of the user. Use words, phrases, and concepts that are familiar to the user, not internal jargon. Follow real-world conventions so that information appears in a natural and logical order.
#3 User control and freedom
Users often perform actions by mistake. They need a clearly marked “emergency exit” to leave the unwanted action without having to go through a lengthy process.
#4 Consistency and standards
Users shouldn’t have to wonder if different words, situations, or actions mean the same thing. Follow industry and audience conventions.
#5 Error prevention
Good error messages are important, but the better designs carefully prevent problems from occurring in the first place. Either error-prone conditions are eliminated or they are searched for and the user is offered a confirmation option before performing the action.
#6 Recognition rather than recall
Minimize user overload by making elements, actions, and options visible. The user should not have to remember information from one part of the interface to another. Information that is required to use the design (e.g., field labels or menu items) should be visible or easily retrievable when needed.
#7 Flexibility and efficiency of use
Shortcuts – hidden from inexperienced users – can speed up interaction for experienced users, so the design can accommodate both inexperienced and experienced users. Allow users to customize common actions.
#8 Aesthetic and minimalist design
Interfaces should not contain information that is irrelevant or rarely needed. Each additional information unit in an interface competes with the relevant information units and reduces their relative visibility.
#9 Help users recognize, diagnose, and recover from errors
Error messages should be formulated in simple language (no error codes), state the problem precisely and propose a constructive solution.
#10 Help and documentation
It is best if the system does not require additional explanations. However, it may be necessary to provide documentation to help users understand how to perform their tasks.
The principles presented above help us to extend the principles created by Rams with additional elements and statements.
Mitra: seven heuristics for API design
But how do we now bridge the gap to develop appropriate principles that fit API design 100 percent? Fortunately, this has already been done by Ronnie Mitra in 2017. To do this, he took Nielsen and Molich’s ten heuristics and reduced the original list to seven heuristics that API designers absolutely must learn and understand.
#1 Visibility of system status
* Is it difficult to know when something has gone wrong in the system?
#2 Match between system and real world
* Do the message formats, libraries, and message patterns fit the user’s world?
#3 Consistency and standards
* Is the API consistent in its signature (e.g. URI format, query controls)?
#4 Error prevention
* Are the documented examples incorrect or misleading?
#5 Flexibility and efficiency of use
* How suitable is the interface for the first-time user?
#6 Support of users in the detection, diagnosis and correction of errors
* Is the error information correct?
#7 help and documentation
* Does the documentation meet the needs of the different learning levels (beginner, advanced user and expert)?
With Mitra’s seven principles, we now have a foundation for designing APIs with a good experience.
For the API experience already mentioned, a process is required. With regard to a process, we very easily stumble over the buzzword “API management”, which aims to adequately describe this process.
API Management describes phases that an API will go through during its lifecycle related to the API Provider and the API Consumer. However, this process approach does not quite fit the reality of an API’s lifecycle, as it does not take into account the complexity of certain phases. To be more precise, this refers to the Design/Strategy, Create, Test/Publish and Secure phases. These are also the main phases associated with “Manage” that are targeted by API management vendors. To confuse interested parties even further, they then like to talk about “Full Lifecycle”. But how can we make these four or five phases more tangible?
First and foremost, the “API-first” approach must be established. This approach is based on three principles:
1. the API is the first user interface of the application. The API must be developed with a clear focus on the end user. Developers must give the same attention to the design and maintenance of an API as they do to UX and the graphical user interface.
2. The API comes first – before the implementation. The application can gain functionality through further development, optimization or restructuring. Your API should remain consistent. The API should be treated separately from the implementation. This allows the API to become a contract that drives the implementation, rather than just hovering over the implementation.
3. the API is explained (and even self-explanatory). To be as fast and efficient as possible, the API must be easily understood by others who were not involved in its creation. Usable API documentation is the foundation for translating content so that it can be consumed. This means structured documentation that follows standard patterns for elements such as URLs, request methods, headers, parameter queries, and responsible formats.
These principles echo the points already made in Ronnie Mitra’s seven heuristics. Thus, we can further strengthen the existing foundation with API-first principles. As we could already see with the connection to Nielsen and Molich’s ten heuristics, understanding user experience is also compelling when designing APIs. In short, we want to solve a problem based on three questions:
– What problem is the API intended to solve?
– What is the goal of providing the API?
– Who is the actual customer, or more precisely consumer, of the API?
API Design Sprint
The task now is to solve the questions raised as quickly and purposefully as possible. In projects with customers, the framework of a design sprint has proven itself – as a so-called API design sprint. The design sprint itself originated as an idea at Google Ventures. Before the team wrote the book Sprint about the procedure, they had conducted design sprints with over 100 startups. In terms of procedure, we are guided by the design thinking process, in which we first start without any concrete background knowledge and are not finished until the API is concretely implemented as an idea. Within the iterative process, the consumers with their respective needs are in the foreground.
Overview of the different phases of the design thinking process:
#1 Understand – define the problem
#2 Observe – understand customer needs
#3 Point of view – what have we learned?
#4 Developing ideas – outlining and prioritizing solutions.
#5 Prototyping – modeling the best ideas
On the basis of the design thinking process, we can now present the above-mentioned phases of the API management process (Design/Strategy, Create, Test/Publish, Secure and also Manage) much more clearly for the provider of an API. It should be made clear once again that this sprint or process cannot be completed in a short period of time (one week) at the beginning. This is because, especially at the beginning, some hurdles have to be removed in order to understand these hurdles at the same time as a basis for guidelines regarding compliance and governance. The result of this process transformation looks as shown in fig. 2 and at the same time offers room for adaptation and optimization.
Personas and Use Cases
We start this first phase of the process with two simple questions:
Who will use the API?
What will the API be used for?
We also start directly with the stakeholders in the context of APIs. Here we meet the following, depending on the provider and consumer side:
- API Provider:
- API owner
- Author of the API description
- Backend Developer
- API Consumer:
- Application Owner
- End User
- API Provider:
In project situations with so-called Citizen Developers, these can be found on the consumer side, both in the roles of Developer and End User.
Citizen developers are users of low/no-code solutions who are part of the business and do not necessarily have deep programming knowledge.
In order to understand more precisely who we will be dealing with on the consumer side in the respective project context, the introduction of personas is useful.
What are personas?
Personas are used to describe the ideal typical users of a system and to depict them as fictitious characters or persons with the help of profiles. This gives abstract data a personal, human face, and we gain a common understanding of real users in terms of their goals, capabilities, and contexts. Personas also help prevent self-centered design. It is important to be careful to avoid portraying stereotypes. As part of determining the personas, the security context regarding authentication/authorization must also be clarified – whether a persona is a functional user or requires a technical user on the system side. Depending on the type of user, a corresponding approval process may be required. With the personas, we have clarified the first of the above questions, so we can turn to the second.
What are the Use Cases?
The intended use abstractly describes the goal to be achieved with an API. It is necessary to find the main actor and understand his actions in order to draw conclusions for an API to be described. Here it is important to know if and how other systems are involved. Likewise, it is important to check whether there are pre- or post-conditions for the use case. Also, at the end, to complete the use case, there is the question of whether there are other actors that could lead to a different use case. Once the use case is outlined, we can start thinking about the API style we want to use. Which now also means that these are initial thoughts on the architecture of the solution to the use case. The following five style variants are currently available to us:
– Message- and Event-driven
For the further steps in this post we decide to use REST. We have seen that the two questions about personas and use cases may not be easily answered. Now, if the personas and the use case are really known, it makes sense to look in detail at the data model as the API will deliver it. At this point, we can also rephrase API first to API by use case first to again emphasize the importance of the use case.
The data model
The data model is first of all about understanding the internal model for the use case. Then to look at whether a delineation to an external model is needed, and at the same time whether and how transformations are needed. For transformation, we may also need to look at using and building middleware to implement transformation or aggregation. This again has implications for the API backend and its architecture. The data model needs to be in the representation form of an entity relationship model to provide clarity regarding the structure and possible flows. At the same time, the presence of a global Data Catalog would be beneficial, as this would allow others to participate in the data model. Since we want to make the data model available via a REST API, we need to clarify whether it is a resource or collection as a response. A resource represents a single data representation, whereas a collection represents a list of resources. Likewise, clarifying the basic representation of the data is critical, simply put XML and/or JSON.
After clarifying the data model, we now turn to the description of an API. Here I don’t want to go into too much detail, as I already did this in one of my last blog posts . For a good API description it is important to develop an understanding of the OpenAPI specification, based on the collected information from phase 1 and 2. A tool like Spotlight Studio can only assist in this. As is generally the case in software development, writing in a team, even collaboratively, can be another factor for a good API. Thus, a corresponding Git repository should be created for each API product. Similarly, rule sets should be in place for linters such as Spectral and OpenAPI-cli . The basis for the rulesets are existing or yet to be defined API guidelines. The rulesets can be used to prevent or even eliminate errors or undesirable description styles. In conjunction with a Git repo, the creation of a pipeline for validation makes sense as a first step. The creation and maintenance of an API Design Library helps – especially at the beginning of a description – to reduce hurdles.
The API description has been created. Now we need to clarify how we want to expose the API externally or internally. In the case of a REST API, we need an architecture layer that ensures that the API is available in a secured and managed manner. This is where the API gateway comes into play – assuming that the communication flow is north-south. In order not to go into further detail, I refer to my previous blogposts around API gateways at this point.
We have now made the API available via a gateway and this may already provide sample data. From this moment on, it is important to think about a connection to the backend, if this does not yet exist. To achieve a certain quality and speed, the recommendation would be to use a programming language or framework that the development team is well familiar with and that fits the requirements. On the codecentric blog I once described this using Spring Boot and API first as a starting point. Specifically, it is about a first representation of the data from the backend system. It is also possible that at least one transformation is needed.
With regard to transformations, it is not a matter of reinventing the wheel and building the next integration platform. It is rather a question of relying on enterprise integration patterns on the one hand and existing product offerings or frameworks on the other – such as Apache Camel, Spring Integration, Apache Nifi, Microsoft LiveApps, MuleSoft or SaaS services (such as Make). Regarding the API backend, we have looked at foundational APIs for the first time. That is, APIs that deliver data directly from backend systems. But to further improve the consumer experience, we should also think about aggregation of services on the provider side. After all, there is nothing as bad as a consumer trying to do aggregations on his or her own side and not getting the desired results. In order to offer aggregation, the same applies with regard to services as with foundational APIs. For the developer experience, something familiar should be used with regard to the development of the services.
The API is ready for a first test with the connection to the backend. But how can we test it now? Testing takes place on the basis of the API description. The validated description thus becomes a contract. Currently, in API Experience projects, we generate a postman collection from the description. Supported by the tool Portman , we will be able to make the postman collection undergo appropriate contract, variation and integration tests. For this purpose, we will take the pipeline already mentioned in the context of the “API description” phase as a basis and develop it accordingly. In Listing 1, we see parts of the code for a corresponding pipeline with Azure DevOps, respectively. The pipeline consists of several stages. Here, we’ll pick out two (VALIDATE and TEST_BASIC_AUTH), as the entire script is a bit beyond the scope of this article.
We have seen that the path of an API as a digital product is not an easy one and is full of hurdles and even pitfalls. Likewise, it does not make sense to simply trust the marketing promises of solution providers. APIs beyond traditional integration need a true product mindset to be successful in the market. The interests of the consumer(s) must be clearly in focus.
Your job at Codecentric?
More articles in this subject area
Discover exciting further topics and let the codecentric world inspire you.