haveapi 0.32.1 → 0.32.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -8
  3. data/README.md +3 -422
  4. data/Rakefile +17 -7
  5. data/benchmarks/performance_compare.rb +27 -6
  6. data/doc/cs/client-examples.md +535 -0
  7. data/doc/cs/create-client.md +118 -0
  8. data/doc/cs/json-schema.html +1182 -0
  9. data/doc/cs/protocol.md +595 -0
  10. data/doc/cs/readme.md +432 -0
  11. data/doc/cs/typed-input-validation.md +122 -0
  12. data/doc/{client-examples.md → en/client-examples.md} +20 -10
  13. data/doc/{documentation-ui.md → en/documentation-ui.md} +42 -6
  14. data/doc/{performance.md → en/performance.md} +11 -0
  15. data/doc/{protocol.md → en/protocol.md} +2 -2
  16. data/doc/en/readme.md +423 -0
  17. data/haveapi.gemspec +2 -2
  18. data/lib/haveapi/client_example.rb +18 -5
  19. data/lib/haveapi/client_examples/curl.rb +5 -5
  20. data/lib/haveapi/client_examples/dynamic_helpers.rb +10 -10
  21. data/lib/haveapi/client_examples/go_client.rb +1 -1
  22. data/lib/haveapi/client_examples/http.rb +4 -4
  23. data/lib/haveapi/client_examples/js_client.rb +10 -10
  24. data/lib/haveapi/client_examples/php_client.rb +24 -25
  25. data/lib/haveapi/client_examples/python_client.rb +11 -11
  26. data/lib/haveapi/client_examples/ruby_cli.rb +6 -9
  27. data/lib/haveapi/client_examples/ruby_client.rb +24 -16
  28. data/lib/haveapi/client_examples/rust_client.rb +1 -1
  29. data/lib/haveapi/client_examples/ts_generated_client.rb +1 -1
  30. data/lib/haveapi/documentation_context.rb +14 -2
  31. data/lib/haveapi/documentation_helpers.rb +92 -15
  32. data/lib/haveapi/documentation_locale.rb +65 -0
  33. data/lib/haveapi/documentation_oauth.rb +12 -12
  34. data/lib/haveapi/documentation_search.rb +5 -5
  35. data/lib/haveapi/documentation_validators.rb +43 -33
  36. data/lib/haveapi/locales/cs.yml +468 -0
  37. data/lib/haveapi/locales/en.yml +467 -0
  38. data/lib/haveapi/public/css/documentation.css +8 -4
  39. data/lib/haveapi/public/js/documentation.js +73 -20
  40. data/lib/haveapi/server.rb +32 -47
  41. data/lib/haveapi/shared_documentation_helpers.rb +53 -5
  42. data/lib/haveapi/version.rb +1 -1
  43. data/lib/haveapi/views/doc_layout.erb +3 -2
  44. data/lib/haveapi/views/doc_sidebars/create-client.erb +10 -10
  45. data/lib/haveapi/views/doc_sidebars/json-schema.erb +2 -2
  46. data/lib/haveapi/views/doc_sidebars/protocol.erb +24 -24
  47. data/lib/haveapi/views/documentation/search_form.erb +5 -4
  48. data/lib/haveapi/views/documentation/search_results.erb +6 -6
  49. data/lib/haveapi/views/index.erb +3 -3
  50. data/lib/haveapi/views/main_layout.erb +4 -4
  51. data/lib/haveapi/views/shared_documentation.erb +8 -5
  52. data/lib/haveapi/views/shared_sidebar.erb +11 -11
  53. data/lib/haveapi/views/version_page/auth_body.erb +7 -7
  54. data/lib/haveapi/views/version_page/client_auth.erb +1 -1
  55. data/lib/haveapi/views/version_page/client_example.erb +1 -1
  56. data/lib/haveapi/views/version_page/client_init.erb +1 -1
  57. data/lib/haveapi/views/version_page/client_overview.erb +7 -5
  58. data/lib/haveapi/views/version_page/example_panels.erb +5 -2
  59. data/lib/haveapi/views/version_page/resource_body.erb +24 -24
  60. data/lib/haveapi/views/version_page/resource_directory.erb +2 -2
  61. data/lib/haveapi/views/version_page/usage.erb +5 -5
  62. data/lib/haveapi/views/version_page.erb +11 -11
  63. data/lib/haveapi/views/version_sidebar/auth_nav.erb +2 -2
  64. data/lib/haveapi/views/version_sidebar/authentication_control.erb +8 -8
  65. data/lib/haveapi/views/version_sidebar/authentication_status.erb +1 -1
  66. data/lib/haveapi/views/version_sidebar/brand.erb +16 -5
  67. data/lib/haveapi/views/version_sidebar.erb +33 -18
  68. data/spec/client_examples/assets/documentation_test.cjs +107 -9
  69. data/spec/client_examples/comment_capture.rb +72 -0
  70. data/spec/client_examples/comments_spec.rb +162 -0
  71. data/spec/client_examples/context_spec.rb +18 -2
  72. data/spec/client_examples/detail_spec.rb +68 -0
  73. data/spec/documentation/client_overview_spec.rb +60 -0
  74. data/spec/documentation/example_selection_spec.rb +192 -0
  75. data/spec/documentation/language_settings_spec.rb +132 -0
  76. data/spec/documentation/locale_spec.rb +367 -0
  77. data/spec/documentation/navigation_spec.rb +61 -3
  78. data/spec/documentation/oauth_spec.rb +42 -0
  79. data/spec/documentation/search_index_routes_spec.rb +8 -4
  80. data/spec/documentation/search_spec.rb +1 -1
  81. data/spec/documentation/shared_pages_spec.rb +63 -2
  82. data/spec/documentation/validators_spec.rb +25 -0
  83. data/spec/extensions/exception_mailer_spec.rb +2 -2
  84. data/spec/packaging_spec.rb +68 -9
  85. data/spec/performance/event_baseline_spec.rb +1 -1
  86. data/spec/performance/source_versions_spec.rb +111 -2
  87. metadata +24 -11
  88. /data/doc/{create-client.md → en/create-client.md} +0 -0
  89. /data/doc/{documentation-oauth.md → en/documentation-oauth.md} +0 -0
  90. /data/doc/{json-schema.html → en/json-schema.html} +0 -0
  91. /data/doc/{typed-input-validation.md → en/typed-input-validation.md} +0 -0
@@ -0,0 +1,535 @@
1
+ <h1 id="client-examples-in-api-documentation">Klientské příklady v dokumentaci API</h1>
2
+
3
+ Přihlášení do dokumentace v prohlížeči popisuje [Přihlášení přes OAuth](../en/documentation-oauth.md).
4
+
5
+ Ruby server vykresluje příklady z popisu API dostupného aktuálnímu uživateli.
6
+ Příklady pro JavaScript a TypeScript zahrnují callbackové i asynchronní klienty;
7
+ Python zahrnuje synchronní i asynchronní klienty. Tyto klienty není potřeba
8
+ na serveru konfigurovat. Dostupné jsou také příklady pro Ruby, PHP, CLI, curl
9
+ a HTTP. Pokud klient nedokáže příklad vyjádřit, zobrazí omezení. Nevynechává
10
+ vstup ani nevytváří zdání úspěšného výsledku.
11
+
12
+ Výchozí příklady jsou **Jednoduché**. Příklady akcí předpokládají inicializované
13
+ a případně přihlášené `api`; inicializace a autentizace mají samostatné stránky.
14
+ Volba Příklady zůstává viditelná a nabízí **S ošetřením chyb**, pokud aktuální
15
+ stránka obsahuje pro daného klienta příklady s dodatečným ošetřením chyb.
16
+ Příklady bez odlišné podoby ošetření chyb zůstávají jednoduché. Obě úrovně
17
+ zachovávají stejné ukázkové hodnoty, argumenty cesty i sémantiku operací.
18
+ Samotná dodatečná příprava nevytváří další volbu; vestavěná omezení mají
19
+ jeden jednoduchý panel. Navigaci a ukládání nastavení zobrazení popisuje
20
+ [průvodce dokumentačním rozhraním](../en/documentation-ui.md).
21
+
22
+ Příklady používají zástupné přihlašovací údaje: `user` / `secret`,
23
+ `example-token` a `example-access-token`. Nahraď je hodnotami své aplikace.
24
+ Renderery používají tyto veřejné literály; nečtou přihlašovací údaje
25
+ z prostředí, aktuálního uživatele, nastavení profilu ani soukromých výchozích hodnot.
26
+
27
+ Vstupy přihlášení tokenem a dalších ověřovacích kroků používají názvy polí,
28
+ typy a konečné množiny strojově čitelných voleb z popisu dostupného danému
29
+ uživateli. Povinné vstupy zůstávají přítomné a doba platnosti je explicitně
30
+ pevně daná. Vlastní validace může vyžadovat jiné hodnoty; povinné pole,
31
+ které nelze vyjádřit, vede k zobrazení omezení. Názvy a vstupy dalších kroků
32
+ odpovídají zveřejněným akcím, zatímco běhová knihovna dodává a předává průběžné tokeny.
33
+
34
+ API klienti pro Go, Rust a TypeScript vyžadují nastavený profil. Verze jejich
35
+ balíčků jsou nezávislé na HaveAPI i na verzi API. Bez profilu server tyto
36
+ klienty nezobrazuje v přehledu ani v panelech příkladů. Při nastavování profilu
37
+ nainstaluj odpovídající gem generátoru; běžné servery na těchto generátorech nezávisí.
38
+
39
+ <h2 id="configure-an-api-client">Nastavení API klienta</h2>
40
+
41
+ Profily zaregistruj před připojením serveru pomocí mount. Pro API klienta,
42
+ který odpovídá aktuálnímu API, nastav identitu jeho balíčku:
43
+
44
+ ```ruby
45
+ api.documentation_clients('1.0',
46
+ go: {
47
+ import_path: 'example.org/widget/client'
48
+ },
49
+ rust: {
50
+ crate_name: 'widget-client'
51
+ },
52
+ typescript: {
53
+ package_name: '@example/widget-client'
54
+ }
55
+ )
56
+ api.mount('/api/')
57
+ ```
58
+
59
+ Výchozí `generator_version` je `HaveAPI::VERSION` serveru. Do Ruby prostředí
60
+ serveru nainstaluj odpovídající generátor: `haveapi-go-client`,
61
+ `haveapi-rust-client` nebo zdrojově distribuovaný `haveapi-typescript-client`.
62
+ Nastavení popisuje [průvodce generátorem TypeScriptu](../../clients/typescript/README.md).
63
+ Explicitní `generator_version` vyžaduje, aby nainstalovaný generátor hlásil
64
+ danou verzi; server žádný nestahuje. Tato verze je nezávislá na verzích API klienta i API.
65
+
66
+ Na konci mount server sestaví jeden soukromý strukturální model pro každou
67
+ nastavenou verzi API. Model zahrnuje autentizační zdroje, cesty a změny
68
+ z hooků po mount, takže kanonické názvy a argumenty rodičů vycházejí z celé
69
+ deklarace API. Soukromá kopie neobsahuje příklady, textové popisy ani výchozí
70
+ hodnoty parametrů. HTML požadavky používají popis, pole a příklady dostupné
71
+ aktuálnímu uživateli; nikdy nezpřístupňují soukromý model ani diagnostiku
72
+ jeho inicializace. Bez nastaveného profilu server nenačítá žádný volitelný
73
+ generátor a skrývá panely API klientů pro Go, Rust a TypeScript. Callbackové
74
+ a asynchronní příklady TypeScriptu zůstávají samostatné a profil nepotřebují.
75
+
76
+ Automatické profily předpokládají, že nainstalovaný API klient odpovídá
77
+ aktuálnímu kontraktu generování serveru. Název ani verze balíčku nedokládají
78
+ jeho obsah. Starší API klient může postrádat nové akce nebo po kolizi či změně
79
+ cesty používat jiné názvy. Před nabídnutím klienta ověř kompatibilitu;
80
+ pro starší nebo omezené API použij profil s uloženým schématem.
81
+
82
+ <h3 id="optional-api-client-versions-and-sources">Volitelné verze a zdroje API klientů</h3>
83
+
84
+ Pokud potřebuješ konkrétní verzi balíčku, nastav `module_version: 'v1.2.3'`
85
+ pro Go, `crate_version: '1.2.3'` pro Rust nebo `package_version: '1.2.3'`
86
+ pro TypeScript. Vynecháním pole nebo použitím nil necháš výběr vydání
87
+ na správci balíčků uživatele. Server se nedotazuje registru ani netvrdí,
88
+ že verzi vybral. Při vynechané verzi zobrazí tyto instalační příkazy:
89
+
90
+ ```sh
91
+ go get example.org/widget/client@latest
92
+ cargo add widget-client
93
+ # Blokující varianta Rustu:
94
+ cargo add widget-client --features blocking
95
+ npm install @example/widget-client haveapi-client@0.32.0
96
+ ```
97
+
98
+ Go vyhodnocuje `@latest` podle svých běžných pravidel. Cargo vybírá
99
+ kompatibilní vydání podle svého resolveru, manifestu a toolchainu; existující
100
+ lockfily zůstávají v platnosti. Explicitní verze pro Cargo jsou nadále
101
+ požadavky na verzi bez přidaného přesného připnutí pomocí `=`. Výběr
102
+ nejnovějšího vydání se může časem měnit; pokud ho chceš řídit, zadej verzi.
103
+ Cargo nikdy nedostává doslovné `version = "latest"`. Příklady pro Rust také
104
+ uvádějí požadavky na Tokio a serde_json.
105
+
106
+ TypeScript přijímá běžné názvy npm balíčků malými písmeny, včetně názvů se
107
+ scope, a volitelnou konkrétní verzi SemVer. Tagy, rozsahy verzí, Git URL,
108
+ lokální cesty ani vlastní tovární funkce nejsou volbami profilu. Nastav balíček,
109
+ který uživatelé mohou nainstalovat; server neověřuje jeho dostupnost ani ho
110
+ nepublikuje. Příklady TypeScriptu volají typované vlastnosti balíčku přes jeho
111
+ veřejný export `createClient`. Profil nezjišťuje ani nevybírá běhovou knihovnu
112
+ `haveapi-client` nainstalovanou v aplikaci. Instalační příkaz výše používá
113
+ verzi podporovanou [generátorem TypeScriptu](../../clients/typescript/README.md);
114
+ příklady ji neuvádějí jako nakonfigurovanou verzi běhové knihovny.
115
+
116
+ Pro nepublikovaného API klienta v Rustu zadej HTTPS Git URL a úplné SHA commitu:
117
+
118
+ ```ruby
119
+ api.documentation_clients('7.0',
120
+ rust: {
121
+ crate_name: 'vpsadmin-client',
122
+ source: {
123
+ git: 'https://github.com/vpsfreecz/vpsadmin-rust-client',
124
+ rev: 'ff876abe17e3301da62c1b6afbda055ec89db9d2'
125
+ }
126
+ }
127
+ )
128
+ ```
129
+
130
+ Doporučená závislost pak místo vydání z registru používá tento zdroj:
131
+
132
+ ```toml
133
+ # Cargo.toml
134
+ vpsadmin-client = { git = "https://github.com/vpsfreecz/vpsadmin-rust-client", rev = "ff876abe17e3301da62c1b6afbda055ec89db9d2" }
135
+ # Blokující varianta navíc nastavuje features = ["blocking"].
136
+ ```
137
+
138
+ `source` přijímá pouze `git` a `rev`. URL musí být absolutní HTTPS bez
139
+ přihlašovacích údajů, query stringu, fragmentů a řídicích znaků; revize musí
140
+ mít 40 hexadecimálních znaků. Větve, tagy, lokální cesty ani vlastní registry
141
+ nejsou podporované. Explicitní verze crate dále omezuje vybraný zdrojový
142
+ balíček. Server nikdy nestahuje repozitář ani nespouští tyto uživatelské
143
+ instalační příkazy. Nastavení nepřegeneruje ani nepublikuje API klienta
144
+ a nedokládá, že odpovídá konkrétnímu rozhraní API.
145
+
146
+ <h3 id="saved-schema-overrides">Profily s uloženým schématem</h3>
147
+
148
+ Stávající profily založené na souborech jsou nadále podporované:
149
+
150
+ ```ruby
151
+ api.documentation_clients('1.0',
152
+ go: {
153
+ import_path: 'example.org/widget/client',
154
+ module_version: 'v1.2.3',
155
+ description_path: '/srv/widget-sdk/api-1.0.json',
156
+ generator_version: '0.30.0'
157
+ },
158
+ rust: {
159
+ snapshot_path: '/srv/widget-sdk/api-1.0.snapshot.json',
160
+ generator_config_path: '/srv/widget-sdk/generator.toml',
161
+ generator_version: '0.30.0'
162
+ },
163
+ typescript: {
164
+ package_name: '@example/widget-client',
165
+ package_version: '1.2.3',
166
+ snapshot_path: '/srv/widget-sdk/api-1.0.snapshot.json',
167
+ generator_version: '0.30.0'
168
+ }
169
+ )
170
+ ```
171
+
172
+ Cesty označují důvěryhodné absolutní lokální soubory. `description_path`
173
+ je uložený strojově čitelný popis pro Go, nikoli HTML. U Rustu a TypeScriptu
174
+ vybírá `snapshot_path` uložené schéma a metadata jeho pořízení. Tyto soubory
175
+ určují přesnou podobu API klienta místo aktuální deklarace serveru. Uchovávej
176
+ je soukromě spolu s vydáním API klienta.
177
+
178
+ Starší volba Rustu `generator_config_path` poskytuje název a verzi crate
179
+ i úplnou konfiguraci balíčku. Nelze ji kombinovat s přímo zadanými `crate_name`
180
+ a `crate_version`; lze ji spojit s uloženým snapshotem i automatickým
181
+ schématem. Uložený snapshot může místo ní používat přímo zadanou identitu
182
+ crate. `source` funguje s oběma podobami identity. Server validuje celý starší
183
+ TOML; běžná dokumentace s přímým nastavením nepotřebuje volby licence,
184
+ kompilátoru ani formátovače.
185
+
186
+ Uložené soubory se načítají a validují při registraci. Automatické modely se
187
+ inicializují na konci mount. Chybějící soubory či generátory, skutečná neshoda
188
+ verze generátoru, neznámá pole, konfliktní identity a neplatná schémata způsobí
189
+ selhání startu. Mount odmítá také nedostupné verze API a neshodné verze snapshotů
190
+ Rustu a TypeScriptu. Při selhání mount se nezveřejní žádné profily a nezůstane
191
+ použitelná serverová aplikace. Starší explicitně připnutý generátor může
192
+ obsluhovat vhodný starší souborový profil, ale automatický režim Rustu
193
+ s přímým nastavením vyžaduje nové tovární rozhraní a neodhaduje náhradní řešení.
194
+
195
+ Uložený API klient může nadále poskytovat příklady po nesouvisejících rozšířeních
196
+ živého API. Každý příklad musí odpovídat uložené cestě, rozložení a kontraktům
197
+ předaných parametrů; nedostupné nebo zastaralé příklady zobrazí omezení.
198
+ Skryté akce, pole, výchozí hodnoty a příklady zůstávají pro aktuálního uživatele
199
+ skryté. Server při HTML požadavku nikdy nestahuje popisy, nepřegenerovává balíčky
200
+ ani nespouští kompilátor nebo formátovač.
201
+
202
+ Staré nastavení profilů funguje na novém serveru. Přímé nastavení vyžaduje
203
+ nový kód serveru; návrat ke staršímu kódu vyžaduje i obnovení kompatibilního
204
+ nastavení. Kombinace různých verzí serverových workerů může zobrazovat odlišné
205
+ příklady, aniž by se měnily přenášené požadavky nebo uložená data.
206
+
207
+ <h2 id="renderer-extensions">Rozšíření rendererů</h2>
208
+
209
+ Vysvětlující komentáře dodávané frameworkem se řídí jazykem dokumentace.
210
+ Spustitelný kód, identifikátory, literály, zakomentované příkazy a ukázková data
211
+ zůstávají beze změny. Neměnný kontext zachycuje `locale` s výchozí hodnotou `:en`
212
+ a zachovává ho při `with`. `example_comment(key, default:, **values)` vyhledává
213
+ `haveapi.documentation.comments.<key>`; `documentation_message` hledá ostatní
214
+ klíče pod `haveapi.documentation`, včetně omezení generovaných klientů.
215
+ Renderery přidávají značku komentáře ke každému fyzickému řádku textu.
216
+ Dokumentační adaptéry mohou tyto volitelné metody kontextu používat bez závislosti
217
+ na serverovém gemu; staré kontexty a přímá volání rendererů zachovávají anglické
218
+ výchozí texty.
219
+
220
+ Stávající poziční konstruktory rendererů a metody `init`, `auth(method, desc)`
221
+ a `example(sample)` nebo `request(sample)`/`response(sample)` nadále fungují.
222
+ Registr pomocí `with_context` připojuje `HaveAPI::ClientExample::Context`
223
+ platný pro daný požadavek. Obsahuje vybranou verzi, URL včetně mount cesty API,
224
+ filtrovaný popis a aktuální zdroj, akci a příklad. Jeho čtečka `detail` vrací
225
+ právě `:simple` nebo `:thorough`, výchozí je `:simple`. Konstruktor
226
+ i `context.with(detail: ...)` odmítají jiné hodnoty včetně řetězců a nil.
227
+ Změna podrobnosti sdílí již vlastněná data stejně jako jiné odvozené kontexty.
228
+ Pomocná metoda základního rendereru `thorough?` čte tuto hodnotu; starší instance
229
+ s pozičními argumenty používají jednoduchou podobu. Konstrukce kopíruje
230
+ a zmrazuje data Hash, Array a String, aniž by zmrazila kontejnery volajícího.
231
+ Každý požadavek vlastní svůj snapshot popisu. `context.with(...)` vytváří
232
+ samostatný zmrazený kontext, sdílí nezměněná pole identitou a normalizuje pouze
233
+ explicitně předaná pole. I mělce zmrazený vstupní kontejner se musí kopírovat;
234
+ explicitní předání již vlastněného Hash, Array nebo String jej také zkopíruje.
235
+ Renderery musí s daty vlastněnými kontextem pracovat pouze pro čtení.
236
+
237
+ Profil je sdílený odkaz; registrované profily a jejich adaptéry se zmrazují
238
+ samostatně. Ostatní typy objektů zachovávají dosavadní chování odkazů,
239
+ takže konstrukce kontextu neslibuje hluboké zmrazení libovolných objektů.
240
+ Podtřídy `Context` se nadále odvozují přes své konstruktory a zachovávají vlastní
241
+ inicializaci i další klíčová slova. Optimalizace sdílení platí pouze pro přesnou
242
+ základní třídu.
243
+
244
+ Renderery mohou ze stávajících metod vracet String nebo nil. Nové renderery
245
+ vracejí buď `{status: :code, code: source}`, nebo
246
+ `{status: :limitation, reason: text}`. Zdrojový text i text omezení jsou obyčejné
247
+ řetězce, které šablony jednou escapují. Stabilní třídní `id` označuje variantu;
248
+ `code` vybírá jazyk syntaxe. `available?(context)` řídí přehled i každý panel
249
+ před vykreslením.
250
+
251
+ Třídy rendererů deklarují zobrazení pomocí `language 'python'`,
252
+ `language_label 'Python'` a u varianty klienta `variant 'Async'`. Tyto třídní
253
+ metody metadata také čtou. Jazyk je stabilní ID skupiny malými písmeny,
254
+ nezávislé na lexeru syntaxe i přesném ID klienta. Pokud jazyk není určený,
255
+ použije se vlastní `id` rendereru, popisek jazyka vychází z `label` a varianta
256
+ je nil. Metadata se deklarují na každé třídě; podtřída bez vlastních metadat
257
+ dostane tyto výchozí hodnoty. Zachovej ID klientů a pořadí v registru.
258
+
259
+ Třídní dotaz `detail_levels_for(kind, context:, result:, auth_method: nil,
260
+ auth_description: nil)` vybírá smysluplné úrovně pro každou skupinu příkladů.
261
+ `result` je již vykreslený jednoduchý výsledek. Vracej zmrazené `[:simple]`
262
+ nebo `[:simple, :thorough]`; jiné hodnoty jsou chyba. Základní implementace
263
+ vrací zděděnou deklaraci `detail_levels`, která u vlastních rendererů standardně
264
+ obsahuje obě úrovně. Vlastní omezení v jednoduché podobě nepotlačí odlišnou
265
+ implementaci s ošetřením chyb. Přímé vykreslení s oběma hodnotami podrobnosti
266
+ kontextu zůstává podporované nezávisle na volbách nabízených v HTML.
267
+
268
+ Ruby a PHP nabízejí obě úrovně pro vyjádřitelnou inicializaci, autentizaci
269
+ a akce. Ruby OAuth zůstává nepodporovaný. Jejich konstruktory jsou odložené,
270
+ takže podoba S ošetřením chyb provádí přípravu explicitně a zpracovává chyby
271
+ validace, API, autentizace i protokolu. Ruby zachytává `ValidationError` před
272
+ rodičovskou `ActionFailed` a chyby odpovědi čte pouze ze skutečného `Response`.
273
+ PHP používá výjimky frameworku a tam, kde je dostupné, `getErrors()`;
274
+ neznámé výjimky závislostí vyhazuje znovu. Součástí příkladu zůstávají OAuth
275
+ session, state, PKCE, přesměrování i výměna tokenu.
276
+
277
+ Callbackový JavaScript a TypeScript nabízejí obě úrovně pro akce.
278
+ Inicializace a autentizace již kontrolují výsledek připravenosti a nabízejí
279
+ jen jednoduchou podobu. Asynchronní JavaScript, asynchronní TypeScript
280
+ a Python nabízejí obě úrovně pro vyjádřitelné příklady.
281
+
282
+ Jednoduché akce v Go již kontrolují chyby přenosu a API. Obě úrovně jsou dostupné
283
+ pouze pro úspěšné blokující akce s dostupnou oprávněnou pomocnou akcí pro stav
284
+ operace. Inicializace a metody nastavující přihlašovací údaje neposílají žádný
285
+ požadavek a nabízejí pouze jednoduchou podobu. Rust nabízí obě úrovně pro
286
+ vyjádřitelný kód a explicitně zpracovává výsledky konstrukce a odesílání,
287
+ které mohou selhat. Jeho metody pro autentizaci nastavují přihlašovací údaje,
288
+ aniž by je ověřovaly přes síť.
289
+
290
+ Inicializace typovaného TypeScriptu má pouze jednoduchou podobu. Podporovaná
291
+ Basic autentizace, autentizace tokenem a akce nabízejí obě úrovně se zpracováním
292
+ `AsyncError` pomocí await; OAuth zůstává omezením. CLI, curl a HTTP nabízejí
293
+ pouze jednoduchou podobu: CLI hlásí chyby a končí s nenulovým stavem, zatímco
294
+ přepisy komunikace ukazují odpovědi protokolu. Všechna vestavěná omezení mají
295
+ pouze jednoduchou podobu.
296
+
297
+ Obalové renderery Go, Rustu a TypeScriptu předávají dotaz
298
+ `detail_levels_for(kind:, context:, result:, mode:, auth_method: nil,
299
+ auth_description: nil)` svému nastavenému adaptéru, pokud ho implementuje.
300
+ Starší adaptéry zachovávají úrovně deklarované obalovým rendererem včetně
301
+ odlišného výsledku s ošetřením chyb po omezení jednoduché podoby. Tyto adaptéry
302
+ mohou stále nabízet stejný kód na obou úrovních. Pokud dotaz vrátí neplatné
303
+ úrovně nebo vyvolá chybu, tato náhrada se nepoužije. Dotazy na schopnosti
304
+ nesmí znovu vykreslovat ani procházet nesouvisející zdroje. Producent HTML
305
+ vykreslí každou nabízenou podrobnost jednou a zveřejní volby v mapě
306
+ `data-example-details` skupiny příkladů. Metadata klienta obsahují uspořádané
307
+ sjednocení pro aktuální stránku; klienti bez skupin příkladů dostanou jednoduchou
308
+ podobu. Volby skupiny ani stránky nemění uložené nastavení podrobnosti.
309
+
310
+ Renderery jednoduchých akcí používají připravené `api` a zobrazují skutečné
311
+ volání i příslušný výsledek. Inicializuj ho a přihlas pomocí samostatných
312
+ příkladů. Asynchronní fragmenty Pythonu patří do asynchronní funkce;
313
+ jejich komentář to výslovně uvádí. Příklady přípravy Pythonu používají minimální
314
+ asynchronní funkci a `asyncio.run`, zatímco synchronní příklady běží na nejvyšší
315
+ úrovni. Ani jedna úroveň nemá podmínku `__main__`. Synchronní příklady
316
+ s ošetřením chyb používají `try`/`except` na nejvyšší úrovni.
317
+
318
+ Zkompiluj a ověř příklady před výběrem podrobnosti zobrazení. Zachovej přesné
319
+ názvy, argumenty rodičů, false, nulu, prázdné řetězce, hodnoty s povoleným null
320
+ a chování blokujících operací. Příklady nezkracuj vynecháním nepodporovaného
321
+ vstupu ani odstraňováním řádků z již vykresleného programu.
322
+
323
+ Adaptéry generovaných klientů patří do gemů generátorů a používají čtečky
324
+ kontextu bez závislosti na serverovém gemu. Názvy určují z úplného soukromého
325
+ modelu generátoru a při HTML požadavku nikdy nespouštějí kompilátor, formátovač
326
+ ani generátor. Vykreslování adaptérů musí zůstat pouze pro čtení: nastavené
327
+ adaptéry jsou zmrazené a sdílené, zatímco snapshoty autorizovaného popisu
328
+ patří jednotlivým požadavkům. Adaptéry zachovávají stávající signaturu
329
+ `render(kind:, context:, mode:, ...)` a čtou přímo `context.detail`.
330
+ Testovací kontexty musí tuto čtečku poskytovat. Starší adaptér třetí strany
331
+ může toto přidané pole ignorovat a zachovat deklarované volby obalového rendereru
332
+ bez implementace nového dotazu na schopnosti. Odvozené kontexty v jednom
333
+ požadavku sdílejí nezměněná vlastněná data. Předání zdroje, akce nebo příkladu
334
+ stále kopíruje předaný podstrom, takže vykreslení zdroje s mnoha akcemi může
335
+ zůstat nákladné.
336
+
337
+ <h2 id="example-source-style">Styl zdrojového kódu příkladů</h2>
338
+
339
+ Generované příklady dodržují zvyklosti svého výstupního jazyka. Pravidla platí
340
+ pro inicializaci, autentizaci i akce včetně zděděných callbackových,
341
+ synchronních, asynchronních a blokujících variant. Tam, kde jsou podporované
342
+ obě úrovně, udržuj jednoduchou podobu i podobu s ošetřením chyb konzistentní.
343
+
344
+ | Jazyk | Zvyklosti zdrojového kódu |
345
+ | --- | --- |
346
+ | PHP | Bloky a vnoření polí odsazuj čtyřmi mezerami. Pro běžné statické řetězce bez interpolace používej jednoduché uvozovky a kolem spojování řetězců mezery. Escapované dvojité uvozovky zachovej tam, kde je vyžadují řídicí řetězce nebo výstup s novými řádky. |
347
+ | Ruby | Bloky odsazuj dvěma mezerami a pro běžné autorské řetězce používej jednoduché uvozovky. Pro ukázková data zachovej kódování pomocí `dump`, `inspect` a PP. |
348
+ | JavaScript / TypeScript | Bloky odsazuj dvěma mezerami, řetězce a specifikátory importů piš do dvojitých uvozovek. Používej středníky a obvyklé mezery po čárkách, dvojtečkách i uvnitř importů a objektových závorek. Zachovej bezpečné vypočítané klíče a typovaný přístup k vlastnostem. |
349
+ | Python | Bloky odsazuj čtyřmi mezerami a zachovej stávající kódování dat s dvojitými uvozovkami. Vynechávej prázdná místa pro volitelné importy; před spustitelným kódem na úrovni modulu nech jeden prázdný řádek a kolem asynchronních definic na nejvyšší úrovni dva. |
350
+ | Go | Používej tabulátory, mezery kompatibilní s gofmt a oddělené skupiny importů standardní knihovny a klienta. Zachovej nativní kódování řetězců s dvojitými uvozovkami. |
351
+ | Rust | Bloky odsazuj čtyřmi mezerami, používej obvyklé mezery a importy Rustu a stávající kodér řetězců v asynchronních i blokujících příkladech. |
352
+ | CLI / curl | Zachovej pokračování řádků shellu. Nejprve serializuj data a pak zakóduj každý úplný dynamický argument pomocí `Shellwords.escape`, včetně URL, hlaviček, názvů voleb i hodnot. |
353
+ | HTTP | Zachovej přepis protokolu/JSON, zejména oddělení hlaviček od těla. Pravidla shellových uvozovek se neuplatňují. |
354
+
355
+ Na známých hranicích fragmentů vynechávej nepřítomné části a odděluj logické
356
+ bloky jedním účelným prázdným řádkem podle pravidel jazyka výše. Nepřidávej
357
+ prázdné řádky na začátek ani konec, duplicitní oddělovače ani bílé znaky na
358
+ prázdných řádcích. Formátování patří do rendereru či adaptéru daného jazyka.
359
+ Nenormalizuj celé vykreslené programy ani výstup vlastního rendereru společným
360
+ regulárním výrazem nebo formátovačem a nepřidávej závislost na formátovači
361
+ za běhu. Testy mohou používat nativní formátovače.
362
+
363
+ U CLI a curl odděluj autorskou syntaxi shellu od dat argumentů. Každý argument
364
+ zakóduj jednou po serializaci jeho hodnoty; obalit surová data jednoduchými
365
+ nebo dvojitými uvozovkami nestačí. Generované příkazy ověřuj pomocí dočasných
366
+ falešných spustitelných souborů: vyžaduj úspěšné provedení, přesné zachycené
367
+ hodnoty a pořadí argumentů a žádné nezamýšlené spuštění příkazů. Parsováním
368
+ zachyceného JSON z curl ověř, že shellové kódování zachovává celé tělo požadavku.
369
+
370
+ Příklady CLI a curl mohou za spustitelným příkazem zobrazovat výstup odpovědi.
371
+ Každý fyzický řádek odpovědi musí při vložení celého bloku do shellu zůstat
372
+ nespustitelný. Normalizuj CRLF a samotné CR na LF pouze v částech odpovědi
373
+ určených k zobrazení a každý výsledný řádek uvoď `# `. Nenormalizuj ani
374
+ nekomentuj příkaz požadavku a nenahrazuj komentování každého fyzického řádku
375
+ shellovým escapováním. Regresní testy musí spustit celý zobrazený blok
376
+ s dočasnými falešnými spustitelnými soubory, zachovat přesné argumenty požadavku
377
+ a JSON curl a doložit, že nebezpečné víceřádkové hodnoty odpovědi zůstanou
378
+ viditelné bez vyhodnocení.
379
+
380
+ Kódovaná data odděluj od autorské syntaxe. Zachovej skutečné hodnoty, Unicode,
381
+ apostrofy, zpětná lomítka, znaky dolaru, řídicí bajty, prázdné hodnoty, false,
382
+ nulu i null. Řídicí řetězce PHP mohou vyžadovat dvojité uvozovky s escapovanými
383
+ dolary, zpětnými lomítky a uvozovkami a řídicí sekvence platné v PHP;
384
+ JSON `\u` není kodér řetězců PHP. Nikdy neměň nový řádek na doslovné
385
+ zpětné lomítko s n a nedovol, aby odsazení obalového kódu změnilo bajty literálů.
386
+
387
+ Změny formátování musí zachovat veřejné ukázkové přihlašovací údaje, vstupy
388
+ požadavků, obsluhu chyb a tok řízení, kompatibilitu přímého volání a vlastních
389
+ adaptérů i smysluplné volby podrobnosti. Nepřidávej panely jen kvůli odlišnému
390
+ formátování.
391
+
392
+ Při změně rendereru:
393
+
394
+ - Zkontroluj příslušný výstup inicializace, autentizace a akcí pro dotčené
395
+ varianty a obě přímé hodnoty podrobnosti. Pokryj chybějící volitelné části
396
+ a krajní případy literálů, pokud je změna může ovlivnit.
397
+ - Použij stávající [serverové testy příkladů](../../servers/ruby/spec/client_examples/)
398
+ pro ověření zachování literálů PHP a skutečných handlerů, syntaxe Ruby,
399
+ AST a oddělení bloků Pythonu, podrobnosti i vlastních bílých znaků. Podle
400
+ dotčené části použij [dokumentační testy Go](../../clients/go/spec/unit/documentation_spec.rb),
401
+ [dokumentační testy TypeScriptu](../../clients/typescript/spec/unit/) a
402
+ [vývojové kontroly Rustu](../../clients/rust/docs/development.md).
403
+ Pokrytí TypeScriptu zahrnuje zdrojový kód, přísnou kompilaci a výkonnostní testy.
404
+ - V sousedních HTML testech, fixturách a výkonnostních asercích vyhledej přesné
405
+ zápisy zdrojového kódu. Aktualizuj záměrně změněná očekávání uvozovek,
406
+ importů a mezer, ale zachovej sémantické aserce, meze procházení a alokací
407
+ i přísné kontroly kompilátoru.
408
+ - Dodržuj [vývojové příkazy](../agent-instructions/development.md) a stávající
409
+ požadavky na ověření. Kontroly vybírej podle dotčeného jazyka a chování;
410
+ nesouvisející změna nevyžaduje všechny jazykové toolchainy.
411
+
412
+ <h2 id="verification">Ověření</h2>
413
+
414
+ `make test-documentation` kontroluje renderery, kontexty, profily, vykreslené
415
+ HTML i lokální assety. Nejprve připrav bundly komponent a vývojové závislosti
416
+ JavaScriptu pomocí `make release-deps`. Cíl sestaví JavaScriptový balíček před
417
+ kompilací příkladů TypeScriptu proti jeho veřejným deklaracím; Ruby server CI
418
+ používá stejné pořadí.
419
+
420
+ `make test-documentation-python` navíc ověřuje omezení rendereru Pythonu proti
421
+ skutečnému kodéru požadavků. Vyžaduje uzamčené prostředí Pythonu připravené
422
+ pomocí `make release-deps` a je součástí `make test`. Běžné Ruby testy rendererů
423
+ prostředí balíčku Pythonu nepotřebují.
424
+
425
+ Deterministické regrese kontextů a HTML běží v běžné serverové sadě. Ověřují
426
+ sdílení popisu, růst alokací a oddělení uživatelů bez časového limitu běhu.
427
+ Sada adaptéru Rustu samostatně ověřuje, že normalizace neprochází nesouvisející
428
+ potomky popisu.
429
+
430
+ Další povinný kontrakt `make test-performance-clients` kontroluje každý
431
+ registrovaný renderer a režim se skutečnými generovanými profily, omezenou
432
+ prací a alokacemi na vykreslení i škálováním alokací celé stránky. Běží
433
+ v uzamčeném benchmarkovém prostředí bez Bundleru, odděleně od běžného
434
+ serverového bundlu. Přípravu, přesné pokrytí a chování CI popisuje
435
+ [testování výkonu](../en/performance.md#all-client-documentation-contract).
436
+
437
+ <h3 id="documentation-benchmark">Benchmark dokumentace</h3>
438
+
439
+ Připrav serverový bundle v jeho deklarovaném Nix prostředí a pak spusť
440
+ volitelný měřicí nástroj z kořene repozitáře:
441
+
442
+ ```sh
443
+ nix develop .#server-ruby --command bash -c \
444
+ 'make --no-print-directory benchmark-documentation > /tmp/documentation.json'
445
+ ```
446
+
447
+ Cíl před spuštěním nástroje synchronizuje sdílenou dokumentaci. Standardní
448
+ výstup je JSON; příprava shellu a závislostí proběhne před přesměrovaným
449
+ příkazem. Nespouští se síťový server, databáze, kompilace API klienta ani
450
+ formátovač. Syntetická fixtura má uživatele `admin` a `member`. Přímé
451
+ vykreslování a měření popisu používají Basic autentizaci s lokálním heslem
452
+ `fixture-only`. HTML požadavky na podporovaných zdrojích používají skutečné
453
+ OAuth cookies dokumentace s ověřením tokenu při každém požadavku; historické
454
+ zdroje bez této funkce používají Basic.
455
+
456
+ Výchozí měření zahrnuje dvě podoby s osmi běžnými akcemi: osm zdrojů s jednou
457
+ akcí a jeden zdroj s osmi akcemi. Každá běžná akce má i privilegovaný příklad;
458
+ první zdroj má další akci pouze pro správce. Měření kontextu odvozuje
459
+ z připraveného rodiče kontext se změněným profilem nebo s pevným malým
460
+ příkladem. HTML měření při každém opakování provede jeden skutečný Rack
461
+ požadavek se všemi dostupnými dynamickými panely rendererů. Použij minimální
462
+ ověřovací běh nebo rozsáhlejší opakované měření:
463
+
464
+ ```sh
465
+ make benchmark-documentation \
466
+ BENCHMARK_DOCUMENTATION_ARGS='--shape resources --size 1 --warmup 0 --trials 1 --iterations 1'
467
+ make benchmark-documentation \
468
+ BENCHMARK_DOCUMENTATION_ARGS='--shape both --size 64 --samples 2 --parameters 8 --warmup 2 --trials 7 --iterations 500' \
469
+ > /tmp/documentation-large.json
470
+ ```
471
+
472
+ Tyto příkazy `make` spouštěj v připraveném shellu. `--shape custom --resources
473
+ N --actions N` ovládá oba rozměry nezávisle; `--lanes context` omezuje měření
474
+ na odvozování a `--lanes html` na požadavky. `--user member` vybírá omezenou
475
+ dokumentaci. `--help` vypíše všechny volby. `--rust` zapne odpovídající Rust
476
+ profil fixtury, zahrne obě varianty Rustu do HTML a přidá samostatná měření
477
+ asynchronních i blokujících akcí a autentizačních adaptérů. Vyžaduje dostupné
478
+ Ruby závislosti volitelného generátoru; běžné benchmarky je nepotřebují.
479
+ Připrav obě prostředí pomocí `nix develop .#server-ruby` a
480
+ `nix develop .#client-rust`. Samotný serverový bundle neaktivuje závislosti
481
+ Rustu. V hlavním Nix shellu spoj připravená lokální úložiště gemů:
482
+
483
+ ```sh
484
+ env -u RUBYOPT -u RUBYLIB -u BUNDLE_BIN_PATH -u BUNDLE_GEMFILE \
485
+ -u BUNDLE_LOCKFILE -u BUNDLE_PATH -u BUNDLE_FROZEN -u BUNDLER_SETUP \
486
+ GEM_PATH="$PWD/.gems:$PWD/clients/rust/.gems:$(ruby -e 'puts Gem.default_dir')" \
487
+ make benchmark-documentation BENCHMARK_DOCUMENTATION_RUBY=ruby \
488
+ BENCHMARK_DOCUMENTATION_ARGS='--rust --shape both --size 8 --warmup 1 --trials 3 --iterations 100' \
489
+ > /tmp/documentation-rust.json
490
+ ```
491
+
492
+ Příkaz běží mimo Bundler a zaznamenává skutečně aktivované verze gemů.
493
+ Uchovej jejich seznam spolu s lockfily obou komponent a pro obě revize použij
494
+ stejné připravené vstupy. Chybějící volitelné závislosti způsobí selhání;
495
+ měření Rustu se nikdy tiše nevynechává. Viz
496
+ [průvodce adaptérem Rustu](../../clients/rust/docs/documentation.md#verification).
497
+
498
+ Každé měření hlásí jednotlivá opakování i medián reálného času, procesorového
499
+ času procesu a alokovaných objektů spolu s počtem operací na opakování.
500
+ Reálný čas používá monotónní hodiny. Před každým opakováním proběhne úplný GC
501
+ mimo měřený interval; GC vyvolaný měřenou prací zůstává zahrnutý. Konstrukce
502
+ mount a profilů má samostatné metriky přípravy. Konstrukce vlastněných dat,
503
+ výběr popisu, zahřívání, validace výstupu, hashování a serializace JSON jsou
504
+ mimo měřený interval. Výstupy obsahují rozměry fixtury, ID rendererů, režim
505
+ profilu, běhové prostředí Ruby, hostitele, Git HEAD/status/digest diffu,
506
+ digesty načtených zdrojů, verze závislostí a dostupné digesty lockfilů,
507
+ měřicího nástroje i fixtury. HTML a Rust výstupy zahrnují stav, počet bajtů
508
+ a SHA-256; selhání nebo chybějící výstup vede k nenulovému návratovému kódu.
509
+
510
+ Pro porovnání před a po změně uchovej jeden přesný měřicí nástroj a fixturu
511
+ a pomocí `--source-root /absolute/checkout` je nasměruj na každou implementaci.
512
+ Nejprve připrav stejné závislosti a běhové prostředí. Explicitní
513
+ `--source-revision LABEL` může doplnit zjištěný HEAD a je povinné pro
514
+ exportovaný zdrojový strom. Uchovej přesné revize, příkazy, surové JSON
515
+ výstupy, identity lockfilů a vstupů i hostitele. Před porovnáním mediánů
516
+ porovnej rozměry, režimy rendererů, stavy, bajty a digesty těl. Kontextové
517
+ `description_shared` záměrně rozlišuje starou implementaci s kopírováním.
518
+ Každý rozdíl výstupu prošetři; případnou přesnou normalizaci proměnlivých polí
519
+ zaznamenej, místo abys neshody tiše vynechával.
520
+
521
+ Tato měření popisují syntetickou zátěž na zaznamenaném hostiteli. Nedokládají
522
+ latenci v produkci. Volitelný benchmark nemá časový limit;
523
+ [párová výkonnostní sada endpointů](../en/performance.md) poskytuje povinné rychlé
524
+ a týdenní CI kontroly času, alokací a dotazů včetně dokumentačního OPTIONS
525
+ a obou podob HTML. Zachovává šum baseline/self a blokuje neprůkazné výsledky.
526
+ Regrese vlastnictví, procházení a alokací pokrývají tento druh selhání;
527
+ náklady koncentrovaných zdrojů i jiné budoucí regrese nadále vyžadují
528
+ reprezentativní měření.
529
+
530
+ Každý klient má také příkazy pro akceptační testy, které ověřují spustitelné
531
+ ukázky proti nainstalovaným balíčkům nebo API klientovi. Spouštějí vykreslený
532
+ kód proti dočasným fixturám; samotná kontrola syntaxe nedokládá funkčnost
533
+ volání klienta ani autentizace. Testovací prostředí popisuje vývojová
534
+ dokumentace jednotlivých klientů. Sestavení highlighteru popisuje
535
+ [utils/highlight](../../utils/highlight/README.md).
@@ -0,0 +1,118 @@
1
+ <h1 id="client-definition">Definice klienta</h1>
2
+
3
+ Je potřeba rozlišovat mezi klientskou knihovnou pro API založená na HaveAPI
4
+ a klientem pro konkrétní instanci API. Tento dokument popisuje knihovnu.
5
+ Pokud chceš API jen používat, vyber si ze seznamu dostupných klientů knihovnu
6
+ v požadovaném jazyce. Pokračuj, pokud pro něj klient ještě neexistuje.
7
+
8
+ <h1 id="design-rules">Pravidla návrhu</h1>
9
+
10
+ Klient musí zcela vycházet z popisu API:
11
+
12
+ - nesmí obsahovat předpoklady ani kód specifický pro konkrétní API,
13
+ - předem nezná žádné zdroje, akce ani parametry,
14
+ - vše, co o API ví, musí zjistit z jeho popisu.
15
+
16
+ Všichni klienti by měli používat podobný přístup, aby se s nimi v různých
17
+ jazycích dalo pracovat stejně, pokud to syntaxe jazyka umožňuje. Jako vzor
18
+ mohou posloužit klienti dodávaní s HaveAPI. Klient by měl využívat možnosti
19
+ a zvyklosti svého jazyka, například objekty v objektově orientovaných jazycích.
20
+
21
+ Vzorový přístup (bez vazby na konkrétní jazyk):
22
+
23
+ // Vytvoření instance klienta
24
+ api = new HaveAPI.Client("https://your.api.tld")
25
+
26
+ // Autentizace
27
+ api.authenticate("basic", {"user": "yourname", "password": "yourpassword"})
28
+
29
+ // Přístup ke zdrojům a akcím
30
+ api.<resource>.<action>( { <parameters> } )
31
+ api.user.new({"name": "Very Name", "password": "donottellanyone"})
32
+ api.user.list()
33
+ api.nested.resource.deep.list()
34
+
35
+ // Předání ID zdrojům
36
+ api.nested(1).resource(2).deep.list()
37
+
38
+ // Objektový přístup
39
+ user = api.user.show(1)
40
+ user.id
41
+ user.name
42
+ user.destroy()
43
+
44
+ // Odhlášení
45
+ api.logout()
46
+
47
+ <h1 id="necessary-features-to-implement">Nezbytné funkce</h1>
48
+
49
+ Aby byl klient použitelný, měl by implementovat všechny následující funkce.
50
+
51
+ <h2 id="resource-tree">Strom zdrojů</h2>
52
+
53
+ Klient zpřístupňuje všechny uvedené zdroje a jejich akce.
54
+
55
+ Ve skriptovacích jazycích jsou zdroje a akce obvykle definovány jako dynamické
56
+ vlastnosti, objekty nebo metody podle možností daného jazyka.
57
+
58
+ <h2 id="input-output-parameters">Vstupní a výstupní parametry</h2>
59
+
60
+ Umožni odesílat vstupní parametry a přistupovat k odpovědi.
61
+
62
+ <h2 id="input-output-formats">Vstupní a výstupní formáty</h2>
63
+
64
+ Klient musí posílat odpovídající HTTP hlavičku `Accept`. HaveAPI má vestavěnou
65
+ podporu pouze pro JSON, takže by měl posílat `application/json`.
66
+
67
+ <h2 id="authentication">Autentizace</h2>
68
+
69
+ Klient by měl pokud možno podporovat všechny autentizační metody vestavěné
70
+ v HaveAPI. Měl by zvolit metodu vhodnou pro své použití a umožnit vývojáři
71
+ její výběr tam, kde to dává smysl.
72
+
73
+ Autentizační metody je vhodné implementovat jako pluginy, aby vývojáři mohli
74
+ snadno přidávat vlastní poskytovatele autentizace.
75
+
76
+ <h2 id="object-like-access">Objektový přístup</h2>
77
+
78
+ Klient musí interpretovat odpověď API podle rozložení výstupu akce.
79
+ Rozložení `object` a `object_list` by měl zpracovávat jako instance objektů,
80
+ pokud to jazyk umožňuje.
81
+
82
+ Instance představují objekty načtené z databáze. Přijaté parametry jsou dostupné
83
+ jako atributy nebo vlastnosti objektu. Akce jsou definovány jako metody instance.
84
+ Objekty mohou mít vazby na jiné zdroje, které musí být dostupné a snadno přístupné.
85
+
86
+ <h1 id="supplemental-features">Doplňkové funkce</h1>
87
+
88
+ Následující funkce je vhodné podporovat, ale nejsou nutné.
89
+
90
+ <h2 id="client-side-validations">Validace na straně klienta</h2>
91
+
92
+ Klient může pomocí popsaných validátorů ověřit vstup před odesláním do API,
93
+ snížit tak zátěž API a usnadnit práci uživateli.
94
+
95
+ Tato funkce není povinná, protože vstup se vždy validuje i na serveru.
96
+
97
+ Validace datových typů parametrů je od validace pomocí validátorů oddělená
98
+ a doporučuje se vždy. Před odesláním požadavku by měl klient vynutit pravidla
99
+ z dokumentu [Validace typovaných vstupů](typed-input-validation.md).
100
+ I v silně typovaných jazycích je potřeba za běhu ověřit hodnoty jako NaN/Inf
101
+ a formát řetězců s datem a časem.
102
+
103
+ <h2 id="metadata-channel">Kanál metadat</h2>
104
+
105
+ Kanál metadat se používá k určení, které související zdroje se mají předem
106
+ načíst a zda má seznam objektů obsahovat celkový počet položek.
107
+
108
+ Metadata jsou hash ve vstupních parametrech pod klíčem `_meta`.
109
+
110
+ <h2 id="blocking-actions">Blokující akce</h2>
111
+
112
+ Blokující akce jsou užitečné pro API s dlouho běžícími operacemi. Klienti
113
+ mohou jejich stav kontrolovat pomocí zdroje `ActionState`. Tento zdroj je
114
+ automaticky přítomný ve všech API, která blokující akce používají, a klientské
115
+ knihovny jej vývojáři zpřístupňují stejně jako ostatní zdroje API.
116
+
117
+ Můžeš ho ale také začlenit přímo do klienta a umožnit, aby volání akce čekalo
118
+ na dokončení nebo přijímalo callbacky.