diff --git a/src/en/clean-copy/02-Section I. The API Design/04.md b/src/en/clean-copy/02-Section I. The API Design/04.md index c62cd7e..b441ab4 100644 --- a/src/en/clean-copy/02-Section I. The API Design/04.md +++ b/src/en/clean-copy/02-Section I. The API Design/04.md @@ -111,6 +111,8 @@ Here: **NB**. We could have enriched the existing `/coffee-machines` endpoint instead of adding a new one. This decision, however, looks less semantically viable: coupling in one interface different modes of listing entities, by relevance and by order, is usually a bad idea because these two types of rankings imply different usage features and scenarios. Furthermore, enriching the search with “offers” pulls this functionality out of the `coffee-machines` namespace: the fact of getting offers to prepare specific beverages in specific conditions is a key feature to users, with specifying the coffee machine being just a part of an offer. And users actually rarely care about coffee machine models. +**NB**. Actually, having `coffee_machine_id` in the interface is at some extent violating the abstraction separation principle. It should be organized in a more complex way: coffee shops shall somehow map the incoming orders against available coffee machines, and only the type of the coffee machine (if a coffee shop really operates several of them) is something meaningful in the context of the order creation. However, we make it deliberately simplified by making coffee machine selectable in the API to keep our API example readable enough. + Coming back to the code developers are writing, it would now look like that: ``` diff --git a/src/en/clean-copy/03-Section II. The Backwards Compatibility/03.md b/src/en/clean-copy/03-Section II. The Backwards Compatibility/03.md index 0a75b4f..30005f8 100644 --- a/src/en/clean-copy/03-Section II. The Backwards Compatibility/03.md +++ b/src/en/clean-copy/03-Section II. The Backwards Compatibility/03.md @@ -1,9 +1,8 @@ ### Extending through Abstracting -In previous chapters, we have tried to outline theoretical rules and illustrate them with practical examples. However, understanding the principles of change-proof API design requires practice above all things. An ability to anticipate future growth problems comes from a handful of grave mistakes once made. One cannot foresee everything but can develop certain technical intuition. - -So in the following chapters, we will try to probe [our study API](#chapter-12) from the previous Section, testing its robustness from every possible viewpoint, thus carrying out some “variational analysis” of our interfaces. More specifically, we will apply a “What If?” question to every entity, as if we are to provide a possibility to write an alternate implementation of every piece of logic. +In the previous chapters, we have tried to outline theoretical rules and illustrate them with practical examples. However, understanding the principles of the change-proof API design requires practice above all things. An ability to anticipate future growth problems comes from a handful of grave mistakes once made. One cannot foresee everything but can develop a certain technical intuition. +So, in the following chapters, we will try to probe [our study API](#chapter-12) from the previous Section, testing its robustness from every possible viewpoint, thus carrying out some “variational analysis” of our interfaces. More specifically, we will apply a “What If?” question to every entity, as if we are to provide a possibility to write an alternate implementation of every piece of logic. **NB**. In our examples, the interfaces will be constructed in a manner allowing for dynamic real-time linking of different entities. In practice, such integrations usually imply writing an ad hoc server-side code in accordance with specific agreements made with specific partners. But for educational purposes, we will pursue more abstract and complicated ways. Dynamic real-time linking is more typical in complex program constructs like operating system APIs or embeddable libraries; giving educational examples based on such sophisticated systems would be too inconvenient. diff --git a/src/ru/clean-copy/02-Раздел I. Проектирование API/04.md b/src/ru/clean-copy/02-Раздел I. Проектирование API/04.md index bb5f08f..02ad76b 100644 --- a/src/ru/clean-copy/02-Раздел I. Проектирование API/04.md +++ b/src/ru/clean-copy/02-Раздел I. Проектирование API/04.md @@ -105,6 +105,8 @@ POST /v1/offers/search **NB**. Мы могли бы не добавлять новый эндпойнт, а обогатить существующий `/coffee-machines`. Однако такое решение выглядит менее семантично: не стоит в рамках одного интерфейса смешивать способ перечисления объектов по порядку и по релевантности запросу, поскольку эти два вида ранжирования обладают существенно разными свойствами и сценариями использования. К тому же, обогащение поиска «предложениями» скорее выводит эту функциональность из неймспейса «кофемашины»: для пользователя всё-таки первичен факт получения предложения приготовить напиток на конкретных условиях, и кофемашина — лишь одно из них, не самое важное. +**NB**. На самом деле, наличие идентификатора кофе-машины в интерфейсах само по себе нарушает принцип изоляции уровней абстракции. Эа функциональность должна быть организована более сложно: кофейни должны распределять поступающие заказы по свободным кофемашинам, и только тип кофемашины (если кофейня оперирует несколькими одновременно) является значимой частью предложения. Мы сознательно допускаем это упрощение (пользователь сам выбирает кофемашину), чтобы не перегружать наш учебный пример. + Вернёмся к коду, который напишет разработчик. Теперь он будет выглядеть примерно так: ``` // Ищем предложения,