1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-05-19 21:33:04 +02:00

Preparations for the Second Edition

This commit is contained in:
Sergey Konstantinov 2023-04-11 20:32:32 +03:00
parent e679fed5cf
commit cf656ab7e3
7 changed files with 56 additions and 34 deletions

View File

@ -1,7 +1,7 @@
# Read [‘The API’ Book by Sergey Konstantinov](https://twirl.github.io/The-API-Book) in English
# Читать [книгу ‘The API’ Сергея Константинова](https://twirl.github.io/The-API-Book/index.ru.html) по-русски
This is the working repository for ‘The API’ book written by Sergey Konstantinov ([email](mailto:twirl-team@yandex.ru), [Linkedin profile](https://linkedin.com/in/twirl), [Medium blog](https://twirl.medium.com)).
This is the working repository for ‘The API’ book written by Sergey Konstantinov ([email](mailto:yatwirl@gmail.com), [Linkedin profile](https://linkedin.com/in/twirl), [Medium blog](https://twirl.medium.com)).
API-first development is one of the hottest technical topics nowadays since many companies started to realize that API serves as a multiplicator to their opportunities—but it also amplifies the design mistakes as well.

View File

@ -1,4 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 23.04C0 12.1788 0 6.74826 3.37413 3.37413C6.74826 0 12.1788 0 23.04 0H24.96C35.8212 0 41.2517 0 44.6259 3.37413C48 6.74826 48 12.1788 48 23.04V24.96C48 35.8212 48 41.2517 44.6259 44.6259C41.2517 48 35.8212 48 24.96 48H23.04C12.1788 48 6.74826 48 3.37413 44.6259C0 41.2517 0 35.8212 0 24.96V23.04Z" fill="#0077FF"/>
<path d="M25.54 34.5801C14.6 34.5801 8.3601 27.0801 8.1001 14.6001H13.5801C13.7601 23.7601 17.8 27.6401 21 28.4401V14.6001H26.1602V22.5001C29.3202 22.1601 32.6398 18.5601 33.7598 14.6001H38.9199C38.0599 19.4801 34.4599 23.0801 31.8999 24.5601C34.4599 25.7601 38.5601 28.9001 40.1201 34.5801H34.4399C33.2199 30.7801 30.1802 27.8401 26.1602 27.4401V34.5801H25.54Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

View File

@ -1,20 +1,34 @@
### [API Quality Criteria][intro-api-quality]
### [Overview of Existing API Development Solutions][intro-api-solutions-overview]
Before we start laying out the recommendations, we ought to specify what API we consider “fine,” and what's the profit of having a “fine” API.
In the first three sections of this book, we aim to discuss API design in general, not bound to any specific technology. The concepts we describe are equally applicable to web services and, let's say, operating systems (OS) APIs.
Let's discuss the second question first. Obviously, API “finesse” is first of all defined through its capability to solve developers' and users' problems. (One may reasonably say that solving problems might not be the main purpose of offering the API of ours to developers. However, manipulating public opinion is out of this book's author's interest. Here we assume that APIs exist primarily to help people, not for some other covertly declared purposes.)
Still, two main scenarios dominate the stage when we talk about API development:
* developing client-server applications
* developing client SDKs.
So, how the “fine” API design might assist developers in solving their (and their users') problems? Quite simply: a well-designed API allows developers to do their jobs in the most efficient and comprehensible manner. The distance from formulating a task to writing working code must be as short as possible. Among other things, it means that:
* it must be totally obvious out of your API's structure how to solve a task
* ideally, developers at first glance should be able to understand, what entities are meant to solve their problem
* the API must be readable;
* ideally, developers write correct code after just looking at the methods nomenclature, never bothering about details (especially API implementation details!)
* it is also very important to mention that not only problem solution (the “happy path”) should be obvious, but also possible errors and exceptions (the “unhappy path”) as well
* the API must be consistent
* while developing new functionality (i.e. while using previously unknown API entities) developers may write new code similar to the code they have already written using the known API concepts, and this new code will work.
In the first case, we almost universally talk about APIs working atop the HTTP protocol. Today, the only notable examples of non-HTTP-based client-server interaction protocols are WebSocket (though it might, and frequently does, work in conjecture with HTTP) and highly specialized APIs like media streaming and broadcasting formats.
However, the static convenience and clarity of APIs are simple parts. After all, nobody seeks for making an API deliberately irrational and unreadable. When we are developing an API, we always start with clear basic concepts. Providing you've got some experience in APIs, it's quite hard to make an API core that fails to meet obviousness, readability, and consistency criteria.
#### HTTP API
Problems begin when we start to expand our API. Adding new functionality sooner or later results in transforming once plain and simple API into a mess of conflicting concepts, and our efforts to maintain backwards compatibility will lead to illogical, unobvious, and simply bad design solutions. It is partly related to an inability to predict the future in detail: your understanding of “fine” APIs will change over time, both in objective terms (what problems the API is to solve, and what is the best practice) and in subjective terms too (what obviousness, readability, and consistency *really mean* to your API design).
Though the technology looks homogenous because of using the same application-level protocol, in reality, there is a significant diversity regarding different approaches to realizing HTTP-based APIs.
The principles we are explaining below are specifically oriented to making APIs evolve smoothly over time, not being turned into a pile of mixed inconsistent interfaces. It is crucial to understand that this approach isn't free: a necessity to bear in mind all possible extension variants and to preserve essential growth points means interface redundancy and possibly excessing abstractions being embedded in the API design. Besides, both make the developers' jobs harder. **Providing excess design complexities being reserved for future use makes sense only if this future actually exists for your API. Otherwise, it's simply overengineering.**
**First**, implementations differ in terms of utilizing HTTP capabilities:
* either the client-server interaction heavily relies on the features described in the HTTP standard (or rather standards, as the functionality is split across several different RFCs),
* or HTTP is used as a transport, and there is an additional abstraction level built upon it (e.g. the HTTP capabilities, such as the headers and status codes nomenclatures, are deliberately reduced to a bare minimum, and all the metadata is handled by the higher-level protocol).
The APIs that belong to the first category are usually denoted as “REST” or “RESTful” APIs. The second category comprises different RPC formats and some service protocols, for example, SSH.
**Second**, different HTTP APIs rely on different data formats:
* REST APIs and some RPCs (JSON-RPC, GraphQL, etc.) use the JSON format (sometimes with some additional endpoints to transfer binary data);
* GRPC and some specialized RPC protocols like Apache Avro utilize binary formats (such as Protocol Buffers, FlatBuffers, or Apache Avro's own format);
* finally, some RPC protocols (notably SOAP and XML-RPC) employ the XML data format (which is considered a rather outdated practice by many developers).
All the above-mentioned technologies are operating in significantly dissimilar paradigms — which arise rather hot “holy war” debates among software engineers — though at the moment this book is being written we observe the choice for general-purpose APIs is reduced to the “REST API (in fact, JSON-over-HTTP) vs. GRPC vs. GraphQL” triad.
#### SDKs
The term “SDK” is not, strictly speaking, related to APIs: this is a generic term for a software toolkit. As with “REST,” however, it got some popular reading as a client framework to work with some underlying API. This might be, for example, a wrapper to a client-server API, or a UI to some OS API. The major difference from the APIs we discussed in the previous paragraph is that an “SDK” is implemented for a specific programming language and platform, and its purpose is translating the abstract language-agnostic set methods (comprising a client-server or an OS API) into concrete structures specific for the programming language and the platform.
Unlike client-server APIs, such SDKs can hardly be generalized as each of them is developed for a specific language-platform pair. There are some interoperable SDKs, notable cross-platform mobile (React Native, Flutter, Xamarin) and desktop (JavaFX, QT) frameworks and some highly-specialized solutions (Unity).
Still, SDKs feature some generality in terms of *the problems they solve*, and Section V of this book will be dedicated to solving these problems of translating contexts and making UI components.

View File

@ -0,0 +1,20 @@
### [API Quality Criteria][intro-api-quality]
Before we start laying out the recommendations, we ought to specify what API we consider “fine,” and what's the profit of having a “fine” API.
Let's discuss the second question first. Obviously, API “finesse” is first of all defined through its capability to solve developers' and users' problems. (One may reasonably say that solving problems might not be the main purpose of offering the API of ours to developers. However, manipulating public opinion is out of this book's author's interest. Here we assume that APIs exist primarily to help people, not for some other covertly declared purposes.)
So, how the “fine” API design might assist developers in solving their (and their users') problems? Quite simply: a well-designed API allows developers to do their jobs in the most efficient and comprehensible manner. The distance from formulating a task to writing working code must be as short as possible. Among other things, it means that:
* it must be totally obvious out of your API's structure how to solve a task
* ideally, developers at first glance should be able to understand, what entities are meant to solve their problem
* the API must be readable;
* ideally, developers write correct code after just looking at the methods nomenclature, never bothering about details (especially API implementation details!)
* it is also very important to mention that not only problem solution (the “happy path”) should be obvious, but also possible errors and exceptions (the “unhappy path”) as well
* the API must be consistent
* while developing new functionality (i.e. while using previously unknown API entities) developers may write new code similar to the code they have already written using the known API concepts, and this new code will work.
However, the static convenience and clarity of APIs are simple parts. After all, nobody seeks for making an API deliberately irrational and unreadable. When we are developing an API, we always start with clear basic concepts. Providing you've got some experience in APIs, it's quite hard to make an API core that fails to meet obviousness, readability, and consistency criteria.
Problems begin when we start to expand our API. Adding new functionality sooner or later results in transforming once plain and simple API into a mess of conflicting concepts, and our efforts to maintain backwards compatibility will lead to illogical, unobvious, and simply bad design solutions. It is partly related to an inability to predict the future in detail: your understanding of “fine” APIs will change over time, both in objective terms (what problems the API is to solve, and what is the best practice) and in subjective terms too (what obviousness, readability, and consistency *really mean* to your API design).
The principles we are explaining below are specifically oriented to making APIs evolve smoothly over time, not being turned into a pile of mixed inconsistent interfaces. It is crucial to understand that this approach isn't free: a necessity to bear in mind all possible extension variants and to preserve essential growth points means interface redundancy and possibly excessing abstractions being embedded in the API design. Besides, both make the developers' jobs harder. **Providing excess design complexities being reserved for future use makes sense only if this future actually exists for your API. Otherwise, it's simply overengineering.**

View File

@ -1,4 +0,0 @@
<svg width="48" height="48" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M0 23.04C0 12.1788 0 6.74826 3.37413 3.37413C6.74826 0 12.1788 0 23.04 0H24.96C35.8212 0 41.2517 0 44.6259 3.37413C48 6.74826 48 12.1788 48 23.04V24.96C48 35.8212 48 41.2517 44.6259 44.6259C41.2517 48 35.8212 48 24.96 48H23.04C12.1788 48 6.74826 48 3.37413 44.6259C0 41.2517 0 35.8212 0 24.96V23.04Z" fill="#0077FF"/>
<path d="M25.54 34.5801C14.6 34.5801 8.3601 27.0801 8.1001 14.6001H13.5801C13.7601 23.7601 17.8 27.6401 21 28.4401V14.6001H26.1602V22.5001C29.3202 22.1601 32.6398 18.5601 33.7598 14.6001H38.9199C38.0599 19.4801 34.4599 23.0801 31.8999 24.5601C34.4599 25.7601 38.5601 28.9001 40.1201 34.5801H34.4399C33.2199 30.7801 30.1802 27.8401 26.1602 27.4401V34.5801H25.54Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 808 B

View File

@ -6,22 +6,22 @@
* разработка клиент-серверных приложений;
* разработка клиентских SDK.
В первом случае мы говорим практически исключительно об API, работающих поверх протокола HTTP. В настоящий момент клиент-серверное взаимодействие, не опирающееся на HTTP, можно встретить разве что в протоколе WebSockets (хотя и он может быть использован совместно с HTTP, что часто и происходит), а также в различных форматах потокового вещания и других узкоспециализированных интерфейсах.
В первом случае мы говорим практически исключительно об API, работающих поверх протокола HTTP. В настоящий момент клиент-серверное взаимодействие, не опирающееся на HTTP, можно встретить разве что в протоколе WebSocket (хотя и он может быть использован совместно с HTTP, что часто и происходит), а также в различных форматах потокового вещания и других узкоспециализированных интерфейсах.
#### HTTP API
Несмотря на кажущуюся гомогенность технологии ввиду использования одного протокола прикладного уровня, в действительности же наблюдается значительное разнообразие подходов к имплементации HTTP API.
**Во-первых**, существующие протоколы различаются подходом к утилизации собственно протокола HTTP:
**Во-первых**, существующие реализации различаются подходом к утилизации собственно протокола HTTP:
* либо клиент-серверное взаимодействие опирается на описанные в стандарте HTTP возможности (точнее было бы сказать, «стандартах HTTP», поскольку функциональность протокола описана во множестве разных RFC);
* либо HTTP утилизируется как транспорт, и поверх него выстроен дополнительный уровень абстракции (т.е. возможности HTTP, такие как номенклатура ошибок или заголовков, сознательно редуцируются до минимального уровня, а вся мета-информация переносится на уровень вышестоящего протокола).
К первой категории относятся API, которые принято обозначать словом «REST» или «RESTful». а ко второй — все виды RPC, а также прикладные протоколы типа SSH.
Во-вторых, реализации HTTP API опираются на разные форматы передаваемых данных:
**Во-вторых**, реализации HTTP API опираются на разные форматы передаваемых данных:
* REST API и некоторые RPC (JSON-RPC, GraphQL) полагаются в основном на формат JSON (опционально дополненный передачей бинарных файлов);
* GRPC, а также Apache Avro и другие специализированные протоколы полагаются на бинарные форматы (такие как Protocol Buffers или FlatBuffers);
* наконец, некоторые RPC-протоколы (SOAP, XML-RPC) используют для передачи данных формат XML (что на сегодня является скорее устаревшей технологией).
* GRPC, а также Apache Avro и другие специализированные RPC-протоколы полагаются на бинарные форматы (такие как Protocol Buffers, FlatBuffers и собственный формат Apache Avro);
* наконец, некоторые RPC-протоколы (SOAP, XML-RPC) используют для передачи данных формат XML (что многими разработчиками сегодня воспринимается скорее как устаревшая практика).
Все перечисленные технологии оперируют существенно разными парадигмами — и вызывают естественным образом большое количество холиваров — хотя на момент написания этой книги можно констатировать, что для API общего назначения выбор практически сводится к триаде «REST API (фактически, JSON over HTTP) против GRPC против GraphQL».
@ -31,6 +31,6 @@ HTTP API будет посвящён раздел IV; мы также отдел
Понятие SDK, вообще говоря, вовсе не относится к API: это просто термин для некоторого набора программных инструментов. Однако, как и за «REST», за ним закрепилось некоторое определённое толкование — как клиентского фреймворка для работы с некоторым API. Это может быть как обёртка над клиент-серверным API, так и UI-библиотека в рамках какой-то платформы. Существенным отличием от вышеперечисленных API является то, что «SDK» реализован для какого-то конкретного языка программирования, и его целью является как раз превращение абстрактного набора методов (клиент-серверного API или API операционной системы) в конкретные структуры, разработанные для конкретного языка программирования и конкретной платформы.
В отличие от клиент-серверных API, обобщить такие SDK не представляется возможным, т.к. каждый из них написан под конкретное сочетание язык программирования-платформа. Из интероперабельных технологий в мире SDK можно привести в пример разве что React / React Native.
В отличие от клиент-серверных API, обобщить такие SDK не представляется возможным, т.к. каждый из них написан под конкретное сочетание язык программирования-платформа. Из интероперабельных технологий в мире SDK можно привести в пример разве что кросс-платформенные мобильные (React Native, Flutter, Xamarin) и десктопные фреймворки (JavaFX, QT) и некоторые узкоспециализированные решения (Unity).
Тем не менее, SDK обладают общностью *на уровне задач*, которые они решают (см. выше), и именно этому (решению проблем трансляции и предоставления UI-компонент) будет посвящён раздел V настоящей книги.
Тем не менее, SDK обладают общностью *на уровне задач*, которые они решают, и именно этому (решению проблем трансляции и предоставления UI-компонент) будет посвящён раздел V настоящей книги.

View File

@ -28,10 +28,6 @@
"viaTwitter": "blogovodoved"
},
"services": [
{
"key": "vk",
"link": "https://vk.com/share.php?url=${url}"
},
{
"key": "facebook",
"link": "https://www.facebook.com/sharer.php?u=${url}"