1
0
mirror of https://github.com/twirl/The-API-Book.git synced 2025-08-10 21:51:42 +02:00

new build script

This commit is contained in:
Sergey Konstantinov
2022-07-07 00:41:03 +03:00
parent 1e5475d6b6
commit 27b826f1c8
18 changed files with 911 additions and 906 deletions

View File

@@ -1,7 +1,7 @@
import { resolve as pathResolve } from 'path';
import templates from './src/templates.js';
import { init, plugins } from '@twirl/book-builder';
import { readFileSync } from 'fs';
import { readFileSync, writeFileSync } from 'fs';
const l10n = {
en: JSON.parse(readFileSync('./src/en/l10n.json', 'utf-8')),
@@ -12,7 +12,12 @@ const langsToBuild = (process.argv[2] &&
process.argv[2].split(',').map((s) => s.trim())) || ['ru', 'en'];
const targets = (
(process.argv[3] && process.argv[3].split(',')) || ['html', 'pdf', 'epub']
(process.argv[3] && process.argv[3].split(',')) || [
'html',
'pdf',
'epub',
'landing'
]
).reduce((targets, arg) => {
targets[arg.trim()] = true;
return targets;
@@ -52,10 +57,22 @@ langsToBuild.forEach((lang) => {
}
}).then((builder) => {
Object.keys(targets).forEach((target) => {
builder.build(
target,
pathResolve(`docs/${l10n[lang].file}.${lang}.${target}`)
);
if (target !== 'landing') {
builder.build(
target,
pathResolve('docs', `${l10n[lang].file}.${lang}.${target}`)
);
} else {
const landingHtml = templates.landing(
builder.structure,
l10n[lang],
lang
);
writeFileSync(
pathResolve('docs', l10n[lang].landingFile),
landingHtml
);
}
});
});
});

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -1,328 +1,234 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/jpg" href="assets/favicon.png" />
<title>‘The API’ — a free e-book by Sergey Konstantinov</title>
<meta
name="description"
content="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 and API
product management"
/>
<meta property="og:type" content="article" />
<meta
property="og:title"
content="‘The API’ — a free e-book by Sergey Konstantinov"
/>
<meta
property="og:description"
content="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 and API
product management"
/>
<meta property="og:image" content="assets/header.png" />
<meta
property="og:url"
content="https://twirl.github.io/The-API-Book/"
/>
<style>
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Regular.ttf);
}
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/jpg" href="assets/favicon.jpg" />
<title>
Sergey Konstantinov. The API
</title>
<meta
name="description"
content="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."
/>
<meta property="og:type" content="article" />
<meta
property="og:title"
content="Sergey Konstantinov. The API"
/>
<meta
property="og:description"
content="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."
/>
<meta property="og:image" content="assets/header.png" />
<meta
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;
}
@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;
font-size: 24px;
list-style-type: none;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
ul > li {
padding-left: 1em;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
p {
margin: 1em 0;
}
ul > li {
padding-left: 1em;
}
body {
margin: 5px;
}
p {
margin: 1em 0;
}
nav {
text-align: center;
}
body {
font-size: 14pt;
margin: 5px;
}
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;
}
nav {
text-align: center;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
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.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
a.patreon,
a.medium {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.patreon {
background-image: url(assets/patreon.png);
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.habr {
background-image: url(assets/habr.png);
}
a.kindle {
width: auto;
vertical-align: unset;
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
body img {
width: 100%;
max-width: 1000px;
}
a.patreon {
background-image: url(assets/patreon.png);
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}
</style>
</head>
<body>
<nav>
<img
src="assets/header.jpg"
alt="‘The API’ — a free e-book by Sergey Konstantinov"
/><br />
‘The API’ — a free e-book by Sergey Konstantinov<br />Subscribe for
updates on
<a class="github" href="https://github.com/twirl/The-API-Book"></a
><br />Follow me on
<a class="linkedin" href="https://www.linkedin.com/in/twirl/"></a
> &middot; <a
class="twitter"
href="https://twitter.com/blogovodoved"
></a
> &middot; <a class="medium" href="https://twirl.medium.com/"
>Medium</a
><br />You can support this work on
<a class="patreon" href="https://www.patreon.com/yatwirl">Patreon</a
> or <a
class="kindle"
href="https://www.amazon.com/gp/product/B09RHH44S5/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0"
>buy Kindle version</a
>
<br />⚙️⚙️⚙️
</nav>
<p>
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 and API
product management.
</p>
<p>
You might download ‘The API’ in
<a href="API.en.pdf">PDF</a>
or
<a href="API.en.epub">EPUB</a>
format, or
<a href="API.en.html">read it online</a>.
</p>
<h2 class="toc">Table of Contents</h2>
<ul class="table-of-contents">
<li>
<a href="API.en.html#section-1">Introduction</a>
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>
</head>
<body>
<nav>
<img
src="assets/header.jpg"
alt="Sergey Konstantinov. The API"
/><br />
<h1>Sergey Konstantinov<br/><span class="title">The API</span></h1>
<h2>Free e-book</h2>
<br />Subscribe for updates on <a class="github" href="https://github.com/twirl/The-API-Book"></a>
<br/>Follow me on <a class="linkedin" href="https://www.linkedin.com/in/twirl/"></a> &middot; <a class="twitter" href="https://twitter.com/blogovodoved"></a> &middot; <a class="medium" href="https://twirl.medium.com/">Medium</a>
<br />Support this work on <a class="patreon" href="https://www.patreon.com/yatwirl">Patreon</a> &middot; <a class="kindle" href="https://www.amazon.com/gp/product/B09RHH44S5/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0">buy Kindle version</a>
<br />⚙️⚙️⚙️
</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>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>
<ul><li>
<h4><a href="API.en.html#section-1">Introduction</a></h4>
<ul>
<li>
<a href="API.en.html#chapter-1"
>Chapter 1. On the Structure of This Book</a
>
</li>
<li>
<a href="API.en.html#chapter-2"
>Chapter 2. The API Definition</a
>
</li>
<li>
<a href="API.en.html#chapter-3"
>Chapter 3. API Quality Criteria</a
>
</li>
<li>
<a href="API.en.html#chapter-4"
>Chapter 4. Backwards Compatibility</a
>
</li>
<li>
<a href="API.en.html#chapter-5"
>Chapter 5. On Versioning</a
>
</li>
<li>
<a href="API.en.html#chapter-6"
>Chapter 6. Terms and Notation Keys</a
>
</li>
</ul>
<li><a href="API.en.html#chapter-1">Chapter 1. On the Structure of This Book</a></li>
<li><a href="API.en.html#chapter-2">Chapter 2. The API Definition</a></li>
<li><a href="API.en.html#chapter-3">Chapter 3. API Quality Criteria</a></li>
<li><a href="API.en.html#chapter-4">Chapter 4. Backwards Compatibility</a></li>
<li><a href="API.en.html#chapter-5">Chapter 5. On Versioning</a></li>
<li><a href="API.en.html#chapter-6">Chapter 6. Terms and Notation Keys</a></li>
</ul>
</li>
<li>
<a href="API.en.html#section-2">Section I. The API Design</a>
<li>
<h4><a href="API.en.html#section-2">Section I. The API Design</a></h4>
<ul>
<li>
<a href="API.en.html#chapter-7"
>Chapter 7. The API Contexts Pyramid</a
>
</li>
<li>
<a href="API.en.html#chapter-8"
>Chapter 8. Defining an Application Field</a
>
</li>
<li>
<a href="API.en.html#chapter-9"
>Chapter 9. Separating Abstraction Levels</a
>
</li>
<li>
<a href="API.en.html#chapter-10"
>Chapter 10. Isolating Responsibility Areas</a
>
</li>
<li>
<a href="API.en.html#chapter-11"
>Chapter 11. Describing Final Interfaces</a
>
</li>
<li>
<a href="API.en.html#chapter-12"
>Chapter 12. Annex to Section I. Generic API
Example</a
>
</li>
</ul>
<li><a href="API.en.html#chapter-7">Chapter 7. The API Contexts Pyramid</a></li>
<li><a href="API.en.html#chapter-8">Chapter 8. Defining an Application Field</a></li>
<li><a href="API.en.html#chapter-9">Chapter 9. Separating Abstraction Levels</a></li>
<li><a href="API.en.html#chapter-10">Chapter 10. Isolating Responsibility Areas</a></li>
<li><a href="API.en.html#chapter-11">Chapter 11. Describing Final Interfaces</a></li>
<li><a href="API.en.html#chapter-12">Chapter 12. Annex to Section I. Generic API Example</a></li>
</ul>
</li>
<li>
<a href="API.en.html#section-3"
>Section II. The Backwards Compatibility</a
>
<li>
<h4><a href="API.en.html#section-3">Section II. The Backwards Compatibility</a></h4>
<ul>
<li>
<a href="API.en.html#chapter-13"
>Chapter 13. The Backwards Compatibility Problem
Statement</a
>
</li>
<li>
<a href="API.en.html#chapter-14"
>Chapter 14. On the Iceberg's Waterline</a
>
</li>
<li>
<a href="API.en.html#chapter-15"
>Chapter 15. Extending through Abstracting</a
>
</li>
<li>
<a href="API.en.html#chapter-16"
>Chapter 16. Strong Coupling and Related Problems</a
>
</li>
<li>
<a href="API.en.html#chapter-17"
>Chapter 17. Weak Coupling</a
>
</li>
<li>
<a href="API.en.html#chapter-18"
>Chapter 18. Interfaces as a Universal Pattern</a
>
</li>
<li>
<a href="API.en.html#chapter-19"
>Chapter 19. The Serenity Notepad</a
>
</li>
</ul>
<li><a href="API.en.html#chapter-13">Chapter 13. The Backwards Compatibility Problem Statement</a></li>
<li><a href="API.en.html#chapter-14">Chapter 14. On the Iceberg's Waterline</a></li>
<li><a href="API.en.html#chapter-15">Chapter 15. Extending through Abstracting</a></li>
<li><a href="API.en.html#chapter-16">Chapter 16. Strong Coupling and Related Problems</a></li>
<li><a href="API.en.html#chapter-17">Chapter 17. Weak Coupling</a></li>
<li><a href="API.en.html#chapter-18">Chapter 18. Interfaces as a Universal Pattern</a></li>
<li><a href="API.en.html#chapter-19">Chapter 19. The Serenity Notepad</a></li>
</ul>
</li>
<li>
Section III. The API Product
<li>
<h4>Section III. The API Product</h4>
<ul>
<li>Chapter 20. API as a Product</li>
<li>Chapter 21. API Business Models</li>
<li>Chapter 22. Developing a Product Vision</li>
<li>Chapter 23. Communicating with Developers</li>
<li>Chapter 24. Communicating with Business Owners</li>
<li>Chapter 25. API Services Range</li>
<li>Chapter 26. API Key Performance Indicators</li>
<li>Chapter 27. Identifying Users</li>
<li>Chapter 28. Anti-fraud and IT-security</li>
<li>Chapter 29. Supporting API users</li>
<li>Chapter 30. Documentation</li>
<li>Chapter 31. Testing Environment</li>
<li>Chapter 32. Managing Expectations</li>
</ul>
<li>Chapter 21. API Business Models</li>
<li>Chapter 22. Developing a Product Vision</li>
<li>Chapter 23. Communicating with Developers</li>
<li>Chapter 24. Communicating with Business Owners</li>
<li>Chapter 25. API Services Range</li>
<li>Chapter 26. API Key Performance Indicators</li>
<li>Chapter 27. Identifying Users and Preventing Fraud</li>
<li>Chapter 28. IT-security</li>
<li>Chapter 29. Supporting API users</li>
<li>Chapter 30. Documentation</li>
<li>Chapter 31. Testing Environment</li>
<li>Chapter 32. Managing Expectations</li>
</ul>
</li>
</ul>
<p>
The book is distributed under the
<a href="https://creativecommons.org/licenses/by-nc/4.0/"
>Creative Commons Attribution-NonCommercial 4.0 International
licence</a
>. The source code is available on
<a href="https://github.com/twirl/The-API-Book">Github</a>.
Illustration & inspiration by
<a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.
</p>
<p>Также доступна <a href="index.ru.html">русская версия</a>.</p>
</body>
</html>
</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>
</body>
</html>

View File

@@ -1,334 +1,234 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/jpg" href="assets/favicon.png" />
<title>Сергей Константинов. «API». Бесплатная электронная книга</title>
<meta
name="description"
content="Разработка API — особый навык: API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок. Эта книга написана для того, чтобы поделиться опытом и изложить лучшие практики проектирования и управления продуктом API"
/>
<meta property="og:type" content="article" />
<meta
property="og:title"
content="Сергей Константинов. «API». Бесплатная электронная книга"
/>
<meta
property="og:description"
content="Разработка API — особый навык: API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок. Эта книга написана для того, чтобы поделиться опытом и изложить лучшие практики проектирования и управления продуктом API"
/>
<meta property="og:image" content="assets/header.png" />
<meta
property="og:url"
content="https://twirl.github.io/The-API-Book/"
/>
<style>
@font-face {
font-family: local-serif;
src: url(assets/PTSerif-Regular.ttf);
}
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/jpg" href="assets/favicon.jpg" />
<title>
Сергей Константинов. The API
</title>
<meta
name="description"
content="Разработка API — особый навык: API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок. Эта книга написана для того, чтобы поделиться опытом и изложить лучшие практики проектирования API. Книга состоит из двух больших разделов. В первом разделе мы поговорим о проектировании API на стадии разработки концепции — как грамотно выстроить архитектуру, от крупноблочного планирования до конечных интерфейсов. Второй раздел посвящён развитию существующих API с сохранением обратной совместимости"
/>
<meta property="og:type" content="article" />
<meta
property="og:title"
content="Сергей Константинов. The API"
/>
<meta
property="og:description"
content="Разработка API — особый навык: API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок. Эта книга написана для того, чтобы поделиться опытом и изложить лучшие практики проектирования API. Книга состоит из двух больших разделов. В первом разделе мы поговорим о проектировании API на стадии разработки концепции — как грамотно выстроить архитектуру, от крупноблочного планирования до конечных интерфейсов. Второй раздел посвящён развитию существующих API с сохранением обратной совместимости"
/>
<meta property="og:image" content="assets/header.png" />
<meta
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;
}
@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;
font-size: 24px;
list-style-type: none;
}
* {
margin: 0;
padding: 0;
border: none;
font-family: local-serif, Arial, Helvetica, sans-serif;
list-style-type: none;
}
ul > li {
padding-left: 1em;
}
h1 {
font-size: 1.5em;
}
h1.title {
font-size: 2em;
}
h2 {
font-size: 1.2em;
}
p {
margin: 1em 0;
}
ul > li {
padding-left: 1em;
}
body {
margin: 5px;
}
p {
margin: 1em 0;
}
nav {
text-align: center;
}
body {
font-size: 14pt;
margin: 5px;
}
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;
}
nav {
text-align: center;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
nav > img {
max-height: 300px;
object-fit: contain;
}
a.habr {
background-image: url(assets/habr.png);
}
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.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.github {
background-image: url(assets/github.jpg);
width: 1.2em;
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.linkedin {
background-image: url(assets/linkedin.png);
width: 1.176em;
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.twitter {
background-image: url(assets/twitter.svg);
width: 1.392em;
}
a.patreon {
background-image: url(assets/patreon.png);
}
a.habr {
background-image: url(assets/habr.png);
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
a.patreon,
a.medium,
a.habr {
width: auto;
padding-left: 1em;
vertical-align: baseline;
background-position: 0 0.2em;
}
a.kindle {
width: auto;
vertical-align: unset;
}
a.patreon {
background-image: url(assets/patreon.png);
}
body img {
width: 100%;
max-width: 1000px;
}
a.medium {
background-image: url(assets/medium.png);
padding-left: 1.3em;
background-size: 1.42em 1em;
}
@media (min-width: 1010px) {
body {
width: 1000px;
margin: 5px auto;
text-align: justify;
}
}
a.kindle {
width: auto;
vertical-align: unset;
}
@media (min-width: 2000px) {
body {
width: auto;
margin: 5px 25%;
text-align: justify;
}
}
</style>
</head>
<body>
<nav>
<img
src="assets/header.jpg"
alt="Сергей Константинов. «API». Бесплатная электронная книга"
/><br />
Сергей Константинов. «API». Бесплатная электронная книга<br />Подпишитесь
на обновления на
<a class="habr" href="https://habr.com/ru/users/forgotten/posts/"
>Хабре</a
> &middot; <a
class="github"
href="https://github.com/twirl/The-API-Book"
></a
><br />Follow me on
<a class="linkedin" href="https://www.linkedin.com/in/twirl/"></a
> &middot; <a
class="twitter"
href="https://twitter.com/blogovodoved"
></a
> &middot; <a class="medium" href="https://twirl.medium.com/"
>Medium</a
><br />Вы можете поддержать эту работу на
<a class="patreon" href="https://www.patreon.com/yatwirl">Patreon</a
> или <a
class="kindle"
href="https://www.amazon.com/gp/product/B09RHH44S5/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0"
>купить Kindle-версию</a
>
<br />⚙️⚙️⚙️
</nav>
<p>
Разработка API — особый навык: API является как мультипликатором
ваших возможностей, так и мультипликатором ваших ошибок. Эта книга
написана для того, чтобы поделиться опытом и изложить лучшие
практики проектирования и управления продуктом API.
</p>
<p>
Вы можете скачать книгу «API» в формате
<a href="API.ru.pdf">PDF</a>
или
<a href="API.ru.epub">EPUB</a>, или
<a href="API.ru.html">читать её онлайн</a>.
</p>
<h2 class="toc">Содержание</h2>
<ul class="table-of-contents">
<li>
<a href="API.ru.html#section-1">Введение</a>
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>
</head>
<body>
<nav>
<img
src="assets/header.jpg"
alt="Сергей Константинов. The API"
/><br />
<h1>Сергей Константинов<br/><span class="title">The API</span></h1>
<h2>Бесплатная электронная книга</h2>
<br />Подпишитесь на обновления на <a class="habr" href="https://habr.com/ru/users/forgotten/posts/">Хабре</a>
<br />Поддержите эту работу на <a class="patreon" href="https://www.patreon.com/yatwirl">Patreon</a>
<br />⚙️⚙️⚙️
</nav>
<p>«API-first» подход — одна из самых горячих горячих тем в разработке программного обеспечения в наше время. Многие компании начали понимать, что API выступает мультипликатором их возможностей — но также умножает и допущенные ошибки.</p>
<p>Эта книга посвящена проектированию API: как правильно выстроить архитектуру, начиная с высокоуровневого планирования и заканчивая деталями реализации конкретных интерфейсов, и как развивать API, не нарушая обратную совместимость.</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>
<ul><li>
<h4><a href="API.ru.html#section-1">Введение</a></h4>
<ul>
<li>
<a href="API.ru.html#chapter-1"
>Глава 1. О структуре этой книги</a
>
</li>
<li>
<a href="API.ru.html#chapter-2"
>Глава 2. Определение API</a
>
</li>
<li>
<a href="API.ru.html#chapter-3"
>Глава 3. Критерии качества API</a
>
</li>
<li>
<a href="API.ru.html#chapter-4"
>Глава 4. Обратная совместимость</a
>
</li>
<li>
<a href="API.ru.html#chapter-5"
>Глава 5. О версионировании</a
>
</li>
<li>
<a href="API.ru.html#chapter-6"
>Глава 6. Условные обозначения и терминология</a
>
</li>
</ul>
<li><a href="API.ru.html#chapter-1">Глава 1. О структуре этой книги</a></li>
<li><a href="API.ru.html#chapter-2">Глава 2. Определение API</a></li>
<li><a href="API.ru.html#chapter-3">Глава 3. Критерии качества API</a></li>
<li><a href="API.ru.html#chapter-4">Глава 4. Обратная совместимость</a></li>
<li><a href="API.ru.html#chapter-5">Глава 5. О версионировании</a></li>
<li><a href="API.ru.html#chapter-6">Глава 6. Условные обозначения и терминология</a></li>
</ul>
</li>
<li>
<a href="API.ru.html#section-2">Раздел I. Проектирование API</a>
<li>
<h4><a href="API.ru.html#section-2">Раздел I. Проектирование API</a></h4>
<ul>
<li>
<a href="API.ru.html#chapter-7"
>Глава 7. Пирамида контекстов API</a
>
</li>
<li>
<a href="API.ru.html#chapter-8"
>Глава 8. Определение области применения</a
>
</li>
<li>
<a href="API.ru.html#chapter-9"
>Глава 9. Разделение уровней абстракции</a
>
</li>
<li>
<a href="API.ru.html#chapter-10"
>Глава 10. Разграничение областей ответственности</a
>
</li>
<li>
<a href="API.ru.html#chapter-11"
>Глава 11. Описание конечных интерфейсов</a
>
</li>
<li>
<a href="API.ru.html#chapter-12"
>Глава 12. Приложение к разделу I. Модельный API</a
>
</li>
</ul>
<li><a href="API.ru.html#chapter-7">Глава 7. Пирамида контекстов API</a></li>
<li><a href="API.ru.html#chapter-8">Глава 8. Определение области применения</a></li>
<li><a href="API.ru.html#chapter-9">Глава 9. Разделение уровней абстракции</a></li>
<li><a href="API.ru.html#chapter-10">Глава 10. Разграничение областей ответственности</a></li>
<li><a href="API.ru.html#chapter-11">Глава 11. Описание конечных интерфейсов</a></li>
<li><a href="API.ru.html#chapter-12">Глава 12. Приложение к разделу I. Модельный API</a></li>
</ul>
</li>
<li>
<a href="API.ru.html#section-3"
>Раздел II. Обратная совместимость</a
>
<li>
<h4><a href="API.ru.html#section-3">Раздел II. Обратная совместимость</a></h4>
<ul>
<li>
<a href="API.ru.html#chapter-13"
>Глава 13. Постановка проблемы обратной
совместимости</a
>
</li>
<li>
<a href="API.ru.html#chapter-14"
>Глава 14. О ватерлинии айсберга</a
>
</li>
<li>
<a href="API.ru.html#chapter-15"
>Глава 15. Расширение через абстрагирование</a
>
</li>
<li>
<a href="API.ru.html#chapter-16"
>Глава 16. Сильная связность и сопутствующие
проблемы</a
>
</li>
<li>
<a href="API.ru.html#chapter-17"
>Глава 17. Слабая связность</a
>
</li>
<li>
<a href="API.ru.html#chapter-18"
>Глава 18. Интерфейсы как универсальный паттерн</a
>
</li>
<li>
<a href="API.ru.html#chapter-19"
>Глава 19. Блокнот душевного покоя</a
>
</li>
</ul>
<li><a href="API.ru.html#chapter-13">Глава 13. Постановка проблемы обратной совместимости</a></li>
<li><a href="API.ru.html#chapter-14">Глава 14. О ватерлинии айсберга</a></li>
<li><a href="API.ru.html#chapter-15">Глава 15. Расширение через абстрагирование</a></li>
<li><a href="API.ru.html#chapter-16">Глава 16. Сильная связность и сопутствующие проблемы</a></li>
<li><a href="API.ru.html#chapter-17">Глава 17. Слабая связность</a></li>
<li><a href="API.ru.html#chapter-18">Глава 18. Интерфейсы как универсальный паттерн</a></li>
<li><a href="API.ru.html#chapter-19">Глава 19. Блокнот душевного покоя</a></li>
</ul>
</li>
<li>
Раздел III. API как продукт
<li>
<h4>Часть III. API как продукт</h4>
<ul>
<li>Глава 20. Продукт API</li>
<li>Глава 21. Бизнес-модели API</li>
<li>Глава 22. Формирование продуктового видения</li>
<li>Глава 23. Взаимодействие с разработчиками</li>
<li>Глава 24. Взаимодействие с бизнес-аудиторией</li>
<li>Глава 25. Линейка сервисов API</li>
<li>Глава 26. Ключевые показатели эффективности API</li>
<li>Глава 27. Идентификация пользователей</li>
<li>Глава 28. Антифрод и информационная безопасность</li>
<li>Глава 29. Поддержка пользователей API</li>
<li>Глава 30. Документация</li>
<li>Глава 31. Тестовая среда</li>
<li>Глава 32. Управление ожиданиями</li>
</ul>
<li>Глава 21. Бизнес-модели API</li>
<li>Глава 22. Формирование продуктового видения</li>
<li>Глава 23. Взаимодействие с разработчиками</li>
<li>Глава 24. Взаимодействие с бизнес-аудиторией</li>
<li>Глава 25. Линейка сервисов API</li>
<li>Глава 26. Ключевые показатели эффективности API</li>
<li>Глава 27. Идентификация пользователей и борьба с фродом</li>
<li>Глава 28. Информационная безопасность</li>
<li>Глава 29. Поддержка пользователей</li>
<li>Глава 30. Документация</li>
<li>Глава 31. Тестовая среда</li>
<li>Глава 32. Управление ожиданиями</li>
</ul>
</li>
</ul>
<p>
Эта книга распространяется на условиях лицензии
<a href="https://creativecommons.org/licenses/by-nc/4.0/"
>Creative Commons Attribution-NonCommercial 4.0 International
licence</a
>. Исходный код доступен на
<a href="https://github.com/twirl/The-API-Book">Github</a>.
Иллюстрации и вдохновение:
<a href="https://www.instagram.com/art.mari.ka/">art.mari.ka</a>.
</p>
<p>
You might read ‘The API’ <a href="index.html">in English</a> as
well.
</p>
</body>
</html>
</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>
</body>
</html>

View File

@@ -5,7 +5,7 @@
"author": "Sergey Konstantinov <twirl-team@yandex.ru>",
"repository": "github.com:twirl/The-API-Book",
"devDependencies": {
"@twirl/book-builder": "0.0.11",
"@twirl/book-builder": "0.0.12",
"html-docx-js": "^0.3.1"
},
"scripts": {

View File

@@ -1,81 +0,0 @@
<div class="cover">
<h1>Sergey Konstantinov<br />The API</h1>
</div>
<div class="page-break" />
<div class="annotation">
<p>
<strong>Sergey Konstantinov. The API.</strong><br />
<a href="mailto:twirl-team@yandex.ru">twirl-team@yandex.ru</a>
&nbsp;&middot;
<a href="https://www.linkedin.com/in/twirl/"
>www.linkedin.com/in/twirl/</a
>
&nbsp;&middot;
<a href="https://www.patreon.com/yatwirl">www.patreon.com/yatwirl</a>
</p>
<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>
The 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>
Illustrations by Maria Konstantinova<br /><a
href="https://www.instagram.com/art.mari.ka/"
>www.instagram.com/art.mari.ka/</a
>
</p>
<img
class="cc-by-nc-img"
src="https://i.creativecommons.org/l/by-nc/4.0/88x31.png"
/>
<p class="cc-by-nc">
This work is licensed under a
<a href="http://creativecommons.org/licenses/by-nc/4.0/"
>Creative Commons Attribution-NonCommercial 4.0 International
License</a
>.
</p>
<p>
Source codes are available on
<a href="https://github.com/twirl/The-API-Book">GitHub</a>
</p>
</div>
<a
href="https://github.com/twirl/The-API-Book/"
class="github-corner"
aria-label="View source on GitHub"
><svg
width="80"
height="80"
viewBox="0 0 250 250"
style="
fill: #151513;
color: #fff;
position: absolute;
top: 0;
border: 0;
right: 0;
"
aria-hidden="true"
>
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
fill="currentColor"
style="transform-origin: 130px 106px"
class="octo-arm"
></path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor"
class="octo-body"
></path></svg
></a>

View File

@@ -1,16 +1,16 @@
### Identifying Users and Fraud Prevention
### Identifying Users and Preventing Fraud
In the context of working with an API, we talk about two kinds of users of the system:
* users-developers, e.g. your partners writing code atop of the API;
* end users that will interact with applications implemented by the users-developers.
* end users interacting with applications implemented by the users-developers.
In most cases, you need to have both of them identified (in a technical sense: discern one unique visitor from another) to have answers to the following questions:
* how many users are interacting with the system (simultaneously, daily, monthly, and yearly);
* how many actions does each user make.
**NB**. Sometimes, when an API is very large and/or abstract, the chain linking the API provider to end users might comprise more than one developer as large partners are providing services implemented atop of the API to the smaller ones. You need to count both direct and ‘derivative’ partners.
**NB**. Sometimes, when an API is very large and/or abstract, the chain linking the API vendor to end users might comprise more than one developer as large partners provide services implemented atop of the API to the smaller ones. You need to count both direct and ‘derivative’ partners.
Gathering this data is crucial because of two reasons:
@@ -23,7 +23,7 @@ In the case of commercial APIs, the quality and timeliness of gathering this dat
Let's start with the first user category, e.g. API business partners-developers. The important remark: there are two different entities we must learn to identify, namely applications and their owners.
An application is roughly speaking a logically separate case of API usage, usually — literally an application (mobile or desktop one) or a website, e.g. some technical entity. Meanwhile, an owner is an entity which you have the API usage agreement signed with, e.g. a legal body. if API tariffs imply some limits and/or tariffs depend on the type of the service or the way it uses the API, this automatically means the necessity to track one owner's applications separately.
An application is roughly speaking a logically separate case of API usage, usually — literally an application (mobile or desktop one) or a website, e.g. some technical entity. Meanwhile, an owner is a legal body that you have the API usage agreement signed with, e.g. a legal body. if API tariffs imply some limits and/or tariffs depend on the type of the service or the way it uses the API, this automatically means the necessity to track one owner's applications separately.
In the modern world, the factual standard for identifying both entities is using API keys: a developer who wants to start using an API must obtain an API key bound to their contact info. Thus the key identifies the application while the contact data identifies the owner.
@@ -37,7 +37,7 @@ If there are free limits to the API usage, there is a temptation to obtain many
Another problem is that an API key might be simply stolen from a lawful partner; in the case of client or web applications, that's quite trivial.
It might look like the problem is not that important in the case of server-to-server integrations, but it actually is. Imagine that a partner provides a public service of their own that uses your API under the hood. That usually means there is an endpoint in the partner's backend that performs a request to the API and returns the result, and this endpoint perfectly suits as a free replacement of the API access to a cybercriminal. Of course, you might say this fraud is a problem of partners', but, first, it would be naïve to expect each partner develops their own anti-fraud system, and, second, just ineffective: obviously, a centralized anti-fraud system would be way more effective than a bunch of amateur implementations. Also, server keys might also be stolen: it's much harder than stealing client keys but doable. With any popular API, sooner or later you will face the situation of stolen keys made available to the public (or a key owner just shares it with acquaintances out of the kindness of their heart).
It might look like the problem is not that important in the case of server-to-server integrations, but it actually is. Imagine that a partner provides a public service of their own that uses your API under the hood. That usually means there is an endpoint in the partner's backend that performs a request to the API and returns the result, and this endpoint perfectly suits as a free replacement of the API access to a cybercriminal. Of course, you might say this fraud is a problem of partners', but, first, it would be naïve to expect each partner develops their own anti-fraud system, and, second, it's just sub-optimal: obviously, a centralized anti-fraud system would be way more effective than a bunch of amateur implementations. Also, server keys might also be stolen: it's much harder than stealing client keys but doable. With any popular API, sooner or later you will face the situation of stolen keys made available to the public (or a key owner just shares it with acquaintances out of the kindness of their heart).
One way or another, a problem of independent validation arises: how can we control whether the API endpoint is requested by a user in compliance with the terms of service?
@@ -51,11 +51,11 @@ The general conclusion is:
* it is highly desirable to have partners formally identified (either through obtaining API keys or by providing contact data such as website domain or application identifier in a store while initializing the API);
* this information shall not be trusted unconditionally; there must be double-checking mechanisms that identify the suspicious requests.
#### Identifying end users
#### Identifying end users
Usually, you can put forward some requirements for self-identifying of partners, but asking end users to reveal contact information is impossible in the most cases. All the methods of measuring the audience described below are imprecise and often heuristic. (Even if partner application functionality is only available after registration and you do have access to that profile data, it's still a game of assumptions, as an individual account is not the same as an individual user: several different persons might use a single account, or, vice versa, one person might register many accounts.) Also, note that gathering this sort of data might be legally regulated (though we will be mostly speaking about anonymized data, there might still be some applicable law).
Usually, you can put forward some requirements for self-identifying of partners, but asking end users to reveal contact information is impossible in the most cases. All the methods of measuring the audience described below are imprecise and often heuristic. (Even if partner application functionality is only available after registration and you do have access to that profile data, it's still a game of assumptions, as an individual account is not the same as an individual user: several different persons might use a single account, or, vice versa, one person might register many accounts.) Also, note that gathering this sort of data might be legally regulated (though we will be mostly speaking about anonymized data, there might still be some applicable law).
1. The most simple and obvious indicator is an IP address. It's very hard to counterfeit them (e.g. the API server always knows the remote address), and the IP address statistics are reasonably demonstrative.
1. The most simple and obvious indicator is an IP address. It's very hard to counterfeit them (e.g. the API server always knows the remote address), and the IP address statistics are reasonably demonstrative.
If the API is provided as a server-to-server one, there will be no access to the end user's IP address. However, it makes sense to require partners to propagate the IP address (for example, in a form of the `X-Forwarder-For` header) — among other things, to help partners fight fraud and unintended usage of the API.
@@ -68,4 +68,4 @@ The general conclusion is:
2. Additional means of tracking are users' unique identifiers, most notably cookies. However, most recently this method of gathering data is under attack from several sides: browser makers restrict third-party cookies, users are employing anti-tracker software, and lawmakers started to roll out legal requirements against data collection. In the current situation, it's much easier to drop cookie usage than to be compliant with all the regulations.
All this leads to a situation when public APIs (especially those installed on free-to-use sites and applications) are very limited in the means of collecting the statistics and analyzing user behavior. And that impacts not only fighting all kinds of fraud but analyzing use cases as well. That's the way.
All this leads to a situation when public APIs (especially those installed on free-to-use sites and applications) are very limited in the means of collecting the statistics and analyzing user behavior. And that impacts not only fighting all kinds of fraud but analyzing use cases as well. That's the way.

View File

@@ -3,10 +3,83 @@
"author": "Sergey Konstantinov",
"chapter": "Chapter",
"toc": "Table of Contents",
"frontPage": "Front Page",
"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",
"url": "https://twirl.github.io/The-API-Book/docs/API.en.html",
"imageCredit": "Image Credit"
"landingFile": "index.html",
"url": "https://twirl.github.io/The-API-Book/",
"favicon": "/img/favicon.png",
"imageCredit": "Image Credit",
"links": {
"email": "yatwirl@gmail.com",
"emailString": "yatwirl@gmail.com",
"linkedinHref": "https://www.linkedin.com/in/twirl/",
"linkedinString": "linkedin.com/in/twirl",
"patreonHref": "https://www.patreon.com/yatwirl",
"patreonString": "patreon.com/yatwirl",
"patreonTag": "Patreon",
"githubHref": "https://github.com/twirl/The-API-Book",
"githubString": "github.com/twirl/The-API-Book",
"twitterHref": "https://twitter.com/blogovodoved",
"kindleHref": "https://www.amazon.com/gp/product/B09RHH44S5/ref=dbs_a_def_rwt_hsch_vapi_tkin_p1_i0",
"kindleTag": "buy Kindle version",
"mediumHref": "https://twirl.medium.com/",
"mediumTag": "Medium"
},
"sourceCodeAt": "Source code available at",
"frontPage": {
"title": "The API",
"pageTitle": "Front Page",
"contents": [
"<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>Illustrations &amp; inspiration by Maria Konstantinova &middot; <a href=\"https://www.instagram.com/art.mari.ka/\">art.mari.ka</a></p>",
"<img class=\"cc-by-nc-img\" alt=\"Creative Commons «Attribution-NonCommercial» Logo\" src=\"https://i.creativecommons.org/l/by-nc/4.0/88x31.png\"/>",
"<p class=\"cc-by-nc\">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>"
]
},
"landing": {
"subTitle": "Free e-book",
"subscribeOn": "Subscribe for updates on",
"updates": ["github"],
"followOn": "Follow me on",
"follow": ["linkedin", "twitter", "medium"],
"supportThisWork": "Support this work on",
"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>"
],
"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>"
]
},
"contents": [
{ "chapters": ["", "", "", "", "", ""] },
{ "chapters": ["", "", "", "", "", ""] },
{ "chapters": ["", "", "", "", "", "", ""] },
{
"title": "Section III. The API Product",
"chapters": [
"API as a Product",
"API Business Models",
"Developing a Product Vision",
"Communicating with Developers",
"Communicating with Business Owners",
"API Services Range",
"API Key Performance Indicators",
"Identifying Users and Preventing Fraud",
"IT-security",
"Supporting API users",
"Documentation",
"Testing Environment",
"Managing Expectations"
]
}
]
}

BIN
src/img/favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -1,81 +0,0 @@
<div class="cover">
<h1>Сергей Константинов<br />API</h1>
</div>
<div class="page-break" />
<div class="annotation">
<p>
<strong>Сергей Константинов. API.</strong><br />
<a href="mailto:twirl-team@yandex.ru">twirl-team@yandex.ru</a>
&nbsp;&middot;
<a href="https://www.linkedin.com/in/twirl/"
>www.linkedin.com/in/twirl/</a
>
&nbsp;&middot;
<a href="https://www.patreon.com/yatwirl">www.patreon.com/yatwirl</a>
</p>
<p>
«API-first» подход — одна из самых горячих горячих тем в разработке
программного обеспечения в наше время. Многие компании начали понимать,
что API выступает мультипликатором их возможностей — но также умножает и
допущенные ошибки.
</p>
<p>
Эта книга посвящена проектированию API: как правильно выстроить
архитектуру, начиная с высокоуровневого планирования и заканчивая
деталями реализации конкретных интерфейсов, и как развивать API, не
нарушая обратную совместимость.
</p>
<p>
Иллюстрации: Мария Константинова<br /><a
href="https://www.instagram.com/art.mari.ka/"
>www.instagram.com/art.mari.ka/</a
>
</p>
<img
class="cc-by-nc-img"
src="https://i.creativecommons.org/l/by-nc/4.0/88x31.png"
/>
<p class="cc-by-nc">
Это произведение доступно по
<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</a>
</p>
</div>
<a
href="https://github.com/twirl/The-API-Book/"
class="github-corner"
aria-label="Посмотреть исходные материалы на GitHub"
><svg
width="80"
height="80"
viewBox="0 0 250 250"
style="
fill: #151513;
color: #fff;
position: absolute;
top: 0;
border: 0;
right: 0;
"
aria-hidden="true"
>
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
<path
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
fill="currentColor"
style="transform-origin: 130px 106px"
class="octo-arm"
></path>
<path
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
fill="currentColor"
class="octo-body"
></path></svg
></a>

View File

@@ -10,7 +10,7 @@
* сколько пользователей взаимодействуют с системой (одновременно, в течение дня, месяца, года);
* какое количество действий совершает каждый пользователь.
**NB**. Иногда, в случае больших и/или абстрактных API цепочка между вашим API и финальным пользователем может содержать более одного разработчика, т.е. крупные партнёры предоставляют сервис, разработанный поверх API, более мелким. Считать нужно иметь и прямых партнёров, и «производных».
**NB**. Иногда, в случае больших и/или абстрактных API цепочка между вашим API и финальным пользователем может содержать более одного разработчика, т.е. крупные партнёры предоставляют сервис, разработанный поверх API, более мелким. Считать нужно уметь и прямых партнёров, и «производных».
Обладать этой информацией критически важно по двум основным причинам:
@@ -57,15 +57,16 @@
1. Самый простой и очевидный показатель — это ip-адреса; их невозможно подделать (в том смысле, что сервер API всегда знает адрес вызывающего клиента), и поэтому статистика по уникальным ip довольно показательна.
Если API предоставляется как server-to-server сервис, доступа к IP-адресу конечного пользователя может и не быть, однако весьма разумно в такой ситуации требовать от партнёра пробрасывать IP-адрес клиента (например, в виде заголовка X-Forwarded-For) — в том числе для того, чтобы помочь партнёрам бороться с фродом и неправомерным использованием API.
Если API предоставляется как server-to-server сервис, доступа к IP-адресу конечного пользователя может и не быть, однако весьма разумно в такой ситуации требовать от партнёра пробрасывать IP-адрес клиента (например, в виде заголовка X-Forwarded-For) — в том числе для того, чтобы помочь партнёрам бороться с фродом и неправомерным использованием API.
До недавнего времени ip-адрес как единица подсчёта статистики был ещё и удобен тем, что обзавестись большим пулом уникальных адресов было достаточно дорого. Однако с распространением ipv6 это ограничение перестало быть актуальным; скорее, ipv6 ярко подсветил тот факт, что не стоит ограничиваться только подсчётом уникальных ip. Необходимо следить за несколькими агрегатами:
До недавнего времени ip-адрес как единица подсчёта статистики был ещё и удобен тем, что обзавестись большим пулом уникальных адресов было достаточно дорого. Однако с распространением ipv6 это ограничение перестало быть актуальным; скорее, ipv6 ярко подсветил тот факт, что не стоит ограничиваться только подсчётом уникальных ip. Необходимо следить за несколькими агрегатами:
* суммировать статистику по подсетям, т.е. вести иерархические подсчёты (количество уникальных сетей /8, /16, /24 и так далее);
* наблюдать за агрегированной статистикой по автономным сетям (autonomous networks, AS);
* мониторить использование известных публичных прокси и TOR Network.
Необычно высокое количество запросов из одной подсети может свидетельствовать о том, что API активно используется во внутрикорпоративной сети (или в данном регионе доступ в Интернет в основном предоставляется через NAT).
Необычно высокое количество запросов из одной подсети может свидетельствовать о том, что API активно используется во внутрикорпоративной сети (или в данном регионе доступ в Интернет в основном предоставляется через NAT).
2. Дополнительным способом идентификации служат уникальные идентификаторы пользователей, в первую очередь — cookie. Однако в последние годы этот способ ведения статистики подвергается атаке с нескольких сторон: производители браузеров ограничивают возможности установки cookie третьей стороной, пользователи активно защищаются от слежения, и законодатели начали выдвигать требования в отношении сбора данных. В рамках текущего законодательства проще отказаться от использования cookie, чем соблюсти все необходимые требования.
Всё это приводит к тому, что публичным API, особенно используемым в бесплатных сайтах и приложениях, очень тяжело вести статистику, а значит и тяжело анализировать поведение пользователей. И речь здесь не только о борьбе с разного рода фродом, но и банальном анализе сценариев использования API. Таков путь.
Всё это приводит к тому, что публичным API, особенно используемым в бесплатных сайтах и приложениях, очень тяжело вести статистику, а значит и тяжело анализировать поведение пользователей. И речь здесь не только о борьбе с разного рода фродом, но и банальном анализе сценариев использования API. Таков путь.

View File

@@ -1,12 +1,80 @@
{
"title": "API",
"title": "The API",
"author": "Сергей Константинов",
"chapter": "Глава",
"toc": "Содержание",
"frontPage": "Титульный лист",
"description": "Разработка API — особый навык: API является как мультипликатором ваших возможностей, так и мультипликатором ваших ошибок. Эта книга написана для того, чтобы поделиться опытом и изложить лучшие практики проектирования API. Книга состоит из двух больших разделов. В первом разделе мы поговорим о проектировании API на стадии разработки концепции — как грамотно выстроить архитектуру, от крупноблочного планирования до конечных интерфейсов. Второй раздел посвящён развитию существующих API с сохранением обратной совместимости",
"locale": "ru_RU",
"file": "API",
"url": "https://twirl.github.io/The-API-Book/docs/API.ru.html",
"imageCredit": "Image Credit"
"landingFile": "index.ru.html",
"url": "https://twirl.github.io/The-API-Book/index.ru.html",
"favicon": "/img/favicon.png",
"imageCredit": "Image Credit",
"links": {
"email": "yatwirl@gmail.com",
"emailString": "yatwirl@gmail.com",
"linkedinHref": "https://www.linkedin.com/in/twirl/",
"linkedinString": "linkedin.com/in/twirl",
"patreonHref": "https://www.patreon.com/yatwirl",
"patreonString": "patreon.com/yatwirl",
"patreonTag": "Patreon",
"githubHref": "https://github.com/twirl/The-API-Book",
"githubString": "github.com/twirl/The-API-Book",
"habrHref": "https://habr.com/ru/users/forgotten/posts/",
"habrTag": "Хабре"
},
"sourceCodeAt": "Исходный код доступен на",
"frontPage": {
"title": "The API",
"pageTitle": "Титульный лист",
"contents": [
"<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>",
"<img class=\"cc-by-nc-img\" alt=\"Creative Commons «Attribution-NonCommercial» Logo\" src=\"https://i.creativecommons.org/l/by-nc/4.0/88x31.png\"/>",
"<p class=\"cc-by-nc\">Это произведение доступно по <a href=\"http://creativecommons.org/licenses/by-nc/4.0/\">лицензии Creative Commons «Attribution-NonCommercial» («Атрибуция — Некоммерческое использование») 4.0 Всемирная</a>.</p>"
]
},
"landing": {
"subTitle": "Бесплатная электронная книга",
"subscribeOn": "Подпишитесь на обновления на",
"updates": ["habr"],
"supportThisWork": "Поддержите эту работу на",
"support": ["patreon"],
"content": [
"<p>«API-first» подход — одна из самых горячих горячих тем в разработке программного обеспечения в наше время. Многие компании начали понимать, что API выступает мультипликатором их возможностей — но также умножает и допущенные ошибки.</p>",
"<p>Эта книга посвящена проектированию API: как правильно выстроить архитектуру, начиная с высокоуровневого планирования и заканчивая деталями реализации конкретных интерфейсов, и как развивать API, не нарушая обратную совместимость.</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>"
]
},
"contents": [
{ "chapters": ["", "", "", "", "", ""] },
{ "chapters": ["", "", "", "", "", ""] },
{ "chapters": ["", "", "", "", "", "", ""] },
{
"title": "Часть III. API как продукт",
"chapters": [
"Продукт API",
"Бизнес-модели API",
"Формирование продуктового видения",
"Взаимодействие с разработчиками",
"Взаимодействие с бизнес-аудиторией",
"Линейка сервисов API",
"Ключевые показатели эффективности API",
"Идентификация пользователей и борьба с фродом",
"Информационная безопасность",
"Поддержка пользователей",
"Документация",
"Тестовая среда",
"Управление ожиданиями"
]
}
]
}

View File

@@ -1,3 +1,277 @@
const templates = (module.exports = {
pageBreak: '<div class="page-break"></div>'
pageBreak: '<div class="page-break"></div>',
frontPage: (l10n) => `
<div class="cover">
<h1>
<span class="author">${l10n.author}</span><br /><span class="title"
>${l10n.frontPage.title}</span
>
</h1>
</div><div class="page-break"></div><div class="annotation"><p>
<strong>${l10n.author}. ${l10n.title}.</strong><br />
<a target="_blank" href="mailto:${l10n.links.email}">${
l10n.links.emailString
}</a> &middot; <a target="_blank" href="${l10n.links.linkedinHref}">${
l10n.links.linkedinString
}</a> &middot; <a target="_blank" href="${l10n.links.patreonHref}">${
l10n.links.patreonString
}</a></p>
${l10n.frontPage.contents.join('\n')}
<p>${l10n.sourceCodeAt} <a target="_blank" href="${
l10n.links.githubHref
}">${l10n.links.githubString}</a></p>
</div><div class="page-break"></div>`,
landing: (structure, l10n, lang) => {
const link = (anchor, type = 'html') =>
`${encodeURIComponent(l10n.file)}.${lang}.${type}${
anchor ? '#' + anchor : ''
}`;
let chapterCounter = 0;
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/jpg" href="assets/favicon.jpg" />
<title>
${l10n.author}. ${l10n.title}
</title>
<meta
name="description"
content="${l10n.description}"
/>
<meta property="og:type" content="article" />
<meta
property="og:title"
content="${l10n.author}. ${l10n.title}"
/>
<meta
property="og:description"
content="${l10n.description}"
/>
<meta property="og:image" content="assets/header.png" />
<meta
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>
</head>
<body>
<nav>
<img
src="assets/header.jpg"
alt="${l10n.author}. ${l10n.title}"
/><br />
<h1>${l10n.author}<br/><span class="title">${l10n.title}</span></h1>
<h2>${l10n.landing.subTitle}</h2>
<br />${l10n.landing.subscribeOn} ${l10n.landing.updates
.map(
(source) =>
`<a class="${source}" href="${
l10n.links[source + 'Href']
}">${l10n.links[source + 'Tag'] || ''}</a>`
)
.join(' &middot; ')}
${
l10n.landing.follow && l10n.landing.follow.length
? `<br/>${l10n.landing.followOn} ${l10n.landing.follow
.map(
(source) =>
`<a class="${source}" href="${
l10n.links[source + 'Href']
}">${l10n.links[source + 'Tag'] || ''}</a>`
)
.join(' &middot; ')}`
: ''
}
<br />${l10n.landing.supportThisWork} ${l10n.landing.support
.map(
(source) =>
`<a class="${source}" href="${
l10n.links[source + 'Href']
}">${l10n.links[source + 'Tag'] || ''}</a>`
)
.join(' &middot; ')}
<br />⚙️⚙️⚙️
</nav>
${l10n.landing.content.join('\n')}
<p>${l10n.landing.download} <a href="${link(
null,
'pdf'
)}">PDF</a>, <a href="${link(null, 'epub')}">EPUB</a>, ${
l10n.landing.or
} <a href="${link()}">${l10n.landing.readOnline}</a>.
</p>
<h3>${l10n.toc}</h3>
<ul>${l10n.contents
.map((section, i) => {
const written = structure.sections[i];
return `<li>
<h4>${
written
? `<a href="${link(written.anchor)}">${
written.title
}</a>`
: `${section.title}`
}</h4>
${
section.chapters.length
? `<ul>
${section.chapters
.map((chapter, j) => {
const writtenChapter =
written && written.chapters[j];
chapterCounter++;
return writtenChapter
? `<li><a href="${link(
writtenChapter.anchor
)}">${writtenChapter.title}</a></li>`
: `<li>${l10n.chapter} ${chapterCounter}. ${chapter}</li>`;
})
.join('\n')}
</ul>`
: ''
}
</li>`;
})
.join('\n')}
</ul>
<p>${l10n.landing.license}</p>
<p>${l10n.sourceCodeAt} <a href="${l10n.links.githubHref}">${
l10n.links.githubString
}</a></p>
${l10n.landing.footer.join('\n')}
</body>
</html>`;
}
});