1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-05-31 22:09:37 +02:00

About author

This commit is contained in:
Sergey Konstantinov 2022-07-31 15:08:37 +03:00
parent 8b3ee1bb97
commit cf39846cc3
13 changed files with 246 additions and 440 deletions

147
docs/assets/landing.css Normal file
View File

@ -0,0 +1,147 @@
@font-face {
font-family: local-serif;
src: url(PTSerif-Regular.ttf);
}
@font-face {
font-family: local-serif;
src: url(PTSerif-Bold.ttf);
font-weight: bold;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
ul > li {
padding-left: 1em;
}
p, body > ul, h3 {
margin: 0 0 1em 0;
}
body {
font-size: 14pt;
margin: 5px;
}
nav {
text-align: center;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
nav a {
vertical-align: -12%;
content: ' ';
width: 1em;
height: 1em;
display: inline-block;
background-position: 0 0;
background-size: auto 100%;
background-repeat: no-repeat;
text-decoration: none;
}
a.github {
background-image: url(github.jpg);
width: 1.2em;
}
a.linkedin {
background-image: url(linkedin.png);
width: 1.176em;
}
a.twitter {
background-image: url(twitter.svg);
width: 1.392em;
}
a.habr {
background-image: url(habr.png);
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.patreon {
background-image: url(patreon.png);
}
a.medium {
background-image: url(medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.kindle {
width: auto;
vertical-align: unset;
}
img.header {
width: 80%;
}
.about-me {
display: flex;
flex-flow: row-reverse wrap;
gap: 0.5em;
justify-content: center;
}
.about-me aside {
min-width: 200px;
max-width: 400px;
padding-top: 0.4em;
}
.about-me aside img {
width: 100%;
}
.about-me .content {
flex-basis: 320px;
flex-grow: 2;
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}

View File

@ -26,138 +26,12 @@
property="og:url"
content="https://github.com/twirl/The-API-Book"
/>
<style>
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Regular.ttf);
}
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Bold.ttf);
font-weight: bold;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
ul > li {
padding-left: 1em;
}
p {
margin: 1em 0;
}
body {
font-size: 14pt;
margin: 5px;
}
nav {
text-align: center;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
nav a {
vertical-align: -12%;
content: ' ';
width: 1em;
height: 1em;
display: inline-block;
background-position: 0 0;
background-size: auto 100%;
background-repeat: no-repeat;
text-decoration: none;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.habr {
background-image: url(assets/habr.png);
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.patreon {
background-image: url(assets/patreon.png);
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.kindle {
width: auto;
vertical-align: unset;
}
body img {
width: 100%;
max-width: 1000px;
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}
</style>
<link rel="stylesheet" href="assets/landing.css"/>
</head>
<body>
<nav>
<img
class="header"
src="assets/header.jpg"
alt="Sergey Konstantinov. The API"
/><br />
@ -170,6 +44,7 @@
</nav>
<p>The 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.</p>
<p>This book is dedicated to designing APIs: how to build the architecture properly, from a high-level planning down to final interfaces, and to extend API in a backwards-compatible manner.</p>
<p>Illustration &amp; inspiration: <a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.</p>
<p>You might download ‘The API’ in <a href="API.en.pdf">PDF</a>, <a href="API.en.epub">EPUB</a>, or <a href="API.en.html">read it online</a>.
</p>
<h3>Table of Contents</h3>
@ -228,7 +103,14 @@
</ul>
<p>This book is distributed under the <a href="http://creativecommons.org/licenses/by-nc/4.0/">Creative Commons Attribution-NonCommercial 4.0 International licence</a>.</p>
<p>Source code available at <a href="https://github.com/twirl/The-API-Book">github.com/twirl/The-API-Book</a></p>
<p>Illustration &amp; inspiration: <a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.</p>
<p>Книгу «API» можно <a href="index.ru.html">читать по-русски</a>.</p>
<h3><a name="about-author">About the Author</a></h3>
<section class="about-me">
<aside><img src="https://konstantinov.cc/static/me.png"/></aside>
<div class="content">
<p>Sergey Konstantinov has been working with APIs for more than a decade. He started his career as a software engineer in the Maps API division at Yandex and eventually became the head of the service, being responsible for both technical architecture and product management.</p>
<p>During this tenure, Sergey got a unique experience in building world-class APIs with a daily audience of tens of millions, planning roadmaps for such a service, and giving numerous public speeches. He also worked for a year and a half as a member of the W3C Technical Architecture Group.</p>
<p>After nine years in Maps, Sergey switched to technical-lead roles in other departments and companies, leading integration efforts and being responsible for the technical architecture of entire business units. Today, Sergey lives in Tallinn, Estonia, and works as a staff software engineer at Bolt.</p></div>
</section>
<p>Книгу «API» можно <a href="index.ru.html">читать по-русски</a>.</p>
</body>
</html>

View File

@ -26,138 +26,12 @@
property="og:url"
content="https://github.com/twirl/The-API-Book"
/>
<style>
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Regular.ttf);
}
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Bold.ttf);
font-weight: bold;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
ul > li {
padding-left: 1em;
}
p {
margin: 1em 0;
}
body {
font-size: 14pt;
margin: 5px;
}
nav {
text-align: center;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
nav a {
vertical-align: -12%;
content: ' ';
width: 1em;
height: 1em;
display: inline-block;
background-position: 0 0;
background-size: auto 100%;
background-repeat: no-repeat;
text-decoration: none;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.habr {
background-image: url(assets/habr.png);
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.patreon {
background-image: url(assets/patreon.png);
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.kindle {
width: auto;
vertical-align: unset;
}
body img {
width: 100%;
max-width: 1000px;
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}
</style>
<link rel="stylesheet" href="assets/landing.css"/>
</head>
<body>
<nav>
<img
class="header"
src="assets/header.jpg"
alt="Сергей Константинов. API"
/><br />
@ -170,6 +44,7 @@
</nav>
<p>«API-first» подход — одна из самых горячих горячих тем в разработке программного обеспечения в наше время. Многие компании начали понимать, что API выступает мультипликатором их возможностей — но также умножает и допущенные ошибки.</p>
<p>Эта книга посвящена проектированию API: как правильно выстроить архитектуру, начиная с высокоуровневого планирования и заканчивая деталями реализации конкретных интерфейсов, и как развивать API, не нарушая обратную совместимость.</p>
<p>Иллюстрации и вдохновение: Maria Konstantinova &middot; <a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.</p>
<p>Вы можете скачать книгу «API» в формате <a href="API.ru.pdf">PDF</a>, <a href="API.ru.epub">EPUB</a>, или <a href="API.ru.html">прочитать её онлайе</a>.
</p>
<h3>Содержание</h3>
@ -228,7 +103,14 @@
</ul>
<p>Это произведение доступно по <a href="http://creativecommons.org/licenses/by-nc/4.0/">лицензии Creative Commons «Attribution-NonCommercial» («Атрибуция — Некоммерческое использование») 4.0 Всемирная</a>.</p>
<p>Исходный код доступен на <a href="https://github.com/twirl/The-API-Book">github.com/twirl/The-API-Book</a></p>
<p>Иллюстрации и вдохновение: Maria Konstantinova &middot; <a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.</p>
<p>You might also <a href="index.html">read ‘The API’ in English</a>.</p>
<h3><a name="about-author">Об авторе</a></h3>
<section class="about-me">
<aside><img src="https://konstantinov.cc/static/me.png"/></aside>
<div class="content">
<p>Сергей Константинов работает с API уже больше десятилетия. Он начинал свою карьеру разработчиком в подразделении API Яндекс.Карт, и со временем стал руководителем всего сервиса, отвечая и за техническую, и за продуктовую составляющую.</p>
<p>За это время Сергей получил уникальный опыт построения API мирового уровня с дневной аудторией в десятки миллионов человек, планирования роадмапов для такого продукта и многочисленных публичных выступлений. Он также проработал полтора года в составе Технической архитектурной группы W3C.</p>
<p>После девяти лет в Картах Сергей переключился на технические роли в других департаментах и компаниях, занимаясь интеграционными проектами и будучи ответственным за техническую архитектуру целых продуктов компании. Сегодня Сергей живёт в Таллинне, Эстония, и работает ведущим инженером в компании Bolt.</p></div>
</section>
<p>You might also <a href="index.html">read ‘The API’ in English</a>.</p>
</body>
</html>

View File

@ -13,4 +13,12 @@ html, body {
* {
font-family: local-monospace, monospace !important;
white-space: nowrap !important;
}
.position-absolute {
position: absolute;
}
.table {
display: table;
}

View File

@ -1,10 +1,10 @@
### The Testing Environment
If the operations executed via the API imply consequences for end users or partners (cost money, in particular) you must provide a test version of the API. In this test API, real-world actions either don't happen at all (for instance, orders are created but nobody serves them) or are simulated by cheaper means (let's say, instead of sending an SMS to a user, an email is sent to the developer's mailbox).
If the operations executed via the API imply consequences for end users or partners (cost money, in particular) you must provide a test version of the API. In this testing API, real-world actions either don't happen at all (for instance, orders are created but nobody serves them) or are simulated by cheaper means (let's say, instead of sending an SMS to a user, an email is sent to the developer's mailbox).
However, in many cases having a test version is not enough — like in our coffee-machine API example. If an order is created but not served, partners are not able to test the functionality of delivering the order or requesting a refund. To run the full cycle of testing, developers need the capability of pushing the order through statuses, as this would happen in reality.
However, in many cases having a test version is not enough — like in our coffee-machine API example. If an order is created but not served, partners are not able to test the functionality of delivering the order or requesting a refund. To run the full cycle of testing, developers need the capability of pushing the order through stages, as this would happen in reality.
A direct solution to this problem is providing a full set of testing API and administrative interfaces. It means that developers will need to run a second application in parallel — the one you're giving to coffee shops so they might get and serve orders (and if there is a delivery functionality, the third app as well: the courier's one) — and make all these actions that coffee shop staff normally does. Obviously, that's not an ideal solution, because of several reasons:
A direct solution to this problem is providing a full set of testing APIs and administrative interfaces. It means that developers will need to run a second application in parallel — the one you're giving to coffee shops so they might get and serve orders (and if there is a delivery functionality, the third app as well: the courier's one) — and make all these actions that coffee shop staff normally does. Obviously, that's not an ideal solution, because of several reasons:
* end user application developers will need to additionally learn how coffee shop and courier apps work, which has nothing to do with the task they're solving;
* you will need to invent and implement some matching algorithm: an order made through a test application must be assigned to a specific virtual courier; this actually means creating an isolated virtual ‘sandbox’ (meaning — a full set of services) for each specific partner;
* executing a full ‘happy path’ of an order will take minutes, maybe tens of minutes, and will require making a multitude of actions in several different interfaces.
@ -19,11 +19,11 @@ Ideally, you should provide helper methods for any actions that are conducted by
The disadvantage of this approach is that client developers still need to know how the ‘flip side’ of the system works, though in simplified terms.
##### The pre-defined scenario simulator
##### The simulator of pre-defined scenarios
The alternative to providing the testing environment API is simulating the working scenarios. In this case, the testing environment takes control over ‘underwater’ parts of the system. In our coffee example, that means that, after the order is submitted, the system will simulate all the preparation steps and then the delivery of the beverage to the customer.
The alternative to providing the testing environment API is simulating the working scenarios. In this case, the testing environment takes control over ‘underwater’ parts of the system and ‘plays’ all external agents' actions. In our coffee example, that means that, after the order is submitted, the system will simulate all the preparation steps and then the delivery of the beverage to the customer.
The advantage of this approach is that it demonstrates vividly how the system works according to the API vendor design plans, e.g. in which sequence the events are generated, and which steps the order passes through. It also reduces the chance of making mistakes in testing scripts, as the API vendor guarantees the actions will be executed in the correct order with the right parameters.
The advantage of this approach is that it demonstrates vividly how the system works according to the API vendor design plans, e.g. in which sequence the events are generated, and which stages the order passes through. It also reduces the chance of making mistakes in testing scripts, as the API vendor guarantees the actions will be executed in the correct order with the right parameters.
The main disadvantage is the necessity to create a separate scenario for each unhappy path (effectively, for every possible error), and give developers the capability of denoting which scenario they want to run. (For example, like that: if there is a pre-agreed comment to the order, the system will simulate a specific error, and developers will be able to write and debug the code that deals with the error.)
@ -31,4 +31,4 @@ The main disadvantage is the necessity to create a separate scenario for each un
Your final goal in implementing testing APIs, regardless of which option you choose, is allowing partners to automate the QA process for their products. The testing environment should be developed with this purpose in mind; for example, if an end user might be brought to a 3-D Secure page to pay for the order, the testing environment API must provide some way of simulating the successful (or not) passing of this step. Also, in both variants, it's possible (and desirable) to allow running the scenarios in a fast-forward manner that will allow making auto-testing much faster than manual testing.
Of course, not every partner will be able to employ this possibility (which also means that ‘manual’ way of testing usage scenarios must also be supported alongside the programmatical one) simply because not every business might afford to hire a QA automation engineer. Nevertheless, the ability to write such auto-tests is a huge competitive advantage from a technically advanced partner's point of view.
Of course, not every partner will be able to employ this possibility (which also means that ‘manual’ way of testing usage scenarios must also be supported alongside the programmatical one) simply because not every business might afford to hire a QA automation engineer. Nevertheless, the ability to write such auto-tests is your API's huge competitive advantage from a technically advanced partner's point of view.

View File

@ -6,6 +6,14 @@
"description": "Designing APIs is a very special skill: API is a multiplier to both your opportunities and mistakes. This book is written to share the expertise and describe the best practices in the API design. In Section I, we'll discuss designing APIs as a concept: how to build the architecture properly, from high-level planning down to final interfaces. Section II is dedicated to expanding existing APIs in a backwards-compatible manner.",
"locale": "en_US",
"file": "API",
"aboutMe": {
"title": "About the Author",
"content": [
"<p>Sergey Konstantinov has been working with APIs for more than a decade. He started his career as a software engineer in the Maps API division at Yandex and eventually became the head of the service, being responsible for both technical architecture and product management.</p>",
"<p>During this tenure, Sergey got a unique experience in building world-class APIs with a daily audience of tens of millions, planning roadmaps for such a service, and giving numerous public speeches. He also worked for a year and a half as a member of the W3C Technical Architecture Group.</p>",
"<p>After nine years in Maps, Sergey switched to technical-lead roles in other departments and companies, leading integration efforts and being responsible for the technical architecture of entire business units. Today, Sergey lives in Tallinn, Estonia, and works as a staff software engineer at Bolt.</p>"
]
},
"landingFile": "index.html",
"url": "https://twirl.github.io/The-API-Book/",
"favicon": "/img/favicon.png",
@ -48,14 +56,14 @@
"support": ["patreon", "kindle"],
"content": [
"<p>The 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.</p>",
"<p>This book is dedicated to designing APIs: how to build the architecture properly, from a high-level planning down to final interfaces, and to extend API in a backwards-compatible manner.</p>"
"<p>This book is dedicated to designing APIs: how to build the architecture properly, from a high-level planning down to final interfaces, and to extend API in a backwards-compatible manner.</p>",
"<p>Illustration &amp; inspiration: <a href=\"https://www.instagram.com/art.mari.ka/\">art.mari.ka</a>.</p>"
],
"download": "You might download ‘The API’ in",
"or": "or",
"readOnline": "read it online",
"license": "This book is distributed under the <a href=\"http://creativecommons.org/licenses/by-nc/4.0/\">Creative Commons Attribution-NonCommercial 4.0 International licence</a>.",
"footer": [
"<p>Illustration &amp; inspiration: <a href=\"https://www.instagram.com/art.mari.ka/\">art.mari.ka</a>.</p>",
"<p>Книгу «API» можно <a href=\"index.ru.html\">читать по-русски</a>.</p>"
]
},

View File

@ -12,12 +12,6 @@
<!-- content -->
<div id="content"></div>
<!-- dependencies -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.4.0/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/3.4.4/joint.js"></script>
<!-- code -->
<script type="text/javascript" src="l10n.js"></script>
<script type="text/javascript" src="lib/lib.js"></script>

View File

@ -1,35 +1,20 @@
(function (global) {
global.lib = {};
const lib = (global.lib = {});
global.lib.paper = ({ height, width, id = 'content' }) => {
const graph = new joint.dia.Graph({}, { cellNamespace: joint.shapes });
const paper = new joint.dia.Paper({
el: document.getElementById(id),
model: graph,
width,
height,
gridSize: 1,
cellViewNamespace: joint.shapes
});
return { paper, graph };
lib.group = ({ parent, height, width, title, left, top }) => {
const element = document.createElement('div');
element.classList.add('position-absolute');
element.innerHTML =
};
global.lib.group = ({
graph,
height = 200,
width = 800,
title,
left,
top
}) => {
lib.entity = ({ parent, height, width, title, left, top, items }) => {
return new joint.shapes.standard.HeaderedRectangle()
.resize(height, width)
.resize(width, height)
.position(left, top)
.attr('root/title', title)
.attr('header/fill', 'lightgray')
.attr('headerText/text', title)
.rotate(-90, true, { x: left + height / 2, y: top + height / 2 })
.attr('bodyText/text', items.join('\n'))
.addTo(graph);
};
})(this);

View File

@ -5,13 +5,23 @@
height: 320
});
lib.group({
// lib.group({
// graph,
// left: 10,
// top: 10,
// width: 980,
// height: 300,
// title: l10n.graphs.topLevel
// });
lib.entity({
graph,
left: 10,
left: 50,
top: 10,
width: 980,
height: 300,
title: l10n.graphs.topLevel
width: 300,
height: 280,
title: 'Recipes Domain',
items: ['GET /recipe/{alias}']
});
};
})(this);

View File

@ -18,11 +18,11 @@
##### Спецификация / справочник / референс
Любая документация начинается с максимально формального описания доступной функциональности. Да, этот вид документации будет максимально бесполезен с точки зрения удобства использования, но не предоставлять его нельзя — справочник является гигиеническим минимумом. Если у вас нет документа, в котором описаны все методы, параметры и настройки, типы всех переменных и их допустимые значения, зафиксированы все опции и поведения — это не API, а просто какая-то самодеятельность.
Любая документация начинается с формального описания доступной функциональности. Да, этот вид документации будет максимально бесполезен с точки зрения удобства использования, но не предоставлять его нельзя — справочник является гигиеническим минимумом. Если у вас нет документа, в котором описаны все методы, параметры и настройки, типы всех переменных и их допустимые значения, зафиксированы все опции и поведения — это не API, а просто какая-то самодеятельность.
Сегодня также стало стандартом предоставлять референс в машиночитаемом виде — согласно какому-либо стандарту, например, OpenAPI.
Спецификация должна содержать не только формальные описания, но и документировать неявные соглашения, такие как, например, последовательность генерации событий или неочевидные побочные эффекты методов. Референс следует рассматривать как наиболее полную из возможных видов документации: изучив референс разработчик должен будет узнать абсолютно обо всей имеющейся функциональности. Его важнейшее прикладное значение — консультативное: разработчики будут обращаться к нему для прояснения каких-то неочевидных вопросов.
Спецификация должна содержать не только формальные описания, но и документировать неявные соглашения, такие как, например, последовательность генерации событий или неочевидные побочные эффекты методов. Референс следует рассматривать как наиболее полный из возможных видов документации: изучив референс разработчик должен будет узнать абсолютно обо всей имеющейся функциональности. Его важнейшее прикладное значение — консультативное: разработчики будут обращаться к нему для прояснения каких-то неочевидных вопросов.
**Важно:** формальная спецификация *не является* документацией сама по себе; документация — это *слова*, которые вы напишете в поле description для каждого поля и метода. Без словесных описаний спецификация годится разве что для проверки, достаточно ли хорошо вы назвали сущности, чтобы разработчик мог догадаться об их смысле самостоятельно.

View File

@ -19,14 +19,16 @@
Недостаток этого подхода заключается в том, что разработчику клиентского приложения всё ещё необходимо разбираться в том, как работает «изнанка» системы, пусть и в упрощённых терминах.
#### Предопределённые сценарии
##### Симулятор предопределённых сценариев
Альтернативой API среды тестирования является симуляция сценариев работы, когда тестовая среда берёт на себя управление «подводной» частью системы. В нашем кофейном примере это будет выглядеть так: после размещения заказа система автоматически симулирует все шаги его приготовления, а потом и получение заказа конечным пользователем. Плюсом такого подхода является наглядная демонстрация, каким образом система работает согласно задумке провайдера API, какие события в какой последовательности генерируются. Кроме того, уменьшается возможность ошибки, поскольку провайдером API гарантируется, что действия будут выполнены в правильном порядке и с правильными параметрами.
Альтернативой API среды тестирования является симуляция сценариев работы, когда тестовая среда берёт на себя управление «подводной» частью системы. В нашем кофейном примере это будет выглядеть так: после размещения заказа система автоматически симулирует все шаги его приготовления, а потом и получение заказа конечным пользователем.
Плюсом такого подхода является наглядная демонстрация, каким образом система работает согласно задумке провайдера API, какие события в какой последовательности генерируются и через какие стадии проходит заказ. Кроме того, уменьшается возможность ошибки в скриптах тестирования, поскольку провайдером API гарантируется, что действия будут выполнены в правильном порядке и с правильными параметрами.
Основным минусом является необходимость разработать отдельный сценарий для всех возможных unhappy path, т.е. для каждой возможной ошибки, причём также необходимо и предоставить возможность разработчику указать, какой именно из сценариев он хочет воспроизвести. (Например, следующим образом: если заказ создан с комментарием определённого вида, будет эмулирована ошибка его исполнения, и разработчик сможет отладить правильную реакцию на такого рода ошибку.)
#### Автоматизация тестирования
Ваша конечная цель при разработке тестового API, независимо от выбранного варианта — это позволить партнёрам автоматизировать тестирование их продуктов. Разработку тестовой среды нужно вести именно с этим прицелом; например, если для оплаты заказа необходимо перевести пользователя на страницу 3DS, в API тестовой среды должен быть предусмотрена возможность программно симулировать прохождение (или непрохождение) пользователем этого вида проверки. Кроме того, в обоих вариантах возможно (и скорее даже желательно) выполнение сценариев в ускоренном масштабе времени, что позволяет производить автоматическое тестирование гораздо быстрее ручного.
Ваша конечная цель при разработке тестового API, независимо от выбранного варианта — это позволить партнёрам автоматизировать тестирование их продуктов. Разработку тестовой среды нужно вести именно с этим прицелом; например, если для оплаты заказа необходимо перевести пользователя на страницу 3-D Secure, то в API тестовой среды должен быть предусмотрена возможность программно симулировать прохождение (или непрохождение) пользователем этого вида проверки. Кроме того, в обоих вариантах возможно (и скорее даже желательно) выполнение сценариев в ускоренном масштабе времени, что позволяет производить автоматическое тестирование гораздо быстрее ручного.
Конечно, далеко не все пользователи этой возможностью смогут воспользоваться (что помимо прочего означает, что «ручной» способ протестировать пользовательские сценарии тоже должен поддерживаться наряду с программным) просто потому что далеко не все бизнесы могут позволить себе нанять автоматизатора тестирования. Тем не менее, сама возможность такие автотесты писать — огромное конкурентное преимущество вашего API в глазах технически продвинутых партнёров.
Конечно, далеко не все партнёры этой возможностью смогут воспользоваться (что помимо прочего означает, что «ручной» способ протестировать пользовательские сценарии тоже должен поддерживаться наряду с программным) просто потому что далеко не все бизнесы могут позволить себе нанять автоматизатора тестирования. Тем не менее, сама возможность такие автотесты писать — огромное конкурентное преимущество вашего API в глазах технически продвинутых партнёров.

View File

@ -7,6 +7,14 @@
"locale": "ru_RU",
"file": "API",
"landingFile": "index.ru.html",
"aboutMe": {
"title": "Об авторе",
"content": [
"<p>Сергей Константинов работает с API уже больше десятилетия. Он начинал свою карьеру разработчиком в подразделении API Яндекс.Карт, и со временем стал руководителем всего сервиса, отвечая и за техническую, и за продуктовую составляющую.</p>",
"<p>За это время Сергей получил уникальный опыт построения API мирового уровня с дневной аудторией в десятки миллионов человек, планирования роадмапов для такого продукта и многочисленных публичных выступлений. Он также проработал полтора года в составе Технической архитектурной группы W3C.</p>",
"<p>После девяти лет в Картах Сергей переключился на технические роли в других департаментах и компаниях, занимаясь интеграционными проектами и будучи ответственным за техническую архитектуру целых продуктов компании. Сегодня Сергей живёт в Таллинне, Эстония, и работает ведущим инженером в компании Bolt.</p>"
]
},
"url": "https://twirl.github.io/The-API-Book/index.ru.html",
"favicon": "/img/favicon.png",
"imageCredit": "Image Credit",
@ -43,14 +51,14 @@
"support": ["patreon"],
"content": [
"<p>«API-first» подход — одна из самых горячих горячих тем в разработке программного обеспечения в наше время. Многие компании начали понимать, что API выступает мультипликатором их возможностей — но также умножает и допущенные ошибки.</p>",
"<p>Эта книга посвящена проектированию API: как правильно выстроить архитектуру, начиная с высокоуровневого планирования и заканчивая деталями реализации конкретных интерфейсов, и как развивать API, не нарушая обратную совместимость.</p>"
"<p>Эта книга посвящена проектированию API: как правильно выстроить архитектуру, начиная с высокоуровневого планирования и заканчивая деталями реализации конкретных интерфейсов, и как развивать API, не нарушая обратную совместимость.</p>",
"<p>Иллюстрации и вдохновение: Maria Konstantinova &middot; <a href=\"https://www.instagram.com/art.mari.ka/\">art.mari.ka</a>.</p>"
],
"download": "Вы можете скачать книгу «API» в формате",
"or": "или",
"readOnline": "прочитать её онлайе",
"license": "Это произведение доступно по <a href=\"http://creativecommons.org/licenses/by-nc/4.0/\">лицензии Creative Commons «Attribution-NonCommercial» («Атрибуция — Некоммерческое использование») 4.0 Всемирная</a>.",
"footer": [
"<p>Иллюстрации и вдохновение: Maria Konstantinova &middot; <a href=\"https://www.instagram.com/art.mari.ka/\">art.mari.ka</a>.</p>",
"<p>You might also <a href=\"index.html\">read ‘The API’ in English</a>.</p>"
]
},

View File

@ -57,138 +57,12 @@ const templates = (module.exports = {
property="og:url"
content="${l10n.links.githubHref}"
/>
<style>
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Regular.ttf);
}
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Bold.ttf);
font-weight: bold;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
ul > li {
padding-left: 1em;
}
p {
margin: 1em 0;
}
body {
font-size: 14pt;
margin: 5px;
}
nav {
text-align: center;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
nav a {
vertical-align: -12%;
content: ' ';
width: 1em;
height: 1em;
display: inline-block;
background-position: 0 0;
background-size: auto 100%;
background-repeat: no-repeat;
text-decoration: none;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.habr {
background-image: url(assets/habr.png);
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.patreon {
background-image: url(assets/patreon.png);
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.kindle {
width: auto;
vertical-align: unset;
}
body img {
width: 100%;
max-width: 1000px;
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}
</style>
<link rel="stylesheet" href="assets/landing.css"/>
</head>
<body>
<nav>
<img
class="header"
src="assets/header.jpg"
alt="${l10n.author}. ${l10n.title}"
/><br />
@ -270,6 +144,12 @@ const templates = (module.exports = {
<p>${l10n.sourceCodeAt} <a href="${l10n.links.githubHref}">${
l10n.links.githubString
}</a></p>
<h3><a name="about-author">${l10n.aboutMe.title}</a></h3>
<section class="about-me">
<aside><img src="https://konstantinov.cc/static/me.png"/></aside>
<div class="content">
${l10n.aboutMe.content.join('\n')}</div>
</section>
${l10n.landing.footer.join('\n')}
</body>
</html>`;