[{"data":1,"prerenderedAt":19360},["ShallowReactive",2],{"navigation_docs":3,"-csharp-network-programming-http-fundamentals":3302,"-csharp-network-programming-http-fundamentals-surround":19355},[4,1707,1896,2350,2531,2572,2779,2901,2951,3008,3042,3168,3245,3298],{"title":5,"icon":6,"path":7,"stem":8,"children":9},"C#","i-devicon-csharp","\u002Fcsharp","01.csharp",[10,13,60,90,120,202,219,253,379,404,457,650,1364,1654,1703],{"title":11,"path":7,"stem":12},"C# та .NET","01.csharp\u002Findex",{"title":14,"icon":15,"path":16,"stem":17,"children":18,"page":59},"Fundamentals","i-lucide-book-open","\u002Fcsharp\u002Ffundamentals","01.csharp\u002F01.fundamentals",[19,23,27,31,35,39,43,47,51,55],{"title":20,"path":21,"stem":22},"Вступ до екосистеми .NET","\u002Fcsharp\u002Ffundamentals\u002Fintroduction-to-ecosystem","01.csharp\u002F01.fundamentals\u002F01.introduction-to-ecosystem",{"title":24,"path":25,"stem":26},"Структура програми на C#","\u002Fcsharp\u002Ffundamentals\u002Fprogram-structure","01.csharp\u002F01.fundamentals\u002F02.program-structure",{"title":28,"path":29,"stem":30},"Змінні та Типи Даних","\u002Fcsharp\u002Ffundamentals\u002Fvariables-data-types","01.csharp\u002F01.fundamentals\u002F03.variables-data-types",{"title":32,"path":33,"stem":34},"Масиви","\u002Fcsharp\u002Ffundamentals\u002Farrays","01.csharp\u002F01.fundamentals\u002F04.arrays",{"title":36,"path":37,"stem":38},"Strings & Text Handling","\u002Fcsharp\u002Ffundamentals\u002Fstrings-text-handling","01.csharp\u002F01.fundamentals\u002F05.strings-text-handling",{"title":40,"path":41,"stem":42},"Дати і Час","\u002Fcsharp\u002Ffundamentals\u002Fdates-time-handling","01.csharp\u002F01.fundamentals\u002F06.dates-time-handling",{"title":44,"path":45,"stem":46},"Потік Керування","\u002Fcsharp\u002Ffundamentals\u002Fcontrol-flow","01.csharp\u002F01.fundamentals\u002F07.control-flow",{"title":48,"path":49,"stem":50},"Методи","\u002Fcsharp\u002Ffundamentals\u002Fmethods","01.csharp\u002F01.fundamentals\u002F08.methods",{"title":52,"path":53,"stem":54},"Основи Відлагодження","\u002Fcsharp\u002Ffundamentals\u002Fdebugging-basics","01.csharp\u002F01.fundamentals\u002F09.debugging-basics",{"title":56,"path":57,"stem":58},"Інтерактивна Консоль (Classic)","\u002Fcsharp\u002Ffundamentals\u002Finteractive-console","01.csharp\u002F01.fundamentals\u002F10.interactive-console",false,{"title":61,"icon":62,"path":63,"stem":64,"children":65,"page":59},"OOP","i-lucide-box","\u002Fcsharp\u002Foop","01.csharp\u002F02.oop",[66,70,74,78,82,86],{"title":67,"path":68,"stem":69},"Package Management (Управління Пакетами)","\u002Fcsharp\u002Foop\u002Fpackage-management","01.csharp\u002F02.oop\u002F01.package-management",{"title":71,"path":72,"stem":73},"Класи та Об'єкти","\u002Fcsharp\u002Foop\u002Fclasses-objects","01.csharp\u002F02.oop\u002F02.classes-objects",{"title":75,"path":76,"stem":77},"Властивості та Поля","\u002Fcsharp\u002Foop\u002Fproperties-fields","01.csharp\u002F02.oop\u002F03.properties-fields",{"title":79,"path":80,"stem":81},"Стовпи ООП","\u002Fcsharp\u002Foop\u002Foop-pillars","01.csharp\u002F02.oop\u002F04.oop-pillars",{"title":83,"path":84,"stem":85},"Advanced Types","\u002Fcsharp\u002Foop\u002Fadvanced-types","01.csharp\u002F02.oop\u002F05.advanced-types",{"title":87,"path":88,"stem":89},"Namespaces (Простори Імен)","\u002Fcsharp\u002Foop\u002Fnamespaces","01.csharp\u002F02.oop\u002F06.namespaces",{"title":91,"icon":92,"path":93,"stem":94,"children":95,"page":59},"Advanced Core","i-lucide-zap","\u002Fcsharp\u002Fadvanced-core","01.csharp\u002F03.advanced-core",[96,100,104,108,112,116],{"title":97,"path":98,"stem":99},"Generics (Узагальнення)","\u002Fcsharp\u002Fadvanced-core\u002Fgenerics","01.csharp\u002F03.advanced-core\u002F01.generics",{"title":101,"path":102,"stem":103},"Делегати, Події та Лямбда-вирази","\u002Fcsharp\u002Fadvanced-core\u002Fdelegates-events-lambdas","01.csharp\u002F03.advanced-core\u002F02.delegates-events-lambdas",{"title":105,"path":106,"stem":107},"Interfaces Deep Dive (Інтерфейси: Поглиблений Розгляд)","\u002Fcsharp\u002Fadvanced-core\u002Finterfaces-deep-dive","01.csharp\u002F03.advanced-core\u002F03.interfaces-deep-dive",{"title":109,"path":110,"stem":111},"Обробка Винятків","\u002Fcsharp\u002Fadvanced-core\u002Fexception-handling","01.csharp\u002F03.advanced-core\u002F04.exception-handling",{"title":113,"path":114,"stem":115},"Pattern Matching","\u002Fcsharp\u002Fadvanced-core\u002Fpattern-matching","01.csharp\u002F03.advanced-core\u002F05.pattern-matching",{"title":117,"path":118,"stem":119},"Додаткові Можливості C#","\u002Fcsharp\u002Fadvanced-core\u002Fadditional-features","01.csharp\u002F03.advanced-core\u002F06.additional-features",{"title":121,"icon":122,"path":123,"stem":124,"children":125,"page":59},"Architecture Best Practices","i-lucide-building-2","\u002Fcsharp\u002Farchitecture-best-practices","01.csharp\u002F04.architecture-best-practices",[126,130,149,153,157,161,165,169],{"title":127,"path":128,"stem":129},"Software Design Principles (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fsoftware-design-principles","01.csharp\u002F04.architecture-best-practices\u002F01.software-design-principles",{"title":131,"icon":132,"path":133,"stem":134,"children":135,"page":59},"Design Patterns","i-lucide-folder","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns",[136],{"title":137,"icon":132,"path":138,"stem":139,"children":140,"page":59},"Creational","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational",[141,145],{"title":142,"path":143,"stem":144},"Singleton (Одинак)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fsingleton","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F01.singleton",{"title":146,"path":147,"stem":148},"Builder (Будівельник)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdesign-patterns\u002Fcreational\u002Fbuilder","01.csharp\u002F04.architecture-best-practices\u002F02.design-patterns\u002Fcreational\u002F02.builder",{"title":150,"path":151,"stem":152},"Building Professional CLIs","\u002Fcsharp\u002Farchitecture-best-practices\u002Fbuilding-professional-clis","01.csharp\u002F04.architecture-best-practices\u002F03.building-professional-clis",{"title":154,"path":155,"stem":156},"Validation & Flow Control","\u002Fcsharp\u002Farchitecture-best-practices\u002Fvalidation-flow-control","01.csharp\u002F04.architecture-best-practices\u002F04.validation-flow-control",{"title":158,"path":159,"stem":160},"The Modern .NET Host (Microsoft.Extensions)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fmodern-dotnet-host","01.csharp\u002F04.architecture-best-practices\u002F05.modern-dotnet-host",{"title":162,"path":163,"stem":164},"Data Mapper: Repository та DAO патерни (Частина 1)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part1","01.csharp\u002F04.architecture-best-practices\u002F06.data-mapper-part1",{"title":166,"path":167,"stem":168},"Data Mapper: Repository та DAO патерни (Частина 2)","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdata-mapper-part2","01.csharp\u002F04.architecture-best-practices\u002F07.data-mapper-part2",{"title":170,"icon":132,"path":171,"stem":172,"children":173,"page":59},"Di Ioc","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc",[174,178,182,186,190,194,198],{"title":175,"path":176,"stem":177},"Проблема залежностей та Інверсія Контролю","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fthe-dependency-problem","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F01.the-dependency-problem",{"title":179,"path":180,"stem":181},"Будуємо власний Service Container","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fbuild-your-own-container","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F02.build-your-own-container",{"title":183,"path":184,"stem":185},"Service Locator: Паттерн та Анти-паттерн","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-locator-pattern","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F03.service-locator-pattern",{"title":187,"path":188,"stem":189},"Паттерни Dependency Injection","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdependency-injection-patterns","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F04.dependency-injection-patterns",{"title":191,"path":192,"stem":193},"Microsoft DI: IServiceCollection та IServiceProvider","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fmicrosoft-di-deep-dive","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F05.microsoft-di-deep-dive",{"title":195,"path":196,"stem":197},"Service Lifetimes та Scopes","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fservice-lifetimes-and-scopes","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F06.service-lifetimes-and-scopes",{"title":199,"path":200,"stem":201},"DI Анти-паттерни та Найкращі Практики","\u002Fcsharp\u002Farchitecture-best-practices\u002Fdi-ioc\u002Fdi-anti-patterns-and-best-practices","01.csharp\u002F04.architecture-best-practices\u002F08.di-ioc\u002F07.di-anti-patterns-and-best-practices",{"title":203,"icon":132,"path":204,"stem":205,"children":206,"page":59},"Standard Library","\u002Fcsharp\u002Fstandard-library","01.csharp\u002F05.standard-library",[207,211,215],{"title":208,"path":209,"stem":210},"Collections (Колекції)","\u002Fcsharp\u002Fstandard-library\u002Fcollections","01.csharp\u002F05.standard-library\u002F01.collections",{"title":212,"path":213,"stem":214},"High Performance Types (Високопродуктивні Типи)","\u002Fcsharp\u002Fstandard-library\u002Fhigh-performance-types","01.csharp\u002F05.standard-library\u002F02.high-performance-types",{"title":216,"path":217,"stem":218},"LINQ (Language Integrated Query)","\u002Fcsharp\u002Fstandard-library\u002Flinq","01.csharp\u002F05.standard-library\u002F03.linq",{"title":220,"icon":221,"path":222,"stem":223,"children":224,"page":59},"System Internals Concurrency","i-lucide-server","\u002Fcsharp\u002Fsystem-internals-concurrency","01.csharp\u002F06.system-internals-concurrency",[225,229,233,237,241,245,249],{"title":226,"path":227,"stem":228},"Memory Management","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmemory-management","01.csharp\u002F06.system-internals-concurrency\u002F01.memory-management",{"title":230,"path":231,"stem":232},"Reflection API: System.Type та Метадані","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Freflection-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F02.reflection-fundamentals",{"title":234,"path":235,"stem":236},"Attributes та Dynamic Language Runtime","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fattributes-dynamic","01.csharp\u002F06.system-internals-concurrency\u002F03.attributes-dynamic",{"title":238,"path":239,"stem":240},"Expression Trees: Швидка Альтернатива Рефлексії","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fexpression-trees-compiled","01.csharp\u002F06.system-internals-concurrency\u002F04.expression-trees-compiled",{"title":242,"path":243,"stem":244},"Source Generators: Compile-Time Code Generation","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsource-generators","01.csharp\u002F06.system-internals-concurrency\u002F05.source-generators",{"title":246,"path":247,"stem":248},"Multithreading Fundamentals","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fmultithreading-fundamentals","01.csharp\u002F06.system-internals-concurrency\u002F06.multithreading-fundamentals",{"title":250,"path":251,"stem":252},"Synchronization Primitives","\u002Fcsharp\u002Fsystem-internals-concurrency\u002Fsynchronization-primitives","01.csharp\u002F06.system-internals-concurrency\u002F07.synchronization-primitives",{"title":254,"icon":255,"path":256,"stem":257,"children":258,"page":59},"System Programming Windows","i-lucide-cpu","\u002Fcsharp\u002Fsystem-programming-windows","01.csharp\u002F07.system-programming-windows",[259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375],{"title":260,"path":261,"stem":262},"Як Працює Операційна Система","\u002Fcsharp\u002Fsystem-programming-windows\u002Fhow-os-works","01.csharp\u002F07.system-programming-windows\u002F01.how-os-works",{"title":264,"path":265,"stem":266},"Процеси в .NET — API та Запуск","\u002Fcsharp\u002Fsystem-programming-windows\u002Fprocesses-in-dotnet","01.csharp\u002F07.system-programming-windows\u002F02.processes-in-dotnet",{"title":268,"path":269,"stem":270},"Процеси в .NET — IPC та Міжпроцесна Комунікація","\u002Fcsharp\u002Fsystem-programming-windows\u002F02a.processes-ipc","01.csharp\u002F07.system-programming-windows\u002F02a.processes-ipc",{"title":272,"path":273,"stem":274},"Application Domains та Збірки — AppDomain і AssemblyLoadContext","\u002Fcsharp\u002Fsystem-programming-windows\u002Fappdomains-assemblies","01.csharp\u002F07.system-programming-windows\u002F03.appdomains-assemblies",{"title":276,"path":277,"stem":278},"Application Domains та Збірки — Plug-in Система з Hot-Reload","\u002Fcsharp\u002Fsystem-programming-windows\u002F03a.appdomains-plugin-system","01.csharp\u002F07.system-programming-windows\u002F03a.appdomains-plugin-system",{"title":280,"path":281,"stem":282},"Потоки — Основи та API Thread","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-fundamentals","01.csharp\u002F07.system-programming-windows\u002F04.thread-fundamentals",{"title":284,"path":285,"stem":286},"Потоки — Lifecycle, Пріоритети та Безпечне Завершення","\u002Fcsharp\u002Fsystem-programming-windows\u002F04a.thread-lifecycle-priorities","01.csharp\u002F07.system-programming-windows\u002F04a.thread-lifecycle-priorities",{"title":288,"path":289,"stem":290},"Проблеми Спільного Стану — Race Condition та Data Race","\u002Fcsharp\u002Fsystem-programming-windows\u002Fshared-state-problems","01.csharp\u002F07.system-programming-windows\u002F05.shared-state-problems",{"title":292,"path":293,"stem":294},"Проблеми Спільного Стану — Memory Model та volatile","\u002Fcsharp\u002Fsystem-programming-windows\u002F05a.shared-state-memory-model","01.csharp\u002F07.system-programming-windows\u002F05a.shared-state-memory-model",{"title":296,"path":297,"stem":298},"Синхронізація — Monitor, lock та еволюція примітивів","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-fundamentals","01.csharp\u002F07.system-programming-windows\u002F06.synchronization-fundamentals",{"title":300,"path":301,"stem":302},"Синхронізація — Наскрізний Приклад та Deadlock Detection","\u002Fcsharp\u002Fsystem-programming-windows\u002F06a.synchronization-walkthrough","01.csharp\u002F07.system-programming-windows\u002F06a.synchronization-walkthrough",{"title":304,"path":305,"stem":306},"Синхронізація — Mutex, Semaphore та Event-Based Primitives","\u002Fcsharp\u002Fsystem-programming-windows\u002Fsynchronization-advanced","01.csharp\u002F07.system-programming-windows\u002F07.synchronization-advanced",{"title":308,"path":309,"stem":310},"Синхронізація — Interlocked, Volatile та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002F07a.synchronization-advanced-walkthrough","01.csharp\u002F07.system-programming-windows\u002F07a.synchronization-advanced-walkthrough",{"title":312,"path":313,"stem":314},"Interlocked, CAS та Lock-Free Структури","\u002Fcsharp\u002Fsystem-programming-windows\u002Finterlocked-cas-lockfree","01.csharp\u002F07.system-programming-windows\u002F08.interlocked-cas-lockfree",{"title":316,"path":317,"stem":318},"Volatile, Memory Model та Spinning","\u002Fcsharp\u002Fsystem-programming-windows\u002F08a.volatile-memory-model","01.csharp\u002F07.system-programming-windows\u002F08a.volatile-memory-model",{"title":320,"path":321,"stem":322},"ThreadPool — Пул Потоків для Ефективного Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fthread-pool","01.csharp\u002F07.system-programming-windows\u002F09.thread-pool",{"title":324,"path":325,"stem":326},"ThreadPool — Просунуті Сценарії та Внутрішня Будова","\u002Fcsharp\u002Fsystem-programming-windows\u002F09a.thread-pool-advanced","01.csharp\u002F07.system-programming-windows\u002F09a.thread-pool-advanced",{"title":328,"path":329,"stem":330},"Concurrent та Immutable Collections","\u002Fcsharp\u002Fsystem-programming-windows\u002Fconcurrent-collections","01.csharp\u002F07.system-programming-windows\u002F10.concurrent-collections",{"title":332,"path":333,"stem":334},"TPL, Task та Композиція — Від Thread до Task","\u002Fcsharp\u002Fsystem-programming-windows\u002Ftpl-parallel-plinq","01.csharp\u002F07.system-programming-windows\u002F11.tpl-parallel-plinq",{"title":336,"path":337,"stem":338},"Parallel Class та PLINQ — Data Parallelism","\u002Fcsharp\u002Fsystem-programming-windows\u002F11a.tpl-parallel-plinq-advanced","01.csharp\u002F07.system-programming-windows\u002F11a.tpl-parallel-plinq-advanced",{"title":340,"path":341,"stem":342},"Async\u002FAwait — Фундамент Асинхронного Програмування","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-fundamentals","01.csharp\u002F07.system-programming-windows\u002F12.async-fundamentals",{"title":344,"path":345,"stem":346},"SynchronizationContext та ConfigureAwait — Контекст Виконання","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-context-configureawait","01.csharp\u002F07.system-programming-windows\u002F13.async-context-configureawait",{"title":348,"path":349,"stem":350},"Async — Просунуті Паттерни","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-advanced","01.csharp\u002F07.system-programming-windows\u002F14.async-advanced",{"title":352,"path":353,"stem":354},"System.Threading.Channels — Async Producer-Consumer","\u002Fcsharp\u002Fsystem-programming-windows\u002Fchannels","01.csharp\u002F07.system-programming-windows\u002F15.channels",{"title":356,"path":357,"stem":358},"Асинхронна Синхронізація","\u002Fcsharp\u002Fsystem-programming-windows\u002Fasync-synchronization","01.csharp\u002F07.system-programming-windows\u002F16.async-synchronization",{"title":360,"path":361,"stem":362},"Unsafe Code та Вказівники","\u002Fcsharp\u002Fsystem-programming-windows\u002Funsafe-code","01.csharp\u002F07.system-programming-windows\u002F17.unsafe-code",{"title":364,"path":365,"stem":366},"P\u002FInvoke та Windows API — Міст між .NET та Native Code","\u002Fcsharp\u002Fsystem-programming-windows\u002Fpinvoke-winapi","01.csharp\u002F07.system-programming-windows\u002F18.pinvoke-winapi",{"title":368,"path":369,"stem":370},"Реєстр Windows — Центральна База Конфігурації Системи","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-registry","01.csharp\u002F07.system-programming-windows\u002F19.windows-registry",{"title":372,"path":373,"stem":374},"Windows Hooks, Hotkeys та Services — Глибока Інтеграція з ОС","\u002Fcsharp\u002Fsystem-programming-windows\u002Fwindows-hooks-services","01.csharp\u002F07.system-programming-windows\u002F20.windows-hooks-services",{"title":376,"path":377,"stem":378},"Системне Програмування C# (Windows) — 07.system-programming-windows","\u002Fcsharp\u002Fsystem-programming-windows\u002Fimplementation_plan","01.csharp\u002F07.system-programming-windows\u002Fimplementation_plan",{"title":380,"icon":132,"path":381,"stem":382,"children":383,"page":59},"Io","\u002Fcsharp\u002Fio","01.csharp\u002F08.io",[384,388,392,396,400],{"title":385,"path":386,"stem":387},"8.1.1. Основи роботи з файловою системою","\u002Fcsharp\u002Fio\u002Ffile-system-basics","01.csharp\u002F08.io\u002F01.file-system-basics",{"title":389,"path":390,"stem":391},"8.1.2. Потоки (Streams) та Серіалізація Даних","\u002Fcsharp\u002Fio\u002Fstreams-serialization","01.csharp\u002F08.io\u002F02.streams-serialization",{"title":393,"path":394,"stem":395},"8.2.1. JSON Serialization з System.Text.Json","\u002Fcsharp\u002Fio\u002Fjson-serialization","01.csharp\u002F08.io\u002F03.json-serialization",{"title":397,"path":398,"stem":399},"8.2.2. XML Serialization та LINQ to XML","\u002Fcsharp\u002Fio\u002Fxml-serialization","01.csharp\u002F08.io\u002F04.xml-serialization",{"title":401,"path":402,"stem":403},"8.2.3. Binary Serialization: MessagePack та Protocol Buffers","\u002Fcsharp\u002Fio\u002Fbinary-serialization","01.csharp\u002F08.io\u002F05.binary-serialization",{"title":405,"icon":132,"path":406,"stem":407,"children":408,"page":59},"Ado Net","\u002Fcsharp\u002Fado-net","01.csharp\u002F09.ado-net",[409,413,417,421,425,429,433,437,441,445,449,453],{"title":410,"path":411,"stem":412},"9.1. Введення в ADO.NET","\u002Fcsharp\u002Fado-net\u002Fintroduction-to-adonet","01.csharp\u002F09.ado-net\u002F01.introduction-to-adonet",{"title":414,"path":415,"stem":416},"9.2. Клас DbConnection — з'єднання з базою даних","\u002Fcsharp\u002Fado-net\u002Fconnection","01.csharp\u002F09.ado-net\u002F02.connection",{"title":418,"path":419,"stem":420},"9.3. Клас DbCommand — виконання SQL-запитів","\u002Fcsharp\u002Fado-net\u002Fcommand-and-queries","01.csharp\u002F09.ado-net\u002F03.command-and-queries",{"title":422,"path":423,"stem":424},"9.4. Клас DbDataReader — ефективне читання даних","\u002Fcsharp\u002Fado-net\u002Fdatareader","01.csharp\u002F09.ado-net\u002F04.datareader",{"title":426,"path":427,"stem":428},"9.5. Параметризовані запити та захист від SQL Injection","\u002Fcsharp\u002Fado-net\u002Fparameters-and-sql-injection","01.csharp\u002F09.ado-net\u002F05.parameters-and-sql-injection",{"title":430,"path":431,"stem":432},"9.6. Транзакції в ADO.NET","\u002Fcsharp\u002Fado-net\u002Ftransactions","01.csharp\u002F09.ado-net\u002F06.transactions",{"title":434,"path":435,"stem":436},"9.7. DbProviderFactory — провайдер-незалежний код","\u002Fcsharp\u002Fado-net\u002Fprovider-factory","01.csharp\u002F09.ado-net\u002F07.provider-factory",{"title":438,"path":439,"stem":440},"9.8. Асинхронний доступ до даних","\u002Fcsharp\u002Fado-net\u002Fasync-data-access","01.csharp\u002F09.ado-net\u002F08.async-data-access",{"title":442,"path":443,"stem":444},"9.9. Від'єднаний режим: DataSet, DataTable, DataRow","\u002Fcsharp\u002Fado-net\u002Fdisconnected-mode-dataset","01.csharp\u002F09.ado-net\u002F09.disconnected-mode-dataset",{"title":446,"path":447,"stem":448},"9.10. DataAdapter — міст між DataSet та базою даних","\u002Fcsharp\u002Fado-net\u002Fdata-adapter","01.csharp\u002F09.ado-net\u002F10.data-adapter",{"title":450,"path":451,"stem":452},"9.11. Data Mapper та Repository: Архітектура доступу до даних","\u002Fcsharp\u002Fado-net\u002Fdata-mapper-repository","01.csharp\u002F09.ado-net\u002F11.data-mapper-repository",{"title":454,"path":455,"stem":456},"9.12. Identity Map, Unit of Work та Specification Pattern","\u002Fcsharp\u002Fado-net\u002Fadvanced-patterns","01.csharp\u002F09.ado-net\u002F12.advanced-patterns",{"title":458,"icon":255,"path":459,"stem":460,"children":461,"page":59},"Ef Core","\u002Fcsharp\u002Fef-core","01.csharp\u002F10.ef-core",[462,466,470,474,478,482,486,490,494,498,502,506,510,514,518,522,526,532,538,542,546,550,554,558,562,566,570,574,578,582,586,590,594,598,602,606,610,614,618,622,626,630,634,638,642,646],{"title":463,"path":464,"stem":465},"Що таке ORM? Від SQL до об'єктів","\u002Fcsharp\u002Fef-core\u002Fwhat-is-orm","01.csharp\u002F10.ef-core\u002F01.what-is-orm",{"title":467,"path":468,"stem":469},"Перший проєкт — від нуля до CRUD","\u002Fcsharp\u002Fef-core\u002Ffirst-project","01.csharp\u002F10.ef-core\u002F02.first-project",{"title":471,"path":472,"stem":473},"DbContext — Серце EF Core","\u002Fcsharp\u002Fef-core\u002Fdbcontext-deep-dive","01.csharp\u002F10.ef-core\u002F03.dbcontext-deep-dive",{"title":475,"path":476,"stem":477},"Провайдери баз даних — Архітектура та Вибір СУБД","\u002Fcsharp\u002Fef-core\u002Fdatabase-providers","01.csharp\u002F10.ef-core\u002F04.database-providers",{"title":479,"path":480,"stem":481},"Конвенції EF Core — Магія без конфігурації","\u002Fcsharp\u002Fef-core\u002Fconventions","01.csharp\u002F10.ef-core\u002F05.conventions",{"title":483,"path":484,"stem":485},"Fluent API та Data Annotations — Явна конфігурація моделі","\u002Fcsharp\u002Fef-core\u002Ffluent-api-vs-annotations","01.csharp\u002F10.ef-core\u002F06.fluent-api-vs-annotations",{"title":487,"path":488,"stem":489},"Зв'язки — One-to-One та One-to-Many","\u002Fcsharp\u002Fef-core\u002Frelationships-basics","01.csharp\u002F10.ef-core\u002F07.relationships-basics",{"title":491,"path":492,"stem":493},"Зв'язки Advanced — Many-to-Many та Складні Сценарії","\u002Fcsharp\u002Fef-core\u002Frelationships-advanced","01.csharp\u002F10.ef-core\u002F08.relationships-advanced",{"title":495,"path":496,"stem":497},"Властивості — Типи, Конвертери, Компаратори (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part1","01.csharp\u002F10.ef-core\u002F09.property-configuration-part1",{"title":499,"path":500,"stem":501},"Властивості — Value Comparers, Generators, Shadow Properties (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fproperty-configuration-part2","01.csharp\u002F10.ef-core\u002F09.property-configuration-part2",{"title":503,"path":504,"stem":505},"Складні типи — Owned Types та Complex Types (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part1","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part1",{"title":507,"path":508,"stem":509},"Складні типи — Complex Types, Keyless Entities, Порівняння (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fcomplex-types-owned-part2","01.csharp\u002F10.ef-core\u002F10.complex-types-owned-part2",{"title":511,"path":512,"stem":513},"JSON Columns — Складні дані у JSON (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part1","01.csharp\u002F10.ef-core\u002F11.json-columns-part1",{"title":515,"path":516,"stem":517},"JSON Columns — Value Comparers, Індекси, Провайдери (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fjson-columns-part2","01.csharp\u002F10.ef-core\u002F11.json-columns-part2",{"title":519,"path":520,"stem":521},"Успадкування — Абстрактні класи та TPH (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finheritance-part1","01.csharp\u002F10.ef-core\u002F12.inheritance-part1",{"title":523,"path":524,"stem":525},"Успадкування — TPT, TPC та Порівняння Стратегій (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finheritance-part2","01.csharp\u002F10.ef-core\u002F12.inheritance-part2",{"title":527,"path":528,"stem":529,"children":530},"Індекси, Обмеження та Схема (Частина 1)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part1","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part1",[531],{"title":527,"path":528,"stem":529},{"title":533,"path":534,"stem":535,"children":536},"Індекси, Обмеження та Схема (Частина 2)","\u002Fcsharp\u002Fef-core\u002Findexes-constraints-part2","01.csharp\u002F10.ef-core\u002F13.indexes-constraints-part2",[537],{"title":533,"path":534,"stem":535},{"title":539,"path":540,"stem":541},"Seed Data — Початкові Дані (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fseeding-part1","01.csharp\u002F10.ef-core\u002F14.seeding-part1",{"title":543,"path":544,"stem":545},"Seed Data — SQL-скрипти, Bogus та Стратегії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fseeding-part2","01.csharp\u002F10.ef-core\u002F14.seeding-part2",{"title":547,"path":548,"stem":549},"Global Query Filters — Глобальні Фільтри (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part1","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part1",{"title":551,"path":552,"stem":553},"Global Query Filters — Підводні камені та Інтеграція (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fglobal-query-filters-part2","01.csharp\u002F10.ef-core\u002F15.global-query-filters-part2",{"title":555,"path":556,"stem":557},"LINQ-запити в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part1","01.csharp\u002F10.ef-core\u002F16.linq-queries-part1",{"title":559,"path":560,"stem":561},"LINQ-запити в EF Core (Частина 2)","\u002Fcsharp\u002Fef-core\u002Flinq-queries-part2","01.csharp\u002F10.ef-core\u002F16.linq-queries-part2",{"title":563,"path":564,"stem":565},"Завантаження Пов'язаних Даних (Частина 1)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part1","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part1",{"title":567,"path":568,"stem":569},"Завантаження Пов'язаних Даних (Частина 2)","\u002Fcsharp\u002Fef-core\u002Floading-related-data-part2","01.csharp\u002F10.ef-core\u002F17.loading-related-data-part2",{"title":571,"path":572,"stem":573},"Raw SQL, Views та Stored Procedures (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part1","01.csharp\u002F10.ef-core\u002F18.raw-sql-part1",{"title":575,"path":576,"stem":577},"Raw SQL — Stored Procedures, DbFunction та Bulk Operations (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fraw-sql-part2","01.csharp\u002F10.ef-core\u002F18.raw-sql-part2",{"title":579,"path":580,"stem":581},"Продвинуті Запити — Compiled Queries, Bulk та Оптимізація (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part1","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part1",{"title":583,"path":584,"stem":585},"Продвинуті Запити — Query Tags, Bulk та Interceptors (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fadvanced-queries-part2","01.csharp\u002F10.ef-core\u002F19.advanced-queries-part2",{"title":587,"path":588,"stem":589},"Change Tracker — Відстеження Змін (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part1","01.csharp\u002F10.ef-core\u002F20.change-tracking-part1",{"title":591,"path":592,"stem":593},"Change Tracker — Графи Об'єктів та Disconnected (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fchange-tracking-part2","01.csharp\u002F10.ef-core\u002F20.change-tracking-part2",{"title":595,"path":596,"stem":597},"Збереження Даних та Транзакції (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part1","01.csharp\u002F10.ef-core\u002F21.saving-data-part1",{"title":599,"path":600,"stem":601},"Збереження Даних — Concurrency та Outbox (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fsaving-data-part2","01.csharp\u002F10.ef-core\u002F21.saving-data-part2",{"title":603,"path":604,"stem":605},"Конкурентність та Блокування (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part1","01.csharp\u002F10.ef-core\u002F22.concurrency-part1",{"title":607,"path":608,"stem":609},"Конкурентність — Дедлоки та Queue Processing (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fconcurrency-part2","01.csharp\u002F10.ef-core\u002F22.concurrency-part2",{"title":611,"path":612,"stem":613},"Міграції в EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part1","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part1",{"title":615,"path":616,"stem":617},"Міграції в EF Core — Основи (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-basics-part2","01.csharp\u002F10.ef-core\u002F23.migrations-basics-part2",{"title":619,"path":620,"stem":621},"Міграції — Просунуті Сценарії (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part1","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part1",{"title":623,"path":624,"stem":625},"Міграції — Просунуті Сценарії (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fmigrations-advanced-part2","01.csharp\u002F10.ef-core\u002F24.migrations-advanced-part2",{"title":627,"path":628,"stem":629},"Управління Схемою та Database-First (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part1","01.csharp\u002F10.ef-core\u002F25.schema-management-part1",{"title":631,"path":632,"stem":633},"Управління Схемою та Database-First (Частина 2)","\u002Fcsharp\u002Fef-core\u002Fschema-management-part2","01.csharp\u002F10.ef-core\u002F25.schema-management-part2",{"title":635,"path":636,"stem":637},"Продуктивність EF Core — Основи (Частина 1)","\u002Fcsharp\u002Fef-core\u002Fperformance-fundamentals-part1","01.csharp\u002F10.ef-core\u002F26.performance-fundamentals-part1",{"title":639,"path":640,"stem":641},"Interceptors в EF Core (Частина 1)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part1","01.csharp\u002F10.ef-core\u002F29.interceptors-part1",{"title":643,"path":644,"stem":645},"Interceptors в EF Core — Connection, Transaction та Materialization (Частина 2)","\u002Fcsharp\u002Fef-core\u002Finterceptors-part2","01.csharp\u002F10.ef-core\u002F29.interceptors-part2",{"title":647,"path":648,"stem":649},"План вивчення Entity Framework Core — Повний курс","\u002Fcsharp\u002Fef-core\u002Fimplementation_plan","01.csharp\u002F10.ef-core\u002Fimplementation_plan",{"title":651,"icon":652,"path":653,"stem":654,"children":655,"page":59},"ASP.NET","i-devicon-dotnetcore","\u002Fcsharp\u002Faspnet","01.csharp\u002F11.aspnet",[656,730,791,869,927,941,967,1057,1111,1182,1212,1289,1346],{"title":657,"icon":658,"path":659,"stem":660,"children":661,"page":59},"Minimal API","i-lucide-network","\u002Fcsharp\u002Faspnet\u002Fminimal-api","01.csharp\u002F11.aspnet\u002F01.minimal-api",[662,666,670,674,678,682,686,690,694,698,702,706,710,714,718,722,726],{"title":663,"path":664,"stem":665},"Вступ до ASP.NET та еволюція фреймворку","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fintroduction","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F01.introduction",{"title":667,"path":668,"stem":669},"Перший додаток на ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Ffirst-application","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F02.first-application",{"title":671,"path":672,"stem":673},"WebApplication, Builder та Dependency Injection","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fwebapplication-builder","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F03.webapplication-builder",{"title":675,"path":676,"stem":677},"Конвеєр запитів та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frequest-pipeline-middleware","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F04.request-pipeline-middleware",{"title":679,"path":680,"stem":681},"Маршрутизація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F05.routing-basics",{"title":683,"path":684,"stem":685},"Маршрутизація в ASP.NET Core: Розширені можливості","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Frouting-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F06.routing-advanced",{"title":687,"path":688,"stem":689},"Статичні файли в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-files","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F07.static-files",{"title":691,"path":692,"stem":693},"Статичні Активи: MapStaticAssets (ASP.NET Core 9.0)","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstatic-assets","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F08.static-assets",{"title":695,"path":696,"stem":697},"Конфігурація в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-fundamentals","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F09.configuration-fundamentals",{"title":699,"path":700,"stem":701},"Конфігурація: Паттерн Options","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fconfiguration-options","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F10.configuration-options",{"title":703,"path":704,"stem":705},"Логування в ASP.NET Core: Основи","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-basics","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F11.logging-basics",{"title":707,"path":708,"stem":709},"Логування: Serilog та Middleware","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Flogging-advanced","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F12.logging-advanced",{"title":711,"path":712,"stem":713},"Управління станом: HttpContext.Items та Cookies","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fstate-management","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F13.state-management",{"title":715,"path":716,"stem":717},"Стан сесії: Sessions","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fsession-state","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F14.session-state",{"title":719,"path":720,"stem":721},"Структура проєкту: від хаосу до архітектури","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fproject-structure","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F15.project-structure",{"title":723,"path":724,"stem":725},"Scalar у Minimal API: повний проєкт і Fluent OpenAPI","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fscalar-openapi-fluent","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F16.scalar-openapi-fluent",{"title":727,"path":728,"stem":729},"Swagger \u002F Swashbuckle у Minimal API: окремий класичний шлях","\u002Fcsharp\u002Faspnet\u002Fminimal-api\u002Fswagger-swashbuckle","01.csharp\u002F11.aspnet\u002F01.minimal-api\u002F17.swagger-swashbuckle",{"title":731,"icon":658,"path":732,"stem":733,"children":734,"page":59},"API","\u002Fcsharp\u002Faspnet\u002Fapi","01.csharp\u002F11.aspnet\u002F02.api",[735,739,743,747,751,755,759,763,767,771,775,779,783,787],{"title":736,"path":737,"stem":738},"Що таке API. Клієнт-серверна архітектура","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fwhat-is-api","01.csharp\u002F11.aspnet\u002F02.api\u002F01.what-is-api",{"title":740,"path":741,"stem":742},"Формати даних: JSON, XML, TOML та бінарні формати","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fdata-formats","01.csharp\u002F11.aspnet\u002F02.api\u002F02.data-formats",{"title":744,"path":745,"stem":746},"Парадигми API та концепція REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-paradigms-rest","01.csharp\u002F11.aspnet\u002F02.api\u002F03.api-paradigms-rest",{"title":748,"path":749,"stem":750},"HTTP-методи, статус-коди та заголовки","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fhttp-methods-status-codes","01.csharp\u002F11.aspnet\u002F02.api\u002F04.http-methods-status-codes",{"title":752,"path":753,"stem":754},"Організація HTTP API за принципами REST","\u002Fcsharp\u002Faspnet\u002Fapi\u002Frest-organizing","01.csharp\u002F11.aspnet\u002F02.api\u002F05.rest-organizing",{"title":756,"path":757,"stem":758},"Номенклатура URL та CRUD-операції","\u002Fcsharp\u002Faspnet\u002Fapi\u002Furl-nomenclature-crud","01.csharp\u002F11.aspnet\u002F02.api\u002F06.url-nomenclature-crud",{"title":760,"path":761,"stem":762},"Правила дизайну: іменування та стандарти","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-naming","01.csharp\u002F11.aspnet\u002F02.api\u002F07.api-design-naming",{"title":764,"path":765,"stem":766},"Валідація, ліміти та обробка помилок","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-validation","01.csharp\u002F11.aspnet\u002F02.api\u002F08.api-design-validation",{"title":768,"path":769,"stem":770},"Обробка помилок у Minimal API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Ferror-handling-http","01.csharp\u002F11.aspnet\u002F02.api\u002F09.error-handling-http",{"title":772,"path":773,"stem":774},"Ідемпотентність та синхронізація стану","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fidempotency-sync","01.csharp\u002F11.aspnet\u002F02.api\u002F10.idempotency-sync",{"title":776,"path":777,"stem":778},"Пагінація та організація списків","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fpagination-lists","01.csharp\u002F11.aspnet\u002F02.api\u002F11.pagination-lists",{"title":780,"path":781,"stem":782},"Безпека API, кешування та інтернаціоналізація","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fsecurity-auth","01.csharp\u002F11.aspnet\u002F02.api\u002F12.security-auth",{"title":784,"path":785,"stem":786},"Процес проєктування API та документування","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fapi-design-process","01.csharp\u002F11.aspnet\u002F02.api\u002F13.api-design-process",{"title":788,"path":789,"stem":790},"OpenAPI: контракт, специфікація та документація API","\u002Fcsharp\u002Faspnet\u002Fapi\u002Fopenapi","01.csharp\u002F11.aspnet\u002F02.api\u002F14.openapi",{"title":792,"icon":793,"path":794,"stem":795,"children":796,"page":59},"Auth","i-lucide-shield-check","\u002Fcsharp\u002Faspnet\u002Fauth","01.csharp\u002F11.aspnet\u002F03.auth",[797,801,805,809,813,817,821,825,829,833,837,841,845,849,853,857,861,865],{"title":798,"path":799,"stem":800},"Основи аутентифікації та авторизації","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauth-fundamentals","01.csharp\u002F11.aspnet\u002F03.auth\u002F01.auth-fundamentals",{"title":802,"path":803,"stem":804},"JWT-аутентифікація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fjwt-authentication","01.csharp\u002F11.aspnet\u002F03.auth\u002F02.jwt-authentication",{"title":806,"path":807,"stem":808},"Авторизація: ролі, політики та resource-based доступ","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fauthorization-policies","01.csharp\u002F11.aspnet\u002F03.auth\u002F03.authorization-policies",{"title":810,"path":811,"stem":812},"Cookie-аутентифікація та ASP.NET Core Identity","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcookie-auth-identity","01.csharp\u002F11.aspnet\u002F03.auth\u002F04.cookie-auth-identity",{"title":814,"path":815,"stem":816},"JWT + Refresh Tokens (HttpOnly Cookie)","\u002Fcsharp\u002Faspnet\u002Fauth\u002F04b.identity-auth-jwt","01.csharp\u002F11.aspnet\u002F03.auth\u002F04b.identity-auth-jwt",{"title":818,"path":819,"stem":820},"Identity: Підтвердження Email та Скидання Пароля","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-email-confirmation","01.csharp\u002F11.aspnet\u002F03.auth\u002F05.identity-email-confirmation",{"title":822,"path":823,"stem":824},"Identity: Двофакторна Аутентифікація (2FA)","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-two-factor","01.csharp\u002F11.aspnet\u002F03.auth\u002F06.identity-two-factor",{"title":826,"path":827,"stem":828},"Identity: Внутрішня Архітектура та Кастомізація","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fidentity-internals","01.csharp\u002F11.aspnet\u002F03.auth\u002F07.identity-internals",{"title":830,"path":831,"stem":832},"OAuth 2.0 та зовнішні провайдери","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-external-providers","01.csharp\u002F11.aspnet\u002F03.auth\u002F08.oauth-external-providers",{"title":834,"path":835,"stem":836},"Безпека на практиці: CORS, HTTPS та захист від атак","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fsecurity-hardening","01.csharp\u002F11.aspnet\u002F03.auth\u002F09.security-hardening",{"title":838,"path":839,"stem":840},"Теорія OAuth 2.0: Поняття, Аналогії та Флоу","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foauth-theory","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oauth-theory",{"title":842,"path":843,"stem":844},"OIDC, OAuth 2.0 та Keycloak в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Foidc-keycloak","01.csharp\u002F11.aspnet\u002F03.auth\u002F10.oidc-keycloak",{"title":846,"path":847,"stem":848},"API Keys аутентифікація в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fapi-keys","01.csharp\u002F11.aspnet\u002F03.auth\u002F11.api-keys",{"title":850,"path":851,"stem":852},"Rate Limiting та Throttling в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frate-limiting","01.csharp\u002F11.aspnet\u002F03.auth\u002F12.rate-limiting",{"title":854,"path":855,"stem":856},"Refresh Token Rotation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frefresh-token-rotation","01.csharp\u002F11.aspnet\u002F03.auth\u002F13.refresh-token-rotation",{"title":858,"path":859,"stem":860},"Certificate Authentication та mTLS в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fcertificate-auth","01.csharp\u002F11.aspnet\u002F03.auth\u002F14.certificate-auth",{"title":862,"path":863,"stem":864},"RBAC, ABAC та ReBAC в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Frbac-abac-rebac","01.csharp\u002F11.aspnet\u002F03.auth\u002F15.rbac-abac-rebac",{"title":866,"path":867,"stem":868},"Multi-tenancy та ізоляція даних в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fauth\u002Fmulti-tenancy","01.csharp\u002F11.aspnet\u002F03.auth\u002F16.multi-tenancy",{"title":870,"icon":871,"path":872,"stem":873,"children":874,"page":59},"Нотифікації","i-lucide-bell","\u002Fcsharp\u002Faspnet\u002Fnotifications","01.csharp\u002F11.aspnet\u002F04.notifications",[875,879,883,887,891,895,899,903,907,911,915,919,923],{"title":876,"path":877,"stem":878},"In-App нотифікації через базу даних","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fin-app-database-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F01.in-app-database-notifications",{"title":880,"path":881,"stem":882},"Polling: Регулярний запит оновлень","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fpolling","01.csharp\u002F11.aspnet\u002F04.notifications\u002F02.polling",{"title":884,"path":885,"stem":886},"Server-Sent Events: Однострімовий push від сервера","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fserver-sent-events","01.csharp\u002F11.aspnet\u002F04.notifications\u002F03.server-sent-events",{"title":888,"path":889,"stem":890},"WebSockets: Двостороннє з'єднання в реальному часі","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fwebsockets","01.csharp\u002F11.aspnet\u002F04.notifications\u002F04.websockets",{"title":892,"path":893,"stem":894},"SignalR: Абстракція над транспортами реального часу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fsignalr","01.csharp\u002F11.aspnet\u002F04.notifications\u002F05.signalr",{"title":896,"path":897,"stem":898},"Background Services: Фонові задачі в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fbackground-services","01.csharp\u002F11.aspnet\u002F04.notifications\u002F06.background-services",{"title":900,"path":901,"stem":902},"Web Push нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fweb-push","01.csharp\u002F11.aspnet\u002F04.notifications\u002F07.web-push",{"title":904,"path":905,"stem":906},"Email нотифікації","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Femail-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F08.email-notifications",{"title":908,"path":909,"stem":910},"Порівняння підходів: Як вибрати правильну технологію нотифікацій","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fchoosing-the-right-approach","01.csharp\u002F11.aspnet\u002F04.notifications\u002F09.choosing-the-right-approach",{"title":912,"path":913,"stem":914},"Hangfire: Надійне планування фонових задач","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire","01.csharp\u002F11.aspnet\u002F04.notifications\u002F10.hangfire",{"title":916,"path":917,"stem":918},"Практика: Конвертація зображень у WebP через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-image-webp","01.csharp\u002F11.aspnet\u002F04.notifications\u002F11.hangfire-image-webp",{"title":920,"path":921,"stem":922},"Практика: Підготовка відео до HLS-стрімінгу через Hangfire","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Fhangfire-video-hls","01.csharp\u002F11.aspnet\u002F04.notifications\u002F12.hangfire-video-hls",{"title":924,"path":925,"stem":926},"Telegram-нотифікації: від одного повідомлення до масових розсилок і мульти-канального підходу","\u002Fcsharp\u002Faspnet\u002Fnotifications\u002Ftelegram-notifications","01.csharp\u002F11.aspnet\u002F04.notifications\u002F13.telegram-notifications",{"title":928,"icon":929,"path":930,"stem":931,"children":932,"page":59},"Інтернаціоналізація","i-lucide-languages","\u002Fcsharp\u002Faspnet\u002Fi18n","01.csharp\u002F11.aspnet\u002F05.i18n",[933,937],{"title":934,"path":935,"stem":936},"Інтернаціоналізація (i18n) у Minimal API: від A до Я","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Finternationalization","01.csharp\u002F11.aspnet\u002F05.i18n\u002F01.internationalization",{"title":938,"path":939,"stem":940},"Humanizer: людиномовні рядки у .NET","\u002Fcsharp\u002Faspnet\u002Fi18n\u002Fhumanizer","01.csharp\u002F11.aspnet\u002F05.i18n\u002F02.humanizer",{"title":942,"icon":943,"path":944,"stem":945,"children":946,"page":59},"Кешування","i-lucide-layers","\u002Fcsharp\u002Faspnet\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching",[947,951,955,959,963],{"title":948,"path":949,"stem":950},"Огляд кешування: чотири рівні і коли що обирати","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fcaching","01.csharp\u002F11.aspnet\u002F06.caching\u002F01.caching",{"title":952,"path":953,"stem":954},"IMemoryCache: кеш в оперативній пам'яті","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fmemory-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F02.memory-cache",{"title":956,"path":957,"stem":958},"IDistributedCache і Redis: розподілений кеш","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fdistributed-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F03.distributed-cache",{"title":960,"path":961,"stem":962},"Response Cache: HTTP-кешування через Cache-Control","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Fresponse-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F04.response-cache",{"title":964,"path":965,"stem":966},"Output Cache: серверний кеш HTTP-відповідей (.NET 7+)","\u002Fcsharp\u002Faspnet\u002Fcaching\u002Foutput-cache","01.csharp\u002F11.aspnet\u002F06.caching\u002F05.output-cache",{"title":968,"icon":969,"path":970,"stem":971,"children":972,"page":59},"Тестування","i-lucide-test-tube","\u002Fcsharp\u002Faspnet\u002Ftesting","01.csharp\u002F11.aspnet\u002F07.testing",[973,977,981,985,989,993,997,1001,1005,1009,1013,1017,1021,1025,1029,1033,1037,1041,1045,1049,1053],{"title":974,"path":975,"stem":976},"Що таке тестування? Від інтуїції до науки","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-is-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F01.what-is-testing",{"title":978,"path":979,"stem":980},"Піраміда тестування — Стратегія, а не Догма","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-pyramid","01.csharp\u002F11.aspnet\u002F07.testing\u002F02.testing-pyramid",{"title":982,"path":983,"stem":984},"Дві Школи Тестування — Лондон проти Детройту","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-schools","01.csharp\u002F11.aspnet\u002F07.testing\u002F03.testing-schools",{"title":986,"path":987,"stem":988},"TDD та BDD — Тести як Дизайн-інструмент","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftdd-and-bdd","01.csharp\u002F11.aspnet\u002F07.testing\u002F04.tdd-and-bdd",{"title":990,"path":991,"stem":992},"Що саме тестувати — Техніки аналізу та Циклomatична складність","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwhat-to-test","01.csharp\u002F11.aspnet\u002F07.testing\u002F05.what-to-test",{"title":994,"path":995,"stem":996},"Тестові Фреймворки — Навіщо вони і що всередині","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftest-frameworks","01.csharp\u002F11.aspnet\u002F07.testing\u002F06.test-frameworks",{"title":998,"path":999,"stem":1000},"xUnit — Факти, Теорії та Lifecycle тестів","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-basics","01.csharp\u002F11.aspnet\u002F07.testing\u002F07.xunit-basics",{"title":1002,"path":1003,"stem":1004},"xUnit Advanced — Fixtures, Кастомізація та Розширення","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fxunit-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F08.xunit-advanced",{"title":1006,"path":1007,"stem":1008},"Moq — Глибоке занурення в мокування","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fmocking-with-moq","01.csharp\u002F11.aspnet\u002F07.testing\u002F09.mocking-with-moq",{"title":1010,"path":1011,"stem":1012},"Тестування Баз Даних — EF Core, SQLite та Testcontainers","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fdatabase-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F10.database-testing",{"title":1014,"path":1015,"stem":1016},"Integration Testing — Частина 1 [Теорія та WebApplicationFactory]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F11.integration-testing",{"title":1018,"path":1019,"stem":1020},"Інтеграційне тестування — Практика","\u002Fcsharp\u002Faspnet\u002Ftesting\u002F11a.integration-testing-practice","01.csharp\u002F11.aspnet\u002F07.testing\u002F11a.integration-testing-practice",{"title":1022,"path":1023,"stem":1024},"Integration Testing — Частина 2 [Просунуті Сценарії та Testcontainers]","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fintegration-testing-advanced","01.csharp\u002F11.aspnet\u002F07.testing\u002F12.integration-testing-advanced",{"title":1026,"path":1027,"stem":1028},"Професійний Postman: Колекції, Змінні та GitHub Інтеграція","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fpostman-professional","01.csharp\u002F11.aspnet\u002F07.testing\u002F13.postman-professional",{"title":1030,"path":1031,"stem":1032},"HttpClient у Тестах Частина 1: Архітектура та MockHttpMessageHandler","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fhttpclient-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F14.httpclient-testing",{"title":1034,"path":1035,"stem":1036},"HttpClient у Тестах Частина 2: WireMock.Net та Resilience","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fwiremock-net","01.csharp\u002F11.aspnet\u002F07.testing\u002F15.wiremock-net",{"title":1038,"path":1039,"stem":1040},"Патерни та Анти-патерни Тестування: Test Smells","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Ftesting-patterns","01.csharp\u002F11.aspnet\u002F07.testing\u002F16.testing-patterns",{"title":1042,"path":1043,"stem":1044},"Просунуті інструменти: Time, Snapshots та Властивості","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fadvanced-testing-tools","01.csharp\u002F11.aspnet\u002F07.testing\u002F17.advanced-testing-tools",{"title":1046,"path":1047,"stem":1048},"Тестування Архітектури з NetArchTest","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Farchitecture-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F18.architecture-testing",{"title":1050,"path":1051,"stem":1052},"Тестування Продуктивності: BenchmarkDotNet, NBomber та k6","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fperformance-testing","01.csharp\u002F11.aspnet\u002F07.testing\u002F19.performance-testing",{"title":1054,"path":1055,"stem":1056},"Залишок плану для курсу \"Тестування ASP.NET Minimal API\"","\u002Fcsharp\u002Faspnet\u002Ftesting\u002Fremaining_plan","01.csharp\u002F11.aspnet\u002F07.testing\u002Fremaining_plan",{"title":1058,"icon":1059,"path":1060,"stem":1061,"children":1062,"page":59},"Платежі","i-lucide-credit-card","\u002Fcsharp\u002Faspnet\u002Fpayments","01.csharp\u002F11.aspnet\u002F08.payments",[1063,1067,1071,1075,1079,1083,1087,1091,1095,1099,1103,1107],{"title":1064,"path":1065,"stem":1066},"Основи платіжної інфраструктури","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-fundamentals","01.csharp\u002F11.aspnet\u002F08.payments\u002F01.payment-fundamentals",{"title":1068,"path":1069,"stem":1070},"Методи оплати в Україні","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-methods-ukraine","01.csharp\u002F11.aspnet\u002F08.payments\u002F02.payment-methods-ukraine",{"title":1072,"path":1073,"stem":1074},"PCI DSS та безпека платежів","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpci-dss-security","01.csharp\u002F11.aspnet\u002F08.payments\u002F03.pci-dss-security",{"title":1076,"path":1077,"stem":1078},"Архітектура платіжної підсистеми","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fpayment-architecture","01.csharp\u002F11.aspnet\u002F08.payments\u002F04.payment-architecture",{"title":1080,"path":1081,"stem":1082},"Інтеграція LiqPay (ПриватБанк)","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fliqpay-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F05.liqpay-integration",{"title":1084,"path":1085,"stem":1086},"Інтеграція Monobank Acquiring API","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fmonobank-acquiring","01.csharp\u002F11.aspnet\u002F08.payments\u002F06.monobank-acquiring",{"title":1088,"path":1089,"stem":1090},"Інтеграція Stripe","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fstripe-integration","01.csharp\u002F11.aspnet\u002F08.payments\u002F07.stripe-integration",{"title":1092,"path":1093,"stem":1094},"Webhooks — глибоке занурення","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fwebhooks-deep-dive","01.csharp\u002F11.aspnet\u002F08.payments\u002F08.webhooks-deep-dive",{"title":1096,"path":1097,"stem":1098},"Підписки та рекурентні платежі","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fsubscriptions-recurring","01.csharp\u002F11.aspnet\u002F08.payments\u002F09.subscriptions-recurring",{"title":1100,"path":1101,"stem":1102},"Повернення коштів та диспути","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Frefunds-disputes","01.csharp\u002F11.aspnet\u002F08.payments\u002F10.refunds-disputes",{"title":1104,"path":1105,"stem":1106},"Тестування платіжних інтеграцій","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Ftesting-payments","01.csharp\u002F11.aspnet\u002F08.payments\u002F11.testing-payments",{"title":1108,"path":1109,"stem":1110},"Чекліст виходу в Production","\u002Fcsharp\u002Faspnet\u002Fpayments\u002Fproduction-checklist","01.csharp\u002F11.aspnet\u002F08.payments\u002F12.production-checklist",{"title":1112,"icon":1113,"items":1114,"path":1127,"stem":1128,"children":1129,"page":59},"Популярні бібліотеки","lucide:box",[1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125,1126],"01.fluent-validation","02.mapster","03.erroror-result-pattern","04.serilog","05.mediatr","06.polly","07.health-checks","08.feature-management","09.fluent-email","10.quest-pdf","11.bogus","12.humanizer-guard","\u002Fcsharp\u002Faspnet\u002Flibraries","01.csharp\u002F11.aspnet\u002F09.libraries",[1130,1134,1138,1142,1146,1150,1154,1158,1162,1166,1170,1174,1178],{"title":1131,"path":1132,"stem":1133},"Валідація з FluentValidation в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-validation","01.csharp\u002F11.aspnet\u002F09.libraries\u002F01.fluent-validation",{"title":1135,"path":1136,"stem":1137},"Маппінг об","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmapster","01.csharp\u002F11.aspnet\u002F09.libraries\u002F02.mapster",{"title":1139,"path":1140,"stem":1141},"Обробка помилок з ErrorOr та Result Pattern в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ferroror-result-pattern","01.csharp\u002F11.aspnet\u002F09.libraries\u002F03.erroror-result-pattern",{"title":1143,"path":1144,"stem":1145},"Структуроване логування з Serilog в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fserilog","01.csharp\u002F11.aspnet\u002F09.libraries\u002F04.serilog",{"title":1147,"path":1148,"stem":1149},"CQRS та Mediator з MediatR в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fmediatr","01.csharp\u002F11.aspnet\u002F09.libraries\u002F05.mediatr",{"title":1151,"path":1152,"stem":1153},"Відмовостійкість з Polly в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fpolly","01.csharp\u002F11.aspnet\u002F09.libraries\u002F06.polly",{"title":1155,"path":1156,"stem":1157},"Health Checks в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F09.libraries\u002F07.health-checks",{"title":1159,"path":1160,"stem":1161},"Feature Management та Feature Flags в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffeature-management","01.csharp\u002F11.aspnet\u002F09.libraries\u002F08.feature-management",{"title":1163,"path":1164,"stem":1165},"Відправка Email з FluentEmail в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Ffluent-email","01.csharp\u002F11.aspnet\u002F09.libraries\u002F09.fluent-email",{"title":1167,"path":1168,"stem":1169},"Генерація PDF з QuestPDF в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fquest-pdf","01.csharp\u002F11.aspnet\u002F09.libraries\u002F10.quest-pdf",{"title":1171,"path":1172,"stem":1173},"Генерація тестових даних з Bogus в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fbogus","01.csharp\u002F11.aspnet\u002F09.libraries\u002F11.bogus",{"title":1175,"path":1176,"stem":1177},"Humanizer та Guard Clauses в ASP.NET Core","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fhumanizer-guard","01.csharp\u002F11.aspnet\u002F09.libraries\u002F12.humanizer-guard",{"title":1179,"path":1180,"stem":1181},"План модуля 10.libraries — Популярні бібліотеки ASP.NET","\u002Fcsharp\u002Faspnet\u002Flibraries\u002Fplan","01.csharp\u002F11.aspnet\u002F09.libraries\u002Fplan",{"title":1183,"icon":1184,"path":1185,"stem":1186,"children":1187,"page":59},"Razor Pages","i-lucide-layout-template","\u002Fcsharp\u002Faspnet\u002Frazor-pages","01.csharp\u002F11.aspnet\u002F10.razor-pages",[1188,1192,1196,1200,1204,1208],{"title":1189,"path":1190,"stem":1191},"Від Minimal API до Razor Pages: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ffrom-minimal-api","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F01.from-minimal-api",{"title":1193,"path":1194,"stem":1195},"PageModel: логіка сторінки Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fpage-model","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F02.page-model",{"title":1197,"path":1198,"stem":1199},"Razor синтаксис: шаблонізатор у .cshtml","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Frazor-syntax","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F03.razor-syntax",{"title":1201,"path":1202,"stem":1203},"Tag Helpers: типізований HTML","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Ftag-helpers","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F04.tag-helpers",{"title":1205,"path":1206,"stem":1207},"Форми і валідація: повний цикл обробки даних","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fforms-validation","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F05.forms-validation",{"title":1209,"path":1210,"stem":1211},"Практичний проєкт: TaskManager на Razor Pages","\u002Fcsharp\u002Faspnet\u002Frazor-pages\u002Fproject-task-manager","01.csharp\u002F11.aspnet\u002F10.razor-pages\u002F06.project-task-manager",{"title":1213,"path":1214,"stem":1215,"children":1216,"page":59},"ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc","01.csharp\u002F11.aspnet\u002F11.mvc",[1217,1221,1225,1229,1233,1237,1241,1245,1249,1253,1257,1261,1265,1269,1273,1277,1281,1285],{"title":1218,"path":1219,"stem":1220},"Патерн MVC: архітектура, що змінила веб","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-pattern","01.csharp\u002F11.aspnet\u002F11.mvc\u002F01.mvc-pattern",{"title":1222,"path":1223,"stem":1224},"Від Razor Pages до MVC: концептуальний перехід","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffrom-razor-pages","01.csharp\u002F11.aspnet\u002F11.mvc\u002F02.from-razor-pages",{"title":1226,"path":1227,"stem":1228},"Controllers та Actions: серце MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fcontrollers-actions","01.csharp\u002F11.aspnet\u002F11.mvc\u002F03.controllers-actions",{"title":1230,"path":1231,"stem":1232},"Маршрутизація в MVC: Convention vs Attribute Routing","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Frouting-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F04.routing-mvc",{"title":1234,"path":1235,"stem":1236},"Model Binding: від HTTP до C#","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmodel-binding","01.csharp\u002F11.aspnet\u002F11.mvc\u002F05.model-binding",{"title":1238,"path":1239,"stem":1240},"Views, ViewData, ViewBag, TempData і ViewModel","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fviews-viewdata-tempdata","01.csharp\u002F11.aspnet\u002F11.mvc\u002F06.views-viewdata-tempdata",{"title":1242,"path":1243,"stem":1244},"Filters: аспектно-орієнтоване програмування в MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffilters","01.csharp\u002F11.aspnet\u002F11.mvc\u002F07.filters",{"title":1246,"path":1247,"stem":1248},"Areas: структурування великих застосунків","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fareas","01.csharp\u002F11.aspnet\u002F11.mvc\u002F08.areas",{"title":1250,"path":1251,"stem":1252},"View Components: повторювані незалежні блоки UI","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fview-components","01.csharp\u002F11.aspnet\u002F11.mvc\u002F09.view-components",{"title":1254,"path":1255,"stem":1256},"Display та Editor Templates","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fdisplay-editor-templates","01.csharp\u002F11.aspnet\u002F11.mvc\u002F10.display-editor-templates",{"title":1258,"path":1259,"stem":1260},"Валідація: IValidatableObject та FluentValidation","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fvalidation-advanced","01.csharp\u002F11.aspnet\u002F11.mvc\u002F11.validation-advanced",{"title":1262,"path":1263,"stem":1264},"HTMX: інтерактивність через HTML-атрибути","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx","01.csharp\u002F11.aspnet\u002F11.mvc\u002F12.htmx",{"title":1266,"path":1267,"stem":1268},"HTMX у ASP.NET Core MVC: серверна інтеграція","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fajax-htmx-mvc","01.csharp\u002F11.aspnet\u002F11.mvc\u002F13.ajax-htmx-mvc",{"title":1270,"path":1271,"stem":1272},"Практичний проєкт: Каталог товарів з HTMX","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fhtmx-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F14.htmx-project",{"title":1274,"path":1275,"stem":1276},"Завантаження та обробка файлів","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Ffile-upload","01.csharp\u002F11.aspnet\u002F11.mvc\u002F15.file-upload",{"title":1278,"path":1279,"stem":1280},"Глобалізація та Локалізація MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fglobalization-localization","01.csharp\u002F11.aspnet\u002F11.mvc\u002F16.globalization-localization",{"title":1282,"path":1283,"stem":1284},"Підсумковий проєкт: Блог-платформа","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fmvc-project","01.csharp\u002F11.aspnet\u002F11.mvc\u002F17.mvc-project",{"title":1286,"path":1287,"stem":1288},"План курсу: ASP.NET Core MVC","\u002Fcsharp\u002Faspnet\u002Fmvc\u002Fplan","01.csharp\u002F11.aspnet\u002F11.mvc\u002Fplan",{"title":1290,"path":1291,"stem":1292,"children":1293,"page":59},"Web Api","\u002Fcsharp\u002Faspnet\u002Fweb-api","01.csharp\u002F11.aspnet\u002F12.web-api",[1294,1298,1302,1306,1310,1314,1318,1322,1326,1330,1334,1338,1342],{"title":1295,"path":1296,"stem":1297},"Від Minimal API до Controller-based API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffrom-minimal-api-to-controllers","01.csharp\u002F11.aspnet\u002F12.web-api\u002F01.from-minimal-api-to-controllers",{"title":1299,"path":1300,"stem":1301},"ControllerBase, ActionResult\u003CT> та Response Types","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontroller-base-actionresult","01.csharp\u002F11.aspnet\u002F12.web-api\u002F02.controller-base-actionresult",{"title":1303,"path":1304,"stem":1305},"Content Negotiation - JSON, XML та власні форматери","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fcontent-negotiation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F03.content-negotiation",{"title":1307,"path":1308,"stem":1309},"Версіонування API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-versioning","01.csharp\u002F11.aspnet\u002F12.web-api\u002F04.api-versioning",{"title":1311,"path":1312,"stem":1313},"ProblemDetails та структурована обробка помилок","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fproblemdetails-error-handling","01.csharp\u002F11.aspnet\u002F12.web-api\u002F05.problemdetails-error-handling",{"title":1315,"path":1316,"stem":1317},"Фільтри у Web API контексті","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Ffilters-for-api","01.csharp\u002F11.aspnet\u002F12.web-api\u002F06.filters-for-api",{"title":1319,"path":1320,"stem":1321},"Пагінація, фільтрація та сортування","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fpagination-filtering-sorting","01.csharp\u002F11.aspnet\u002F12.web-api\u002F07.pagination-filtering-sorting",{"title":1323,"path":1324,"stem":1325},"HATEOAS та Resource Expansion","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhateoas-resource-expansion","01.csharp\u002F11.aspnet\u002F12.web-api\u002F08.hateoas-resource-expansion",{"title":1327,"path":1328,"stem":1329},"Гібридна архітектура - Minimal API + Controllers","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fminimal-api-vs-controllers-hybrid","01.csharp\u002F11.aspnet\u002F12.web-api\u002F09.minimal-api-vs-controllers-hybrid",{"title":1331,"path":1332,"stem":1333},"Документація API - Swashbuckle, NSwag та генерація клієнтів","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fapi-documentation-generation","01.csharp\u002F11.aspnet\u002F12.web-api\u002F10.api-documentation-generation",{"title":1335,"path":1336,"stem":1337},"Health Checks та моніторинг API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fhealth-checks-monitoring","01.csharp\u002F11.aspnet\u002F12.web-api\u002F11.health-checks-monitoring",{"title":1339,"path":1340,"stem":1341},"Підсумковий проєкт - Production-Ready REST API","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fweb-api-project","01.csharp\u002F11.aspnet\u002F12.web-api\u002F12.web-api-project",{"title":1343,"path":1344,"stem":1345},"План курсу: ASP.NET Core Web API (Controllers)","\u002Fcsharp\u002Faspnet\u002Fweb-api\u002Fplan","01.csharp\u002F11.aspnet\u002F12.web-api\u002Fplan",{"title":1347,"icon":1348,"path":1349,"stem":1350,"children":1351,"page":59},"Моніторинг","i-lucide-activity","\u002Fcsharp\u002Faspnet\u002Fmonitoring","01.csharp\u002F11.aspnet\u002F13.monitoring",[1352,1356,1360],{"title":1353,"path":1354,"stem":1355},"Спостережуваність: від console.log до production-систем","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fobservability-intro","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F01.observability-intro",{"title":1357,"path":1358,"stem":1359},"Health Checks: перший рівень observability","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fhealth-checks","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F02.health-checks",{"title":1361,"path":1362,"stem":1363},"Вбудовані метрики .NET 10 та System.Diagnostics.Metrics","\u002Fcsharp\u002Faspnet\u002Fmonitoring\u002Fdotnet-metrics","01.csharp\u002F11.aspnet\u002F13.monitoring\u002F03.dotnet-metrics",{"title":1365,"icon":1366,"path":1367,"stem":1368,"children":1369,"page":59},"Desktop UI","i-lucide-app-window","\u002Fcsharp\u002Fdesktop-ui","01.csharp\u002F12.desktop-ui",[1370,1374,1378,1382,1386,1390,1394,1398,1402,1406,1410,1414,1418,1422,1426,1430,1434,1438,1442,1446,1450,1454,1458,1462,1466,1470,1474,1478,1482,1486,1490,1494,1498,1502,1506,1510,1514,1518,1522,1526,1530,1534,1538,1542,1546,1550,1554,1558,1562,1566,1570,1574,1578,1582,1586,1590,1594,1598,1602,1606,1610,1614,1618,1622,1626,1630,1634,1638,1642,1646,1650],{"title":1371,"path":1372,"stem":1373},"Що таке десктопна розробка?","\u002Fcsharp\u002Fdesktop-ui\u002Fwhat-is-desktop-dev","01.csharp\u002F12.desktop-ui\u002F01.what-is-desktop-dev",{"title":1375,"path":1376,"stem":1377},"Архітектура WPF — як влаштований графічний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-architecture","01.csharp\u002F12.desktop-ui\u002F02.wpf-architecture",{"title":1379,"path":1380,"stem":1381},"Перший WPF-проєкт — від нуля до вікна","\u002Fcsharp\u002Fdesktop-ui\u002Ffirst-wpf-app","01.csharp\u002F12.desktop-ui\u002F03.first-wpf-app",{"title":1383,"path":1384,"stem":1385},"Перший Avalonia-проєкт: WPF для всіх платформ","\u002Fcsharp\u002Fdesktop-ui\u002F03a.first-avalonia-app","01.csharp\u002F12.desktop-ui\u002F03a.first-avalonia-app",{"title":1387,"path":1388,"stem":1389},"XAML: декларативний інтерфейс","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-basics","01.csharp\u002F12.desktop-ui\u002F04.xaml-basics",{"title":1391,"path":1392,"stem":1393},"Fluent UI у WPF — сучасний дизайн Windows 11","\u002Fcsharp\u002Fdesktop-ui\u002F04a.wpf-fluent-ui","01.csharp\u002F12.desktop-ui\u002F04a.wpf-fluent-ui",{"title":1395,"path":1396,"stem":1397},"WPF UI — сучасна бібліотека Fluent контролів","\u002Fcsharp\u002Fdesktop-ui\u002F04b.wpf-ui-library","01.csharp\u002F12.desktop-ui\u002F04b.wpf-ui-library",{"title":1399,"path":1400,"stem":1401},"HandyControl — велика бібліотека UI контролів для WPF","\u002Fcsharp\u002Fdesktop-ui\u002F04c.handycontrol-library","01.csharp\u002F12.desktop-ui\u002F04c.handycontrol-library",{"title":1403,"path":1404,"stem":1405},"Простори імен та ресурси XAML","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-namespaces-resources","01.csharp\u002F12.desktop-ui\u002F05.xaml-namespaces-resources",{"title":1407,"path":1408,"stem":1409},"XAML в Avalonia: ключові відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F05a.avalonia-xaml-differences","01.csharp\u002F12.desktop-ui\u002F05a.avalonia-xaml-differences",{"title":1411,"path":1412,"stem":1413},"Розширення розмітки XAML (Markup Extensions)","\u002Fcsharp\u002Fdesktop-ui\u002Fxaml-markup-extensions","01.csharp\u002F12.desktop-ui\u002F06.xaml-markup-extensions",{"title":1415,"path":1416,"stem":1417},"Панелі Layout: StackPanel, WrapPanel, DockPanel","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part1","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part1",{"title":1419,"path":1420,"stem":1421},"Grid, Canvas, UniformGrid","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-panels-part2","01.csharp\u002F12.desktop-ui\u002F07.layout-panels-part2",{"title":1423,"path":1424,"stem":1425},"Просунуті техніки Layout","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-advanced","01.csharp\u002F12.desktop-ui\u002F08.layout-advanced",{"title":1427,"path":1428,"stem":1429},"Адаптивний Layout та найкращі практики","\u002Fcsharp\u002Fdesktop-ui\u002Flayout-responsive","01.csharp\u002F12.desktop-ui\u002F09.layout-responsive",{"title":1431,"path":1432,"stem":1433},"Layout в Avalonia: відмінності та нові можливості","\u002Fcsharp\u002Fdesktop-ui\u002F09a.layout-avalonia","01.csharp\u002F12.desktop-ui\u002F09a.layout-avalonia",{"title":1435,"path":1436,"stem":1437},"Button, Image, ProgressBar та інші базові контроли","\u002Fcsharp\u002Fdesktop-ui\u002Fbasic-controls","01.csharp\u002F12.desktop-ui\u002F10.basic-controls",{"title":1439,"path":1440,"stem":1441},"Контроли в Avalonia: відмінності від WPF","\u002Fcsharp\u002Fdesktop-ui\u002F10a.controls-avalonia","01.csharp\u002F12.desktop-ui\u002F10a.controls-avalonia",{"title":1443,"path":1444,"stem":1445},"Текстові контроли — TextBlock, TextBox, RichTextBox","\u002Fcsharp\u002Fdesktop-ui\u002Ftext-controls","01.csharp\u002F12.desktop-ui\u002F11.text-controls",{"title":1447,"path":1448,"stem":1449},"Контроли вибору — CheckBox, RadioButton, ComboBox, ListBox, DatePicker","\u002Fcsharp\u002Fdesktop-ui\u002Fselection-controls","01.csharp\u002F12.desktop-ui\u002F12.selection-controls",{"title":1451,"path":1452,"stem":1453},"Content Model — GroupBox, Expander, TabControl, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fcontent-controls","01.csharp\u002F12.desktop-ui\u002F13.content-controls",{"title":1455,"path":1456,"stem":1457},"UI\u002FUX принципи десктопних застосунків","\u002Fcsharp\u002Fdesktop-ui\u002F13a.ui-ux-principles","01.csharp\u002F12.desktop-ui\u002F13a.ui-ux-principles",{"title":1459,"path":1460,"stem":1461},"Dependency Properties — Концепція та Value Resolution","\u002Fcsharp\u002Fdesktop-ui\u002Fdependency-properties-part1","01.csharp\u002F12.desktop-ui\u002F14.dependency-properties-part1",{"title":1463,"path":1464,"stem":1465},"Avalonia Property System — StyledProperty та DirectProperty","\u002Fcsharp\u002Fdesktop-ui\u002F14a.avalonia-property-system","01.csharp\u002F12.desktop-ui\u002F14a.avalonia-property-system",{"title":1467,"path":1468,"stem":1469},"Attached Properties — Властивості без меж","\u002Fcsharp\u002Fdesktop-ui\u002Fattached-properties","01.csharp\u002F12.desktop-ui\u002F15.attached-properties",{"title":1471,"path":1472,"stem":1473},"Routed Events — Маршрутизація подій у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Frouted-events","01.csharp\u002F12.desktop-ui\u002F16.routed-events",{"title":1475,"path":1476,"stem":1477},"Data Binding — Від Code-Behind до Декларативності","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part1","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part1",{"title":1479,"path":1480,"stem":1481},"INotifyPropertyChanged — Живе оновлення UI","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-basics-part2","01.csharp\u002F12.desktop-ui\u002F17.data-binding-basics-part2",{"title":1483,"path":1484,"stem":1485},"Compiled Bindings в Avalonia — Безпека на етапі компіляції","\u002Fcsharp\u002Fdesktop-ui\u002F17a.avalonia-compiled-bindings","01.csharp\u002F12.desktop-ui\u002F17a.avalonia-compiled-bindings",{"title":1487,"path":1488,"stem":1489},"Просунутий Data Binding — ElementName, RelativeSource, MultiBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-binding-advanced","01.csharp\u002F12.desktop-ui\u002F18.data-binding-advanced",{"title":1491,"path":1492,"stem":1493},"Value Converters — Перетворення типів даних у Data Binding","\u002Fcsharp\u002Fdesktop-ui\u002Fvalue-converters","01.csharp\u002F12.desktop-ui\u002F19.value-converters",{"title":1495,"path":1496,"stem":1497},"Data Templates — Візуалізація об'єктів у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-templates","01.csharp\u002F12.desktop-ui\u002F20.data-templates",{"title":1499,"path":1500,"stem":1501},"Collections Binding Part 1 — ObservableCollection та ItemsControl","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part1","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part1",{"title":1503,"path":1504,"stem":1505},"Collections Binding Part 2 — ICollectionView, Filtering, Sorting та Virtualization","\u002Fcsharp\u002Fdesktop-ui\u002Fcollections-binding-part2","01.csharp\u002F12.desktop-ui\u002F21.collections-binding-part2",{"title":1507,"path":1508,"stem":1509},"MVVM Pattern — Від Spaghetti Code до архітектури","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-pattern","01.csharp\u002F12.desktop-ui\u002F22.mvvm-pattern",{"title":1511,"path":1512,"stem":1513},"ViewModel Implementation — Від BaseViewModel до валідації","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-implementation","01.csharp\u002F12.desktop-ui\u002F23.viewmodel-implementation",{"title":1515,"path":1516,"stem":1517},"Commands — Від event handlers до декларативних команд","\u002Fcsharp\u002Fdesktop-ui\u002Fcommands","01.csharp\u002F12.desktop-ui\u002F24.commands",{"title":1519,"path":1520,"stem":1521},"MVVM Toolkit — MVVM без boilerplate через Source Generators","\u002Fcsharp\u002Fdesktop-ui\u002Fmvvm-toolkit","01.csharp\u002F12.desktop-ui\u002F25.mvvm-toolkit",{"title":1523,"path":1524,"stem":1525},"Messenger Pattern — Комунікація між ViewModel без прямих посилань","\u002Fcsharp\u002Fdesktop-ui\u002Fmessenger-pattern","01.csharp\u002F12.desktop-ui\u002F26.messenger-pattern",{"title":1527,"path":1528,"stem":1529},"Стилі WPF — CSS для десктопу","\u002Fcsharp\u002Fdesktop-ui\u002Fstyles-basics","01.csharp\u002F12.desktop-ui\u002F27.styles-basics",{"title":1531,"path":1532,"stem":1533},"CSS-like стилі Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F27a.avalonia-css-styling","01.csharp\u002F12.desktop-ui\u002F27a.avalonia-css-styling",{"title":1535,"path":1536,"stem":1537},"Control Templates — Частина 1. Концепція та TemplateBinding","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part1","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part1",{"title":1539,"path":1540,"stem":1541},"Control Templates — Частина 2. Named Parts та ContentPresenter","\u002Fcsharp\u002Fdesktop-ui\u002Fcontrol-templates-part2","01.csharp\u002F12.desktop-ui\u002F28.control-templates-part2",{"title":1543,"path":1544,"stem":1545},"Control Themes в Avalonia — нова ера стилізації","\u002Fcsharp\u002Fdesktop-ui\u002F28a.avalonia-control-themes","01.csharp\u002F12.desktop-ui\u002F28a.avalonia-control-themes",{"title":1547,"path":1548,"stem":1549},"Triggers та Visual State Manager у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Ftriggers-visual-states","01.csharp\u002F12.desktop-ui\u002F29.triggers-visual-states",{"title":1551,"path":1552,"stem":1553},"Pseudo-classes в Avalonia — замість WPF Triggers","\u002Fcsharp\u002Fdesktop-ui\u002F29a.avalonia-pseudo-classes","01.csharp\u002F12.desktop-ui\u002F29a.avalonia-pseudo-classes",{"title":1555,"path":1556,"stem":1557},"Теми та ресурсні словники у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fresources-themes","01.csharp\u002F12.desktop-ui\u002F30.resources-themes",{"title":1559,"path":1560,"stem":1561},"Avalonia Themes — Fluent Design та система тематизації","\u002Fcsharp\u002Fdesktop-ui\u002F30a.avalonia-themes-fluent","01.csharp\u002F12.desktop-ui\u002F30a.avalonia-themes-fluent",{"title":1563,"path":1564,"stem":1565},"Контроли колекцій — глибоке занурення","\u002Fcsharp\u002Fdesktop-ui\u002Fcollection-controls","01.csharp\u002F12.desktop-ui\u002F31.collection-controls",{"title":1567,"path":1568,"stem":1569},"DataGrid — колонки та базове відображення","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part1","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part1",{"title":1571,"path":1572,"stem":1573},"DataGrid — сортування, фільтрація, редагування","\u002Fcsharp\u002Fdesktop-ui\u002Fdatagrid-part2","01.csharp\u002F12.desktop-ui\u002F32.datagrid-part2",{"title":1575,"path":1576,"stem":1577},"TreeView та GridView","\u002Fcsharp\u002Fdesktop-ui\u002Ftreeview-listview","01.csharp\u002F12.desktop-ui\u002F33.treeview-listview",{"title":1579,"path":1580,"stem":1581},"Меню, Toolbar, ContextMenu, StatusBar","\u002Fcsharp\u002Fdesktop-ui\u002Fmenus-toolbars","01.csharp\u002F12.desktop-ui\u002F34.menus-toolbars",{"title":1583,"path":1584,"stem":1585},"Навігація та керування вікнами. Частина 1: вікна та сторінки","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part1","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part1",{"title":1587,"path":1588,"stem":1589},"Навігація та керування вікнами. Частина 2: MVVM-навігація","\u002Fcsharp\u002Fdesktop-ui\u002Fnavigation-windows-part2","01.csharp\u002F12.desktop-ui\u002F35.navigation-windows-part2",{"title":1591,"path":1592,"stem":1593},"Avalonia — Навігація та діалоги","\u002Fcsharp\u002Fdesktop-ui\u002F35a.avalonia-navigation-dialogs","01.csharp\u002F12.desktop-ui\u002F35a.avalonia-navigation-dialogs",{"title":1595,"path":1596,"stem":1597},"Діалоги та File Pickers у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fdialogs-file-pickers","01.csharp\u002F12.desktop-ui\u002F36.dialogs-file-pickers",{"title":1599,"path":1600,"stem":1601},"UserControl: компонентний підхід у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fuser-controls","01.csharp\u002F12.desktop-ui\u002F37.user-controls",{"title":1603,"path":1604,"stem":1605},"Custom Controls: Lookless Controls у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fcustom-controls","01.csharp\u002F12.desktop-ui\u002F38.custom-controls",{"title":1607,"path":1608,"stem":1609},"Avalonia TemplatedControl — Lookless Controls","\u002Fcsharp\u002Fdesktop-ui\u002F38a.avalonia-templated-controls","01.csharp\u002F12.desktop-ui\u002F38a.avalonia-templated-controls",{"title":1611,"path":1612,"stem":1613},"Анімації у WPF: Storyboard та Easing Functions","\u002Fcsharp\u002Fdesktop-ui\u002Fanimations-transitions","01.csharp\u002F12.desktop-ui\u002F39.animations-transitions",{"title":1615,"path":1616,"stem":1617},"Анімації в Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002F39a.avalonia-animations","01.csharp\u002F12.desktop-ui\u002F39a.avalonia-animations",{"title":1619,"path":1620,"stem":1621},"2D Графіка та Мультимедіа у WPF","\u002Fcsharp\u002Fdesktop-ui\u002Fmedia-graphics","01.csharp\u002F12.desktop-ui\u002F40.media-graphics",{"title":1623,"path":1624,"stem":1625},"Dependency Injection у WPF та Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Fdi-integration","01.csharp\u002F12.desktop-ui\u002F41.di-integration",{"title":1627,"path":1628,"stem":1629},"SQLite та EF Core у десктопних додатках","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part1","01.csharp\u002F12.desktop-ui\u002F42.data-persistence-part1",{"title":1631,"path":1632,"stem":1633},"Repository Pattern та Unit of Work","\u002Fcsharp\u002Fdesktop-ui\u002Fdata-persistence-part2","01.csharp\u002F12.desktop-ui\u002F43.data-persistence-part2",{"title":1635,"path":1636,"stem":1637},"Тестування ViewModels","\u002Fcsharp\u002Fdesktop-ui\u002Fviewmodel-testing","01.csharp\u002F12.desktop-ui\u002F44.viewmodel-testing",{"title":1639,"path":1640,"stem":1641},"Avalonia Headless Testing — тестування UI без вікон","\u002Fcsharp\u002Fdesktop-ui\u002F44a.avalonia-headless-testing","01.csharp\u002F12.desktop-ui\u002F44a.avalonia-headless-testing",{"title":1643,"path":1644,"stem":1645},"Кросплатформна розробка з Avalonia","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-cross-platform","01.csharp\u002F12.desktop-ui\u002F45.avalonia-cross-platform",{"title":1647,"path":1648,"stem":1649},"Пакування та розгортання Avalonia додатків","\u002Fcsharp\u002Fdesktop-ui\u002Favalonia-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F46.avalonia-packaging-deployment",{"title":1651,"path":1652,"stem":1653},"Розгортання WPF застосунків","\u002Fcsharp\u002Fdesktop-ui\u002Fwpf-packaging-deployment","01.csharp\u002F12.desktop-ui\u002F47.wpf-packaging-deployment",{"title":1655,"icon":658,"path":1656,"stem":1657,"children":1658,"page":59},"Network Programming","\u002Fcsharp\u002Fnetwork-programming","01.csharp\u002F13.network-programming",[1659,1663,1667,1671,1675,1679,1683,1687,1691,1695,1699],{"title":1660,"path":1661,"stem":1662},"Основи комп'ютерних мереж","\u002Fcsharp\u002Fnetwork-programming\u002Ffoundations","01.csharp\u002F13.network-programming\u002F01.foundations",{"title":1664,"path":1665,"stem":1666},"Модель OSI та стек TCP\u002FIP","\u002Fcsharp\u002Fnetwork-programming\u002Fosi-model","01.csharp\u002F13.network-programming\u002F02.osi-model",{"title":1668,"path":1669,"stem":1670},"IP-протокол та адресація","\u002Fcsharp\u002Fnetwork-programming\u002Fip-addressing","01.csharp\u002F13.network-programming\u002F03.ip-addressing",{"title":1672,"path":1673,"stem":1674},"UDP — протокол без з'єднання","\u002Fcsharp\u002Fnetwork-programming\u002Fudp","01.csharp\u002F13.network-programming\u002F05.udp",{"title":1676,"path":1677,"stem":1678},"UDP Broadcast та Multicast","\u002Fcsharp\u002Fnetwork-programming\u002Fudp-broadcast-multicast","01.csharp\u002F13.network-programming\u002F06.udp-broadcast-multicast",{"title":1680,"path":1681,"stem":1682},"HTTP — протокол вебу","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-fundamentals","01.csharp\u002F13.network-programming\u002F07.http-fundamentals",{"title":1684,"path":1685,"stem":1686},"HttpListener — вбудований HTTP-сервер .NET","\u002Fcsharp\u002Fnetwork-programming\u002F07a.http-listener","01.csharp\u002F13.network-programming\u002F07a.http-listener",{"title":1688,"path":1689,"stem":1690},"HTTP Advanced — cookies, аутентифікація та HTTPS","\u002Fcsharp\u002Fnetwork-programming\u002Fhttp-advanced","01.csharp\u002F13.network-programming\u002F08.http-advanced",{"title":1692,"path":1693,"stem":1694},"SMTP та протоколи електронної пошти","\u002Fcsharp\u002Fnetwork-programming\u002Fsmtp","01.csharp\u002F13.network-programming\u002F09.smtp",{"title":1696,"path":1697,"stem":1698},"WebSocket — повнодуплексний протокол реального часу","\u002Fcsharp\u002Fnetwork-programming\u002Fwebsockets","01.csharp\u002F13.network-programming\u002F10.websockets",{"title":1700,"path":1701,"stem":1702},"TLS\u002FSSL — криптографічний захист мережевих з'єднань","\u002Fcsharp\u002Fnetwork-programming\u002Ftls-ssl","01.csharp\u002F13.network-programming\u002F11.tls-ssl",{"title":1704,"path":1705,"stem":1706},"C# & .NET: The Ultimate Roadmap","\u002Fcsharp\u002Froadmap","01.csharp\u002Froadmap",{"title":1708,"icon":1709,"path":1710,"stem":1711,"children":1712,"page":59},"C++","i-devicon-cplusplus","\u002Fcpp","02.cpp",[1713,1717,1721,1725,1729,1733,1737,1741,1745,1748,1752,1756,1760,1764,1768,1772,1776,1780,1784,1788,1792,1796,1800,1804,1808,1812,1816,1820,1824,1828,1832,1836,1840,1844,1848,1852,1856,1860,1864,1868,1872,1876,1880,1884,1888,1892],{"title":1714,"path":1715,"stem":1716},"Вступ у програмування та алгоритми","\u002Fcpp\u002Fintro-algorithms","02.cpp\u002F01.intro-algorithms",{"title":1718,"path":1719,"stem":1720},"Code Style: угоди про оформлення коду","\u002Fcpp\u002Fcode-style","02.cpp\u002F02.code-style",{"title":1722,"path":1723,"stem":1724},"Середовище розробки та перший проєкт","\u002Fcpp\u002Fide-setup","02.cpp\u002F03.ide-setup",{"title":1726,"path":1727,"stem":1728},"Вивід даних на екран","\u002Fcpp\u002Fdata-output","02.cpp\u002F04.data-output",{"title":1730,"path":1731,"stem":1732},"Типи даних, змінні та константи","\u002Fcpp\u002Fdata-types-variables","02.cpp\u002F05.data-types-variables",{"title":1734,"path":1735,"stem":1736},"Ввід даних з клавіатури","\u002Fcpp\u002Fdata-input","02.cpp\u002F06.data-input",{"title":1738,"path":1739,"stem":1740},"Оператори, перетворення типів та логічні операції","\u002Fcpp\u002Foperators-type-conversion","02.cpp\u002F07.operators-type-conversion",{"title":1742,"path":1743,"stem":1744},"Цикли","\u002Fcpp\u002Floops","02.cpp\u002F08.loops",{"title":32,"path":1746,"stem":1747},"\u002Fcpp\u002Farrays","02.cpp\u002F09.arrays",{"title":1749,"path":1750,"stem":1751},"Алгоритми сортування та аналіз складності","\u002Fcpp\u002Fsorting","02.cpp\u002F10.sorting",{"title":1753,"path":1754,"stem":1755},"Алгоритми пошуку","\u002Fcpp\u002Fsearching","02.cpp\u002F11.searching",{"title":1757,"path":1758,"stem":1759},"Функції: основи","\u002Fcpp\u002Ffunctions-basics","02.cpp\u002F12.functions-basics",{"title":1761,"path":1762,"stem":1763},"Функції: прототипи, область видимості та додаткові можливості","\u002Fcpp\u002Ffunctions-scope","02.cpp\u002F13.functions-scope",{"title":1765,"path":1766,"stem":1767},"Функції: перевантаження та шаблони","\u002Fcpp\u002Ffunctions-overloading-templates","02.cpp\u002F14.functions-overloading-templates",{"title":1769,"path":1770,"stem":1771},"Вказівники: основи","\u002Fcpp\u002Fpointers-basics","02.cpp\u002F15.pointers-basics",{"title":1773,"path":1774,"stem":1775},"Посилання (References)","\u002Fcpp\u002Freferences","02.cpp\u002F16.references",{"title":1777,"path":1778,"stem":1779},"Вказівники, const і масиви","\u002Fcpp\u002Fpointers-const-arrays","02.cpp\u002F17.pointers-const-arrays",{"title":1781,"path":1782,"stem":1783},"Адресна арифметика","\u002Fcpp\u002Fpointer-arithmetic","02.cpp\u002F18.pointer-arithmetic",{"title":1785,"path":1786,"stem":1787},"Динамічна пам'ять","\u002Fcpp\u002Fdynamic-memory","02.cpp\u002F19.dynamic-memory",{"title":1789,"path":1790,"stem":1791},"Вказівники типу void","\u002Fcpp\u002Fvoid-pointers","02.cpp\u002F20.void-pointers",{"title":1793,"path":1794,"stem":1795},"Вказівники на вказівники","\u002Fcpp\u002Fpointers-to-pointers","02.cpp\u002F21.pointers-to-pointers",{"title":1797,"path":1798,"stem":1799},"Оператор доступу до членів через вказівник (->)","\u002Fcpp\u002Fmember-access-operator","02.cpp\u002F22.member-access-operator",{"title":1801,"path":1802,"stem":1803},"Цикл for-each (Range-based for)","\u002Fcpp\u002Fforeach-loop","02.cpp\u002F23.foreach-loop",{"title":1805,"path":1806,"stem":1807},"Вказівники на функції","\u002Fcpp\u002Ffunction-pointers","02.cpp\u002F24.function-pointers",{"title":1809,"path":1810,"stem":1811},"Лямбда-вирази","\u002Fcpp\u002Flambdas","02.cpp\u002F25.lambdas",{"title":1813,"path":1814,"stem":1815},"Лямбда-захоплення","\u002Fcpp\u002Flambda-captures","02.cpp\u002F26.lambda-captures",{"title":1817,"path":1818,"stem":1819},"Еліпсис","\u002Fcpp\u002Fellipsis","02.cpp\u002F27.ellipsis",{"title":1821,"path":1822,"stem":1823},"Безпечні альтернативи еліпсису","\u002Fcpp\u002F27a.ellipsis","02.cpp\u002F27a.ellipsis",{"title":1825,"path":1826,"stem":1827},"Аргументи командного рядка","\u002Fcpp\u002Fcommand-line-arguments","02.cpp\u002F28.command-line-arguments",{"title":1829,"path":1830,"stem":1831},"Перерахування (enum)","\u002Fcpp\u002Fenum","02.cpp\u002F29.enum",{"title":1833,"path":1834,"stem":1835},"Класи-перерахування (enum class)","\u002Fcpp\u002Fenum-class","02.cpp\u002F30.enum-class",{"title":1837,"path":1838,"stem":1839},"Псевдоніми типів (typedef і using)","\u002Fcpp\u002Ftype-aliases","02.cpp\u002F31.type-aliases",{"title":1841,"path":1842,"stem":1843},"Системи числення та двійкова арифметика","\u002Fcpp\u002Fnumber-systems","02.cpp\u002F32.number-systems",{"title":1845,"path":1846,"stem":1847},"Структури (struct): агрегування даних","\u002Fcpp\u002Fstruct","02.cpp\u002F33.struct",{"title":1849,"path":1850,"stem":1851},"Структури у функціях","\u002Fcpp\u002Fstruct-functions","02.cpp\u002F34.struct-functions",{"title":1853,"path":1854,"stem":1855},"Масиви структур і вкладені структури","\u002Fcpp\u002Fstruct-arrays","02.cpp\u002F35.struct-arrays",{"title":1857,"path":1858,"stem":1859},"Патерни struct та межі застосування","\u002Fcpp\u002Fstruct-patterns","02.cpp\u002F36.struct-patterns",{"title":1861,"path":1862,"stem":1863},"Символи та таблиця ASCII","\u002Fcpp\u002Fascii-characters","02.cpp\u002F37.ascii-characters",{"title":1865,"path":1866,"stem":1867},"Unicode та кодування UTF","\u002Fcpp\u002Funicode-utf","02.cpp\u002F38.unicode-utf",{"title":1869,"path":1870,"stem":1871},"C-style рядки","\u002Fcpp\u002Fc-strings","02.cpp\u002F39.c-strings",{"title":1873,"path":1874,"stem":1875},"Вступ до std::string","\u002Fcpp\u002Fstd-string-intro","02.cpp\u002F40.std-string-intro",{"title":1877,"path":1878,"stem":1879},"Довжина, ємність та доступ до символів std::string","\u002Fcpp\u002Fstd-string-capacity-access","02.cpp\u002F41.std-string-capacity-access",{"title":1881,"path":1882,"stem":1883},"Модифікація std::string: присвоювання, додавання, вставка, видалення та заміна","\u002Fcpp\u002Fstd-string-modification","02.cpp\u002F42.std-string-modification",{"title":1885,"path":1886,"stem":1887},"Пошук у std::string: find, npos та практичні патерни","\u002Fcpp\u002Fstd-string-search","02.cpp\u002F43.std-string-search",{"title":1889,"path":1890,"stem":1891},"std::string_view: невласницький погляд на рядок без копіювання","\u002Fcpp\u002Fstd-string-view","02.cpp\u002F44.std-string-view",{"title":1893,"path":1894,"stem":1895},"План навчання: Курс C++ — Продовження (Статті 29–60+)","\u002Fcpp\u002Fcurriculum-plan","02.cpp\u002Fcurriculum-plan",{"title":1897,"icon":1898,"path":1899,"stem":1900,"children":1901,"page":59},"JavaScript","i-devicon-javascript","\u002Fjavascript","03.javascript",[1902,1928,1982,2004,2308,2346],{"title":1903,"icon":1904,"path":1905,"stem":1906,"children":1907,"page":59},"Events","i-lucide-mouse-pointer-click","\u002Fjavascript\u002Fevents","03.javascript\u002F01.events",[1908,1912,1916,1920,1924],{"title":1909,"path":1910,"stem":1911},"Вступ до подій браузера","\u002Fjavascript\u002Fevents\u002Fintro","03.javascript\u002F01.events\u002F01.intro",{"title":1913,"path":1914,"stem":1915},"Бульбашковий механізм (Bubbling) та занурення (Capturing)","\u002Fjavascript\u002Fevents\u002Fbubbling-capturing","03.javascript\u002F01.events\u002F02.bubbling-capturing",{"title":1917,"path":1918,"stem":1919},"Делегування подій (Event Delegation)","\u002Fjavascript\u002Fevents\u002Fdelegate-events","03.javascript\u002F01.events\u002F03.delegate-events",{"title":1921,"path":1922,"stem":1923},"Типові дії браузера та preventDefault()","\u002Fjavascript\u002Fevents\u002Fprevent-default","03.javascript\u002F01.events\u002F04.prevent-default",{"title":1925,"path":1926,"stem":1927},"Запуск користувацьких подій (Custom Events)","\u002Fjavascript\u002Fevents\u002Fcustom-events","03.javascript\u002F01.events\u002F05.custom-events",{"title":1929,"icon":1930,"path":1931,"stem":1932,"children":1933,"page":59},"Network","i-lucide-globe","\u002Fjavascript\u002Fnetwork","03.javascript\u002F02.network",[1934,1938,1942,1946,1950,1954,1958,1962,1966,1970,1974,1978],{"title":1935,"path":1936,"stem":1937},"Fetch API - Сучасний підхід до HTTP-запитів","\u002Fjavascript\u002Fnetwork\u002F01-fetch-api","03.javascript\u002F02.network\u002F01-fetch-api",{"title":1939,"path":1940,"stem":1941},"FormData - Робота з формами та файлами","\u002Fjavascript\u002Fnetwork\u002F02-formdata","03.javascript\u002F02.network\u002F02-formdata",{"title":1943,"path":1944,"stem":1945},"Відстеження прогресу завантаження","\u002Fjavascript\u002Fnetwork\u002F03-download-progress","03.javascript\u002F02.network\u002F03-download-progress",{"title":1947,"path":1948,"stem":1949},"Переривання fetch-запитів","\u002Fjavascript\u002Fnetwork\u002F04-abort-requests","03.javascript\u002F02.network\u002F04-abort-requests",{"title":1951,"path":1952,"stem":1953},"CORS - Запити між різними джерелами","\u002Fjavascript\u002Fnetwork\u002F05-cors","03.javascript\u002F02.network\u002F05-cors",{"title":1955,"path":1956,"stem":1957},"Fetch API - Повний довідник опцій","\u002Fjavascript\u002Fnetwork\u002F06-fetch-options","03.javascript\u002F02.network\u002F06-fetch-options",{"title":1959,"path":1960,"stem":1961},"URL Objects - Робота з посиланнями","\u002Fjavascript\u002Fnetwork\u002F07-url-objects","03.javascript\u002F02.network\u002F07-url-objects",{"title":1963,"path":1964,"stem":1965},"XMLHttpRequest - AJAX та низькорівневі запити","\u002Fjavascript\u002Fnetwork\u002F08-xmlhttprequest","03.javascript\u002F02.network\u002F08-xmlhttprequest",{"title":1967,"path":1968,"stem":1969},"Відновлюване завантаження файлів","\u002Fjavascript\u002Fnetwork\u002F09-resumable-upload","03.javascript\u002F02.network\u002F09-resumable-upload",{"title":1971,"path":1972,"stem":1973},"Cookies, document.cookie та світ після \"Cookiepocalypse\"","\u002Fjavascript\u002Fnetwork\u002F10-cookies","03.javascript\u002F02.network\u002F10-cookies",{"title":1975,"path":1976,"stem":1977},"js-cookie: Керування Cookies без Болю","\u002Fjavascript\u002Fnetwork\u002F11-js-cookie","03.javascript\u002F02.network\u002F11-js-cookie",{"title":1979,"path":1980,"stem":1981},"Axios: Потужний HTTP-клієнт для JavaScript","\u002Fjavascript\u002Fnetwork\u002F12-axios","03.javascript\u002F02.network\u002F12-axios",{"title":1983,"icon":1984,"path":1985,"stem":1986,"children":1987,"page":59},"Bom","i-lucide-monitor","\u002Fjavascript\u002Fbom","03.javascript\u002F03.bom",[1988,1992,1996,2000],{"title":1989,"path":1990,"stem":1991},"LocalStorage, SessionStorage та patterns збереження даних","\u002Fjavascript\u002Fbom\u002F01-localstorage","03.javascript\u002F03.bom\u002F01-localstorage",{"title":1993,"path":1994,"stem":1995},"Location Object - Керування адресою сторінки","\u002Fjavascript\u002Fbom\u002F02-location-object","03.javascript\u002F03.bom\u002F02-location-object",{"title":1997,"path":1998,"stem":1999},"History API - Керування історією браузера","\u002Fjavascript\u002Fbom\u002F03-history-api","03.javascript\u002F03.bom\u002F03-history-api",{"title":2001,"path":2002,"stem":2003},"Navigator Object - Ідентифікація та Можливості Пристрою","\u002Fjavascript\u002Fbom\u002F04-navigator-object","03.javascript\u002F03.bom\u002F04-navigator-object",{"title":2005,"icon":2006,"path":2007,"stem":2008,"children":2009},"React","i-devicon-react","\u002Fjavascript\u002Freact","03.javascript\u002F04.react\u002Findex",[2010,2011,2015,2019,2023,2027,2090,2125,2277],{"title":2005,"path":2007,"stem":2008},{"title":2012,"path":2013,"stem":2014},"Робота з Формами в React","\u002Fjavascript\u002Freact\u002Freact-forms","03.javascript\u002F04.react\u002F01.react-forms",{"title":2016,"path":2017,"stem":2018},"React Hook Form: Професійна Робота з Формами","\u002Fjavascript\u002Freact\u002Freact-hook-form","03.javascript\u002F04.react\u002F02.react-hook-form",{"title":2020,"path":2021,"stem":2022},"React Hook Form: Глибоке Розуміння Архітектури та Оптимізації","\u002Fjavascript\u002Freact\u002Freact-hook-form-new","03.javascript\u002F04.react\u002F02.react-hook-form-new",{"title":2024,"path":2025,"stem":2026},"Axios та React: Професійна Архітектура Запитів","\u002Fjavascript\u002Freact\u002Fdata-fetching-axios","03.javascript\u002F04.react\u002F03.data-fetching-axios",{"title":2028,"icon":132,"path":2029,"stem":2030,"children":2031},"Tanstack Query","\u002Fjavascript\u002Freact\u002Ftanstack-query","03.javascript\u002F04.react\u002F04.tanstack-query\u002Findex",[2032,2034,2038,2042,2046,2050,2054,2058,2062,2066,2070,2074,2078,2082,2086],{"title":2033,"path":2029,"stem":2030},"TanStack Query: Майстерність Керування Станом Сервера",{"title":2035,"path":2036,"stem":2037},"Парадигма Server State: Чому useEffect недостатньо","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-state-paradigm","03.javascript\u002F04.react\u002F04.tanstack-query\u002F01.server-state-paradigm",{"title":2039,"path":2040,"stem":2041},"Встановлення та Налаштування: Фундамент","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Finstallation-and-devtools","03.javascript\u002F04.react\u002F04.tanstack-query\u002F02.installation-and-devtools",{"title":2043,"path":2044,"stem":2045},"Основи Запитів та Магія Ключів","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fquery-basics-and-keys","03.javascript\u002F04.react\u002F04.tanstack-query\u002F03.query-basics-and-keys",{"title":2047,"path":2048,"stem":2049},"Синхронізація Даних: Життєвий Цикл Запиту","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fdata-synchronization","03.javascript\u002F04.react\u002F04.tanstack-query\u002F04.data-synchronization",{"title":2051,"path":2052,"stem":2053},"Мутації та Інвалідація: Зміна Даних","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fmutations-and-invalidation","03.javascript\u002F04.react\u002F04.tanstack-query\u002F05.mutations-and-invalidation",{"title":2055,"path":2056,"stem":2057},"Оптимістичні Оновлення: Швидше за Світло","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Foptimistic-updates","03.javascript\u002F04.react\u002F04.tanstack-query\u002F06.optimistic-updates",{"title":2059,"path":2060,"stem":2061},"Пагінація та Infinite Scroll","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fpagination-and-load-more","03.javascript\u002F04.react\u002F04.tanstack-query\u002F07.pagination-and-load-more",{"title":2063,"path":2064,"stem":2065},"Просунуті Патерни та Оптимізація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F04.tanstack-query\u002F08.advanced-patterns",{"title":2067,"path":2068,"stem":2069},"Архітектура та Best Practices","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Farchitecture-and-best-practices","03.javascript\u002F04.react\u002F04.tanstack-query\u002F09.architecture-and-best-practices",{"title":2071,"path":2072,"stem":2073},"Server-Side Rendering (SSR) та Гідратація","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fserver-side-rendering","03.javascript\u002F04.react\u002F04.tanstack-query\u002F10.server-side-rendering",{"title":2075,"path":2076,"stem":2077},"Стратегії Тестування","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Ftesting-strategies","03.javascript\u002F04.react\u002F04.tanstack-query\u002F11.testing-strategies",{"title":2079,"path":2080,"stem":2081},"Аутентифікація та Обробка Помилок","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fauthentication-and-errors","03.javascript\u002F04.react\u002F04.tanstack-query\u002F12.authentication-and-errors",{"title":2083,"path":2084,"stem":2085},"React Suspense та Майбутнє","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Freact-suspense","03.javascript\u002F04.react\u002F04.tanstack-query\u002F13.react-suspense",{"title":2087,"path":2088,"stem":2089},"Глибоке Занурення в Продуктивність","\u002Fjavascript\u002Freact\u002Ftanstack-query\u002Fperformance-deep-dive","03.javascript\u002F04.react\u002F04.tanstack-query\u002F14.performance-deep-dive",{"title":2091,"icon":2006,"path":2092,"stem":2093,"children":2094},"React Router","\u002Fjavascript\u002Freact\u002Freact-router","03.javascript\u002F04.react\u002F05.react-router\u002Findex",[2095,2097,2101,2105,2109,2113,2117,2121],{"title":2096,"path":2092,"stem":2093},"React Router: Навігаційна система сучасного вебу",{"title":2098,"path":2099,"stem":2100},"Налаштування та Базовий Роутинг","\u002Fjavascript\u002Freact\u002Freact-router\u002Fsetup-and-basic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F01.setup-and-basic-routing",{"title":2102,"path":2103,"stem":2104},"Динамічна Навігація","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnavigation-and-links","03.javascript\u002F04.react\u002F05.react-router\u002F02.navigation-and-links",{"title":2106,"path":2107,"stem":2108},"Вкладені Маршрути та Макети","\u002Fjavascript\u002Freact\u002Freact-router\u002Fnested-routes-and-layouts","03.javascript\u002F04.react\u002F05.react-router\u002F03.nested-routes-and-layouts",{"title":2110,"path":2111,"stem":2112},"Динамічні Маршрути та Параметри","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdynamic-routing","03.javascript\u002F04.react\u002F05.react-router\u002F04.dynamic-routing",{"title":2114,"path":2115,"stem":2116},"Data APIs: Loaders та Actions","\u002Fjavascript\u002Freact\u002Freact-router\u002Fdata-loading","03.javascript\u002F04.react\u002F05.react-router\u002F05.data-loading",{"title":2118,"path":2119,"stem":2120},"Просунуті Патерни","\u002Fjavascript\u002Freact\u002Freact-router\u002Fadvanced-patterns","03.javascript\u002F04.react\u002F05.react-router\u002F06.advanced-patterns",{"title":2122,"path":2123,"stem":2124},"Legacy Routing: Компонентний підхід","\u002Fjavascript\u002Freact\u002Freact-router\u002Flegacy-routing","03.javascript\u002F04.react\u002F05.react-router\u002F07.legacy-routing",{"title":2126,"icon":132,"path":2127,"stem":2128,"children":2129},"Redux","\u002Fjavascript\u002Freact\u002Fredux","03.javascript\u002F04.react\u002F06.redux\u002Findex",[2130,2132,2148,2177,2186,2207,2223,2252],{"title":2131,"path":2127,"stem":2128},"Redux: Еволюція управління станом",{"title":14,"icon":15,"path":2133,"stem":2134,"children":2135,"page":59},"\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals",[2136,2140,2144],{"title":2137,"path":2138,"stem":2139},"Вступ до State Management","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fintro-state-management","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F01.intro-state-management",{"title":2141,"path":2142,"stem":2143},"Філософія Redux та Три Принципи","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fredux-philosophy","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F02.redux-philosophy",{"title":2145,"path":2146,"stem":2147},"Чисті функції та Іммутабельність","\u002Fjavascript\u002Freact\u002Fredux\u002Ffundamentals\u002Fpure-functions-immutability","03.javascript\u002F04.react\u002F06.redux\u002F01.fundamentals\u002F03.pure-functions-immutability",{"title":2149,"icon":132,"path":2150,"stem":2151,"children":2152,"page":59},"Classic Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux",[2153,2157,2161,2165,2169,2173],{"title":2154,"path":2155,"stem":2156},"Створення Store (Classic Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fstore-setup","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F01.store-setup",{"title":2158,"path":2159,"stem":2160},"Actions, Constants та Action Creators","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Factions-constants","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F02.actions-constants",{"title":2162,"path":2163,"stem":2164},"Логіка Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freducers","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F03.reducers",{"title":2166,"path":2167,"stem":2168},"Комбінування Reducers (Root Reducer)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fdata-flow","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F04.data-flow",{"title":2170,"path":2171,"stem":2172},"Підключення до React (React-Redux)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Freact-redux-connection","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F05.react-redux-connection",{"title":2174,"path":2175,"stem":2176},"Middleware та Асинхронність (Redux Thunk)","\u002Fjavascript\u002Freact\u002Fredux\u002Fclassic-redux\u002Fmiddleware-thunk","03.javascript\u002F04.react\u002F06.redux\u002F02.classic-redux\u002F06.middleware-thunk",{"title":2178,"icon":132,"path":2179,"stem":2180,"children":2181,"page":59},"Transition To Rtk","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk",[2182],{"title":2183,"path":2184,"stem":2185},"Проблеми класичного Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftransition-to-rtk\u002Fproblems-with-classic","03.javascript\u002F04.react\u002F06.redux\u002F03.transition-to-rtk\u002F01.problems-with-classic",{"title":2187,"icon":132,"path":2188,"stem":2189,"children":2190,"page":59},"Redux Toolkit","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit",[2191,2195,2199,2203],{"title":2192,"path":2193,"stem":2194},"Налаштування Store з configureStore","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fconfigure-store","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F01.configure-store",{"title":2196,"path":2197,"stem":2198},"createSlice: Революція в Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fcreate-slice","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F02.create-slice",{"title":2200,"path":2201,"stem":2202},"Асинхронність з createAsyncThunk","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fasync-thunks","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F03.async-thunks",{"title":2204,"path":2205,"stem":2206},"04. Entity Adapter: Керування нормалізованим станом","\u002Fjavascript\u002Freact\u002Fredux\u002Fredux-toolkit\u002Fentity-adapter","03.javascript\u002F04.react\u002F06.redux\u002F04.redux-toolkit\u002F04.entity-adapter",{"title":2208,"icon":92,"path":2209,"stem":2210,"children":2211,"page":59},"Advanced","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced",[2212,2216,2220],{"title":2213,"path":2214,"stem":2215},"Мемоізація та Селектори: Повний Гайд по Reselect","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Fselectors-reselect","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F01.selectors-reselect",{"title":2217,"path":2218,"stem":2219},"RTK Query: Архітектура Серверного Кешу","\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Frtk-query-intro","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F02.rtk-query-intro",{"title":2067,"path":2221,"stem":2222},"\u002Fjavascript\u002Freact\u002Fredux\u002Fadvanced\u002Farchitecture-best-practices","03.javascript\u002F04.react\u002F06.redux\u002F05.advanced\u002F03.architecture-best-practices",{"title":2224,"icon":132,"path":2225,"stem":2226,"children":2227,"page":59},"Project Kanban","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban",[2228,2232,2236,2240,2244,2248],{"title":2229,"path":2230,"stem":2231},"Проєкт: Kanban Board (Trello Clone)","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fproject-overview","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F01.project-overview",{"title":2233,"path":2234,"stem":2235},"Налаштування та Типізація","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fsetup-and-types","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F02.setup-and-types",{"title":2237,"path":2238,"stem":2239},"Board Slice: Серце Дошки","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fboard-slice","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F03.board-slice",{"title":2241,"path":2242,"stem":2243},"Логіка Drag & Drop","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Fdrag-and-drop-logic","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F04.drag-and-drop-logic",{"title":2245,"path":2246,"stem":2247},"Інтеграція з RTK Query","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Frtk-query-integration","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F05.rtk-query-integration",{"title":2249,"path":2250,"stem":2251},"Optimistic Updates","\u002Fjavascript\u002Freact\u002Fredux\u002Fproject-kanban\u002Foptimistic-updates","03.javascript\u002F04.react\u002F06.redux\u002F06.project-kanban\u002F06.optimistic-updates",{"title":2253,"icon":132,"path":2254,"stem":2255,"children":2256,"page":59},"Testing","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting","03.javascript\u002F04.react\u002F06.redux\u002F07.testing",[2257,2261,2265,2269,2273],{"title":2258,"path":2259,"stem":2260},"Тестування Redux","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Fintro-testing","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F01.intro-testing",{"title":2262,"path":2263,"stem":2264},"Тестування Reducers","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-reducers","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F02.testing-reducers",{"title":2266,"path":2267,"stem":2268},"Тестування Селекторів","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-selectors","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F03.testing-selectors",{"title":2270,"path":2271,"stem":2272},"Тестування Компонентів (Integration)","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-components","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F04.testing-components",{"title":2274,"path":2275,"stem":2276},"Тестування Async Thunks","\u002Fjavascript\u002Freact\u002Fredux\u002Ftesting\u002Ftesting-thunks","03.javascript\u002F04.react\u002F06.redux\u002F07.testing\u002F05.testing-thunks",{"title":2278,"icon":132,"path":2279,"stem":2280,"children":2281},"Ui Libraries","\u002Fjavascript\u002Freact\u002Fui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002Findex",[2282,2284,2288,2292,2296,2300,2304],{"title":2283,"path":2279,"stem":2280},"UI Бібліотеки в React",{"title":2285,"path":2286,"stem":2287},"Вступ до UI Бібліотек: Навіщо Винаходити Велосипед Двічі?","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fintroduction-to-ui-libraries","03.javascript\u002F04.react\u002F07.ui-libraries\u002F01.introduction-to-ui-libraries",{"title":2289,"path":2290,"stem":2291},"Філософія shadcn\u002Fui: \"Not a Component Library\"","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-philosophy","03.javascript\u002F04.react\u002F07.ui-libraries\u002F02.shadcn-philosophy",{"title":2293,"path":2294,"stem":2295},"Установка та Налаштування shadcn\u002Fui","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-installation","03.javascript\u002F04.react\u002F07.ui-libraries\u002F03.shadcn-installation",{"title":2297,"path":2298,"stem":2299},"Базові Компоненти shadcn\u002Fui: Фундамент Інтерфейсу","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-basics","03.javascript\u002F04.react\u002F07.ui-libraries\u002F04.shadcn-components-basics",{"title":2301,"path":2302,"stem":2303},"Компоненти Форм: Побудова Інтерактивних Form","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-forms","03.javascript\u002F04.react\u002F07.ui-libraries\u002F05.shadcn-components-forms",{"title":2305,"path":2306,"stem":2307},"Складні Компоненти: Dialog, Dropdown, Table та Command","\u002Fjavascript\u002Freact\u002Fui-libraries\u002Fshadcn-components-advanced","03.javascript\u002F04.react\u002F07.ui-libraries\u002F06.shadcn-components-advanced",{"title":2309,"icon":2310,"path":2311,"stem":2312,"children":2313,"page":59},"TypeScript","i-devicon-typescript","\u002Fjavascript\u002Ftypescript","03.javascript\u002F05.typescript",[2314,2318,2322,2326,2330,2334,2338,2342],{"title":2315,"path":2316,"stem":2317},"TypeScript: Броня для вашого коду","\u002Fjavascript\u002Ftypescript\u002Fintro-and-basic-types","03.javascript\u002F05.typescript\u002F01.intro-and-basic-types",{"title":2319,"path":2320,"stem":2321},"Майстерність Моделювання Даних: Інтерфейси та Просунуті Типи","\u002Fjavascript\u002Ftypescript\u002Finterfaces-and-advanced-types","03.javascript\u002F05.typescript\u002F02.interfaces-and-advanced-types",{"title":2323,"path":2324,"stem":2325},"Алхімія Типів: Generics та Utility Types","\u002Fjavascript\u002Ftypescript\u002Fgenerics-and-utilities","03.javascript\u002F05.typescript\u002F03.generics-and-utilities",{"title":2327,"path":2328,"stem":2329},"Архітектура та Шаблони: Класи в TypeScript","\u002Fjavascript\u002Ftypescript\u002Fclasses-and-oop","03.javascript\u002F05.typescript\u002F04.classes-and-oop",{"title":2331,"path":2332,"stem":2333},"Продакшн та Екосистема: Advanced Config & Workflow","\u002Fjavascript\u002Ftypescript\u002Fadvanced-patterns-and-config","03.javascript\u002F05.typescript\u002F05.advanced-patterns-and-config",{"title":2335,"path":2336,"stem":2337},"TypeScript у світі React","\u002Fjavascript\u002Ftypescript\u002Freact-basics","03.javascript\u002F05.typescript\u002F06.react-basics",{"title":2339,"path":2340,"stem":2341},"React + TypeScript: Продвинуті патерни","\u002Fjavascript\u002Ftypescript\u002Freact-advanced","03.javascript\u002F05.typescript\u002F07.react-advanced",{"title":2343,"path":2344,"stem":2345},"React + TypeScript: Екосистема та бібліотеки","\u002Fjavascript\u002Ftypescript\u002Freact-ecosystem","03.javascript\u002F05.typescript\u002F08.react-ecosystem",{"title":2347,"path":2348,"stem":2349},"Atomic Design","\u002Fjavascript\u002Fatomic-design","03.javascript\u002F2.atomic-design",{"title":2351,"icon":2352,"path":2353,"stem":2354,"children":2355,"page":59},"Java","i-devicon-java","\u002Fjava","04.java",[2356,2359,2362,2366,2370,2374,2378],{"title":162,"path":2357,"stem":2358},"\u002Fjava\u002Fdata-mapper-part1","04.java\u002F01.data-mapper-part1",{"title":166,"path":2360,"stem":2361},"\u002Fjava\u002Fdata-mapper-part2","04.java\u002F02.data-mapper-part2",{"title":2363,"path":2364,"stem":2365},"Service Layer: Організація бізнес-логіки","\u002Fjava\u002Fservice-layer","04.java\u002F03.service-layer",{"title":2367,"path":2368,"stem":2369},"Rich Domain Model та State Pattern","\u002Fjava\u002Frich-domain-model","04.java\u002F04.rich-domain-model",{"title":2371,"path":2372,"stem":2373},"Патерни для складної бізнес-логіки","\u002Fjava\u002Fbusiness-logic-patterns","04.java\u002F05.business-logic-patterns",{"title":2375,"path":2376,"stem":2377},"Обробка помилок та валідація","\u002Fjava\u002Ferror-handling-validation","04.java\u002F06.error-handling-validation",{"title":2379,"path":2380,"stem":2381,"children":2382,"page":59},"Проектування баз даних","\u002Fjava\u002Fpr2","04.java\u002Fpr2",[2383,2387,2391,2395,2399,2403,2407,2411,2415,2419,2423,2427,2431,2435,2439,2443,2447,2451,2455,2459,2463,2467,2471,2475,2479,2483,2487,2491,2495,2499,2503,2507,2511,2515,2519,2523,2527],{"title":2384,"path":2385,"stem":2386},"Концептуальне моделювання: Мистецтво розуміння предметної області","\u002Fjava\u002Fpr2\u002Fconceptual-modeling","04.java\u002Fpr2\u002F01.conceptual-modeling",{"title":2388,"path":2389,"stem":2390},"Логічне моделювання: Від бізнес-ідей до структур даних","\u002Fjava\u002Fpr2\u002Flogical-modeling","04.java\u002Fpr2\u002F02.logical-modeling",{"title":2392,"path":2393,"stem":2394},"Нормалізація: Гігієна даних та боротьба з аномаліями","\u002Fjava\u002Fpr2\u002Fnormalization","04.java\u002Fpr2\u002F03.normalization",{"title":2396,"path":2397,"stem":2398},"Фізична схема: Від абстракції до DDL","\u002Fjava\u002Fpr2\u002Fphysical-schema","04.java\u002Fpr2\u002F04.physical-schema",{"title":2400,"path":2401,"stem":2402},"Архітектурна класифікація таблиць","\u002Fjava\u002Fpr2\u002Ftable-classification","04.java\u002Fpr2\u002F05.table-classification",{"title":2404,"path":2405,"stem":2406},"Database Migrations: Версіонування схеми з Flyway","\u002Fjava\u002Fpr2\u002Fdatabase-migrations","04.java\u002Fpr2\u002F06.database-migrations",{"title":2408,"path":2409,"stem":2410},"А що, якби це була не реляційна БД?","\u002Fjava\u002Fpr2\u002Fbeyond-relational","04.java\u002Fpr2\u002F07.beyond-relational",{"title":2412,"path":2413,"stem":2414},"Object-Relational Impedance Mismatch: Два світи, що не хочуть дружити","\u002Fjava\u002Fpr2\u002Fimpedance-mismatch","04.java\u002Fpr2\u002F09.impedance-mismatch",{"title":2416,"path":2417,"stem":2418},"JDBC: Перший контакт із базою даних","\u002Fjava\u002Fpr2\u002Fjdbc-fundamentals","04.java\u002Fpr2\u002F10.jdbc-fundamentals",{"title":2420,"path":2421,"stem":2422},"Якість коду: Spotless, SpotBugs та SonarQube","\u002Fjava\u002Fpr2\u002F10a.code-quality","04.java\u002Fpr2\u002F10a.code-quality",{"title":2424,"path":2425,"stem":2426},"Connection Pool: Патерн Object Pool для JDBC-з'єднань","\u002Fjava\u002Fpr2\u002Fconnection-pool","04.java\u002Fpr2\u002F11.connection-pool",{"title":2428,"path":2429,"stem":2430},"Row Data Gateway: Об'єкт як обгортка рядка таблиці","\u002Fjava\u002Fpr2\u002Frow-data-gateway","04.java\u002Fpr2\u002F12.row-data-gateway",{"title":2432,"path":2433,"stem":2434},"Table Data Gateway: Фасад таблиці як архітектурний відступ","\u002Fjava\u002Fpr2\u002Ftable-data-gateway","04.java\u002Fpr2\u002F13.table-data-gateway",{"title":2436,"path":2437,"stem":2438},"Repository + Data Mapper: Правильна шарова архітектура з JDBC","\u002Fjava\u002Fpr2\u002Frepository-data-mapper","04.java\u002Fpr2\u002F14.repository-data-mapper",{"title":2440,"path":2441,"stem":2442},"Identity Map: Кешування сутностей у рамках сесії","\u002Fjava\u002Fpr2\u002Fidentity-map","04.java\u002Fpr2\u002F15.identity-map",{"title":2444,"path":2445,"stem":2446},"Unit of Work: Відстеження змін і координація JDBC-транзакцій","\u002Fjava\u002Fpr2\u002Funit-of-work","04.java\u002Fpr2\u002F16.unit-of-work",{"title":2448,"path":2449,"stem":2450},"Strategy: Замінювані SQL-стратегії для підтримки різних СУБД","\u002Fjava\u002Fpr2\u002Fstrategy-sql","04.java\u002Fpr2\u002F17.strategy-sql",{"title":2452,"path":2453,"stem":2454},"Proxy: Lazy Loading для One-To-Many колекцій","\u002Fjava\u002Fpr2\u002Fproxy-lazy-loading","04.java\u002Fpr2\u002F18.proxy-lazy-loading",{"title":2456,"path":2457,"stem":2458},"Generic Repository через Java Reflection: анотації та динамічний SQL","\u002Fjava\u002Fpr2\u002Fgeneric-repository-reflection","04.java\u002Fpr2\u002F19.generic-repository-reflection",{"title":2460,"path":2461,"stem":2462},"Specification Pattern: Композиція бізнес-правил для складних запитів","\u002Fjava\u002Fpr2\u002Fspecification-pattern","04.java\u002Fpr2\u002F20.specification-pattern",{"title":2464,"path":2465,"stem":2466},"Розширені можливості Specification Pattern: підзапити, агрегації та гібридний підхід","\u002Fjava\u002Fpr2\u002F20a.advanced-specifications","04.java\u002Fpr2\u002F20a.advanced-specifications",{"title":2468,"path":2469,"stem":2470},"Асинхронність у JDBC: Від блокуючих викликів до CompletableFuture","\u002Fjava\u002Fpr2\u002Fasynchronous-jdbc","04.java\u002Fpr2\u002F21.asynchronous-jdbc",{"title":2472,"path":2473,"stem":2474},"Інтеграційне тестування JDBC-репозиторіїв: Embedded H2 та патерн AAA","\u002Fjava\u002Fpr2\u002Fintegration-testing-h2","04.java\u002Fpr2\u002F22.integration-testing-h2",{"title":2476,"path":2477,"stem":2478},"Testcontainers: Тестування з реальною PostgreSQL у Docker-контейнерах","\u002Fjava\u002Fpr2\u002Fintegration-testing-testcontainers","04.java\u002Fpr2\u002F23.integration-testing-testcontainers",{"title":2480,"path":2481,"stem":2482},"Google Guice: Впровадження залежностей у JavaFX-проєкті","\u002Fjava\u002Fpr2\u002Fdependency-injection-guice","04.java\u002Fpr2\u002F24.dependency-injection-guice",{"title":2484,"path":2485,"stem":2486},"JavaFX: Основи побудови графічних інтерфейсів","\u002Fjava\u002Fpr2\u002Fjavafx-fundamentals","04.java\u002Fpr2\u002F25.javafx-fundamentals",{"title":2488,"path":2489,"stem":2490},"Properties та Bindings: Реактивність у JavaFX","\u002Fjava\u002Fpr2\u002Fjavafx-properties-bindings","04.java\u002Fpr2\u002F26.javafx-properties-bindings",{"title":2492,"path":2493,"stem":2494},"MVC vs MVP vs MVVM: Еволюція архітектурних патернів UI","\u002Fjava\u002Fpr2\u002Fui-architecture-patterns","04.java\u002Fpr2\u002F27.ui-architecture-patterns",{"title":2496,"path":2497,"stem":2498},"MVVM на практиці: Побудова ViewModel","\u002Fjava\u002Fpr2\u002Fmvvm-viewmodel-implementation","04.java\u002Fpr2\u002F28.mvvm-viewmodel-implementation",{"title":2500,"path":2501,"stem":2502},"View та Controller: Зв'язування з ViewModel через FXML","\u002Fjava\u002Fpr2\u002Fmvvm-view-controller","04.java\u002Fpr2\u002F29.mvvm-view-controller",{"title":2504,"path":2505,"stem":2506},"Інтеграція MVVM з Guice: Автоматична ін'єкція залежностей","\u002Fjava\u002Fpr2\u002Fmvvm-guice-integration","04.java\u002Fpr2\u002F30.mvvm-guice-integration",{"title":2508,"path":2509,"stem":2510},"Валідація та обробка помилок у MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-validation-error-handling","04.java\u002Fpr2\u002F31.mvvm-validation-error-handling",{"title":2512,"path":2513,"stem":2514},"Навігація та управління екранами у JavaFX MVVM","\u002Fjava\u002Fpr2\u002Fmvvm-navigation-screen-management","04.java\u002Fpr2\u002F32.mvvm-navigation-screen-management",{"title":2516,"path":2517,"stem":2518},"Тестування JavaFX MVVM-додатків","\u002Fjava\u002Fpr2\u002Fmvvm-testing","04.java\u002Fpr2\u002F33.mvvm-testing",{"title":2520,"path":2521,"stem":2522},"Стилізація та теми у JavaFX: CSS та User Experience","\u002Fjava\u002Fpr2\u002Fjavafx-styling-themes","04.java\u002Fpr2\u002F34.javafx-styling-themes",{"title":2524,"path":2525,"stem":2526},"AtlantaFX: Сучасні теми для JavaFX додатків","\u002Fjava\u002Fpr2\u002Fatlantafx-modern-themes","04.java\u002Fpr2\u002F35.atlantafx-modern-themes",{"title":2528,"path":2529,"stem":2530},"Пакування та розповсюдження JavaFX-додатків","\u002Fjava\u002Fpr2\u002Fjar-packaging-distribution","04.java\u002Fpr2\u002F36.jar-packaging-distribution",{"title":2532,"icon":2533,"path":2534,"stem":2535,"children":2536,"page":59},"Python","i-devicon-python","\u002Fpython","05.python",[2537,2541,2544,2548,2552,2556,2560,2564,2568],{"title":2538,"path":2539,"stem":2540},"Модулі, Пакети та Віртуальні Середовища","\u002Fpython\u002Fmodules-packages-venv","05.python\u002F00.modules-packages-venv",{"title":71,"path":2542,"stem":2543},"\u002Fpython\u002Fclasses-objects","05.python\u002F01.classes-objects",{"title":2545,"path":2546,"stem":2547},"Інкапсуляція, Керування Доступом та Властивості","\u002Fpython\u002Fencapsulation","05.python\u002F02.encapsulation",{"title":2549,"path":2550,"stem":2551},"Наслідування, MRO та суперсила super()","\u002Fpython\u002Finheritance-mro","05.python\u002F03.inheritance-mro",{"title":2553,"path":2554,"stem":2555},"Абстракція — ABC проти Статичних Протоколів (PEP 544)","\u002Fpython\u002Fabstraction-protocols","05.python\u002F04.abstraction-protocols",{"title":2557,"path":2558,"stem":2559},"Магічні методи (Dunder) та Емуляція протоколів","\u002Fpython\u002Fdunder-methods","05.python\u002F05.dunder-methods",{"title":2561,"path":2562,"stem":2563},"Декоратори та Керування життєвим циклом методів","\u002Fpython\u002Fdecorators-static-class","05.python\u002F06.decorators-static-class",{"title":2565,"path":2566,"stem":2567},"📦 Повний посібник з модулів, пакетів та віртуальних середовищ у Python","\u002Fpython\u002Flesson_9","05.python\u002Flesson_9",{"title":2569,"path":2570,"stem":2571},"[object Object]","\u002Fpython\u002Foop-plan","05.python\u002Foop-plan",{"title":2573,"icon":2574,"path":2575,"stem":2576,"children":2577,"page":59},"Бази даних","i-lucide-database","\u002Fdatabases","06.databases",[2578,2608,2631,2668,2697,2715,2749,2761,2770],{"title":2579,"icon":2580,"path":2581,"stem":2582,"children":2583,"page":59},"Intro","i-lucide-play","\u002Fdatabases\u002Fintro","06.databases\u002F01.intro",[2584,2588,2592,2596,2600,2604],{"title":2585,"path":2586,"stem":2587},"Введення в теорію баз даних","\u002Fdatabases\u002Fintro\u002Fintroduction-to-databases","06.databases\u002F01.intro\u002F01.introduction-to-databases",{"title":2589,"path":2590,"stem":2591},"Реляційна модель даних","\u002Fdatabases\u002Fintro\u002Frelational-model-theory","06.databases\u002F01.intro\u002F02.relational-model-theory",{"title":2593,"path":2594,"stem":2595},"ER-моделювання","\u002Fdatabases\u002Fintro\u002Fer-modeling","06.databases\u002F01.intro\u002F03.er-modeling",{"title":2597,"path":2598,"stem":2599},"Логічне проектування БД","\u002Fdatabases\u002Fintro\u002Flogical-schema","06.databases\u002F01.intro\u002F04.logical-schema",{"title":2601,"path":2602,"stem":2603},"Класифікація таблиць","\u002Fdatabases\u002Fintro\u002Ftable-classification","06.databases\u002F01.intro\u002F05.table-classification",{"title":2605,"path":2606,"stem":2607},"PlantUML для баз даних","\u002Fdatabases\u002Fintro\u002Fplantuml-diagrams","06.databases\u002F01.intro\u002F06.plantuml-diagrams",{"title":2609,"icon":2574,"path":2610,"stem":2611,"children":2612,"page":59},"MS SQL Server Start","\u002Fdatabases\u002Fms-sql-server-start","06.databases\u002F02.ms-sql-server-start",[2613,2617,2623,2627],{"title":2614,"path":2615,"stem":2616},"Типи даних у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fdata-types","06.databases\u002F02.ms-sql-server-start\u002F01.data-types",{"title":2618,"path":2619,"stem":2620,"children":2621},"Індекси у MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-indexes","06.databases\u002F02.ms-sql-server-start\u002F02.sql-indexes",[2622],{"title":2618,"path":2619,"stem":2620},{"title":2624,"path":2625,"stem":2626},"Системні бази даних MS SQL Server","\u002Fdatabases\u002Fms-sql-server-start\u002Fsystem-databases","06.databases\u002F02.ms-sql-server-start\u002F03.system-databases",{"title":2628,"path":2629,"stem":2630},"Огляд мови SQL та запитів","\u002Fdatabases\u002Fms-sql-server-start\u002Fsql-queries-overview","06.databases\u002F02.ms-sql-server-start\u002F04.sql-queries-overview",{"title":2632,"icon":2574,"path":2633,"stem":2634,"children":2635,"page":59},"SQL","\u002Fdatabases\u002Fsql","06.databases\u002F03.sql",[2636,2640,2644,2648,2652,2656,2660,2664],{"title":2637,"path":2638,"stem":2639},"Налаштування демонстраційної бази даних","\u002Fdatabases\u002Fsql\u002Fsample-database-setup","06.databases\u002F03.sql\u002F00.sample-database-setup",{"title":2641,"path":2642,"stem":2643},"DDL - Створення таблиць (CREATE TABLE)","\u002Fdatabases\u002Fsql\u002Fddl-create-table","06.databases\u002F03.sql\u002F01.ddl-create-table",{"title":2645,"path":2646,"stem":2647},"DDL - Зміна та видалення таблиць (ALTER, DROP)","\u002Fdatabases\u002Fsql\u002Fddl-alter-drop-table","06.databases\u002F03.sql\u002F02.ddl-alter-drop-table",{"title":2649,"path":2650,"stem":2651},"SELECT запити - Основи","\u002Fdatabases\u002Fsql\u002Fselect-queries-fundamentals","06.databases\u002F03.sql\u002F03.select-queries-fundamentals",{"title":2653,"path":2654,"stem":2655},"SELECT запити - Розширені можливості","\u002Fdatabases\u002Fsql\u002Fselect-queries-advanced","06.databases\u002F03.sql\u002F04.select-queries-advanced",{"title":2657,"path":2658,"stem":2659},"INSERT запити - Додавання даних","\u002Fdatabases\u002Fsql\u002Finsert-queries","06.databases\u002F03.sql\u002F05.insert-queries",{"title":2661,"path":2662,"stem":2663},"UPDATE та DELETE запити","\u002Fdatabases\u002Fsql\u002Fupdate-delete-queries","06.databases\u002F03.sql\u002F06.update-delete-queries",{"title":2665,"path":2666,"stem":2667},"Транзакції в SQL","\u002Fdatabases\u002Fsql\u002Ftransactions","06.databases\u002F03.sql\u002F07.transactions",{"title":2669,"icon":2574,"path":2670,"stem":2671,"children":2672,"page":59},"Multi Table Databases","\u002Fdatabases\u002Fmulti-table-databases","06.databases\u002F04.multi-table-databases",[2673,2677,2681,2685,2689,2693],{"title":2674,"path":2675,"stem":2676},"Зв'язки та нормалізація БД","\u002Fdatabases\u002Fmulti-table-databases\u002Frelationships-and-normalization","06.databases\u002F04.multi-table-databases\u002F00.relationships-and-normalization",{"title":2678,"path":2679,"stem":2680},"INNER JOIN - З'єднання таблиць","\u002Fdatabases\u002Fmulti-table-databases\u002Finner-join","06.databases\u002F04.multi-table-databases\u002F01.inner-join",{"title":2682,"path":2683,"stem":2684},"OUTER JOINs - LEFT, RIGHT, FULL","\u002Fdatabases\u002Fmulti-table-databases\u002Fouter-joins","06.databases\u002F04.multi-table-databases\u002F02.outer-joins",{"title":2686,"path":2687,"stem":2688},"CROSS та SELF JOINs","\u002Fdatabases\u002Fmulti-table-databases\u002Fcross-self-joins","06.databases\u002F04.multi-table-databases\u002F03.cross-self-joins",{"title":2690,"path":2691,"stem":2692},"Підзапити (Subqueries)","\u002Fdatabases\u002Fmulti-table-databases\u002Fsubqueries","06.databases\u002F04.multi-table-databases\u002F04.subqueries",{"title":2694,"path":2695,"stem":2696},"Агрегації з JOIN","\u002Fdatabases\u002Fmulti-table-databases\u002Faggregations-with-joins","06.databases\u002F04.multi-table-databases\u002F05.aggregations-with-joins",{"title":2698,"icon":2699,"path":2700,"stem":2701,"children":2702,"page":59},"Aggregate Functions","i-lucide-calculator","\u002Fdatabases\u002Faggregate-functions","06.databases\u002F05.aggregate-functions",[2703,2707,2711],{"title":2704,"path":2705,"stem":2706},"Функції агрегування в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fintroduction-aggregate-functions","06.databases\u002F05.aggregate-functions\u002F01.introduction-aggregate-functions",{"title":2708,"path":2709,"stem":2710},"Групування даних в MS SQL Server","\u002Fdatabases\u002Faggregate-functions\u002Fgrouping-data","06.databases\u002F05.aggregate-functions\u002F02.grouping-data",{"title":2712,"path":2713,"stem":2714},"Підзапити з агрегатними функціями","\u002Fdatabases\u002Faggregate-functions\u002Fsubqueries-aggregates","06.databases\u002F05.aggregate-functions\u002F03.subqueries-aggregates",{"title":2716,"icon":2717,"path":2718,"stem":2719,"children":2720,"page":59},"Тригери та зберігаємі процедури","i-lucide-database-zap","\u002Fdatabases\u002Ftriggers-stored-procedures","06.databases\u002F07.triggers-stored-procedures",[2721,2725,2729,2733,2737,2741,2745],{"title":2722,"path":2723,"stem":2724},"DML-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fdml-triggers","06.databases\u002F07.triggers-stored-procedures\u002F01.dml-triggers",{"title":2726,"path":2727,"stem":2728},"DDL-тригери","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fddl-triggers","06.databases\u002F07.triggers-stored-procedures\u002F02.ddl-triggers",{"title":2730,"path":2731,"stem":2732},"Transact-SQL розширення","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransact-sql-extensions","06.databases\u002F07.triggers-stored-procedures\u002F03.transact-sql-extensions",{"title":2734,"path":2735,"stem":2736},"Транзакції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Ftransactions","06.databases\u002F07.triggers-stored-procedures\u002F04.transactions",{"title":2738,"path":2739,"stem":2740},"Зберігаємі процедури","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fstored-procedures","06.databases\u002F07.triggers-stored-procedures\u002F05.stored-procedures",{"title":2742,"path":2743,"stem":2744},"Користувацькі функції","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fuser-defined-functions","06.databases\u002F07.triggers-stored-procedures\u002F06.user-defined-functions",{"title":2746,"path":2747,"stem":2748},"Безпека баз даних","\u002Fdatabases\u002Ftriggers-stored-procedures\u002Fsecurity","06.databases\u002F07.triggers-stored-procedures\u002F08.security",{"title":2746,"icon":793,"path":2750,"stem":2751,"children":2752,"page":59},"\u002Fdatabases\u002Fsecurity","06.databases\u002F08.security",[2753,2757],{"title":2754,"path":2755,"stem":2756},"Вступ до безпеки баз даних","\u002Fdatabases\u002Fsecurity\u002Fintroduction","06.databases\u002F08.security\u002F01.introduction",{"title":2758,"path":2759,"stem":2760},"Системні представлення та метадані","\u002Fdatabases\u002Fsecurity\u002Fsystem-views","06.databases\u002F08.security\u002F02.system-views",{"title":2762,"icon":2763,"path":2764,"stem":2765,"children":2766,"page":59},"Резервне копіювання та відновлення","i-lucide-database-backup","\u002Fdatabases\u002Fbackup-recovery","06.databases\u002F09.backup-recovery",[2767],{"title":2762,"path":2768,"stem":2769},"\u002Fdatabases\u002Fbackup-recovery\u002Fbackup-restore","06.databases\u002F09.backup-recovery\u002F01.backup-restore",{"title":2771,"icon":2772,"path":2773,"stem":2774,"children":2775,"page":59},"Повнотекстовий пошук","i-lucide-search","\u002Fdatabases\u002Ffull-text-search","06.databases\u002F10.full-text-search",[2776],{"title":2771,"path":2777,"stem":2778},"\u002Fdatabases\u002Ffull-text-search\u002Ffull-text-search","06.databases\u002F10.full-text-search\u002F01.full-text-search",{"title":2780,"icon":2781,"path":2782,"stem":2783,"children":2784,"page":59},"Tools","i-lucide-wrench","\u002Ftools","07.tools",[2785,2861],{"title":2786,"icon":2787,"path":2788,"stem":2789,"children":2790},"Docker","i-simple-icons-docker","\u002Ftools\u002Fdocker","07.tools\u002F01.docker\u002Findex",[2791,2793,2797,2801,2805,2809,2813,2817,2821,2825,2829,2833,2837,2841,2845,2849,2853,2857],{"title":2792,"path":2788,"stem":2789},"Docker: від нуля до production",{"title":2794,"path":2795,"stem":2796},"Контейнеризація — від проблеми до рішення","\u002Ftools\u002Fdocker\u002Fcontainerization-concept","07.tools\u002F01.docker\u002F01.containerization-concept",{"title":2798,"path":2799,"stem":2800},"Docker — що це і навіщо?","\u002Ftools\u002Fdocker\u002Fdocker-what-and-why","07.tools\u002F01.docker\u002F02.docker-what-and-why",{"title":2802,"path":2803,"stem":2804},"Архітектура Docker Engine","\u002Ftools\u002Fdocker\u002Fdocker-architecture","07.tools\u002F01.docker\u002F03.docker-architecture",{"title":2806,"path":2807,"stem":2808},"Встановлення Docker","\u002Ftools\u002Fdocker\u002Finstallation","07.tools\u002F01.docker\u002F04.installation",{"title":2810,"path":2811,"stem":2812},"Перший контейнер — docker run","\u002Ftools\u002Fdocker\u002Ffirst-container","07.tools\u002F01.docker\u002F05.first-container",{"title":2814,"path":2815,"stem":2816},"Життєвий цикл контейнера","\u002Ftools\u002Fdocker\u002Fcontainer-lifecycle","07.tools\u002F01.docker\u002F06.container-lifecycle",{"title":2818,"path":2819,"stem":2820},"Docker Images — фундаментальні концепції","\u002Ftools\u002Fdocker\u002Fdocker-images-fundamentals","07.tools\u002F01.docker\u002F07.docker-images-fundamentals",{"title":2822,"path":2823,"stem":2824},"Dockerfile — основи","\u002Ftools\u002Fdocker\u002Fdockerfile-basics","07.tools\u002F01.docker\u002F08.dockerfile-basics",{"title":2826,"path":2827,"stem":2828},"Dockerfile — просунуті техніки","\u002Ftools\u002Fdocker\u002Fdockerfile-advanced","07.tools\u002F01.docker\u002F09.dockerfile-advanced",{"title":2830,"path":2831,"stem":2832},"Build Context та кешування шарів","\u002Ftools\u002Fdocker\u002Fbuild-context-and-cache","07.tools\u002F01.docker\u002F10.build-context-and-cache",{"title":2834,"path":2835,"stem":2836},"Реєстри Docker-образів","\u002Ftools\u002Fdocker\u002Fimage-registries","07.tools\u002F01.docker\u002F11.image-registries",{"title":2838,"path":2839,"stem":2840},"Контейнеризація .NET додатків","\u002Ftools\u002Fdocker\u002Fdotnet-containerization","07.tools\u002F01.docker\u002F12.dotnet-containerization",{"title":2842,"path":2843,"stem":2844},"Томи та збереження даних","\u002Ftools\u002Fdocker\u002Fvolumes-and-data","07.tools\u002F01.docker\u002F13.volumes-and-data",{"title":2846,"path":2847,"stem":2848},"Основи мережі в Docker","\u002Ftools\u002Fdocker\u002Fnetworking-basics","07.tools\u002F01.docker\u002F14.networking-basics",{"title":2850,"path":2851,"stem":2852},"Змінні оточення та конфігурація","\u002Ftools\u002Fdocker\u002Fenvironment-and-configuration","07.tools\u002F01.docker\u002F15.environment-and-configuration",{"title":2854,"path":2855,"stem":2856},"Docker Compose — оркестрація контейнерів","\u002Ftools\u002Fdocker\u002Fdocker-compose-basics","07.tools\u002F01.docker\u002F16.docker-compose-basics",{"title":2858,"path":2859,"stem":2860},"Docker Compose — Multi-Service застосунки","\u002Ftools\u002Fdocker\u002Fcompose-multi-service","07.tools\u002F01.docker\u002F17.compose-multi-service",{"title":2862,"icon":2863,"path":2864,"stem":2865,"children":2866},"Kubernetes","simple-icons:kubernetes","\u002Ftools\u002Fkubernetes","07.tools\u002F02.kubernetes\u002Findex",[2867,2869,2873,2877,2881,2885,2889,2893,2897],{"title":2868,"path":2864,"stem":2865},"Kubernetes: від розробки до production",{"title":2870,"path":2871,"stem":2872},"Kubernetes — коли Docker Compose більше не вистачає","\u002Ftools\u002Fkubernetes\u002Fwhy-kubernetes","07.tools\u002F02.kubernetes\u002F01.why-kubernetes",{"title":2874,"path":2875,"stem":2876},"Архітектура Kubernetes — анатомія кластера","\u002Ftools\u002Fkubernetes\u002Fkubernetes-architecture","07.tools\u002F02.kubernetes\u002F02.kubernetes-architecture",{"title":2878,"path":2879,"stem":2880},"Локальне середовище — minikube, kind та k3s","\u002Ftools\u002Fkubernetes\u002Flocal-environment","07.tools\u002F02.kubernetes\u002F03.local-environment",{"title":2882,"path":2883,"stem":2884},"Pod — атомарна одиниця Kubernetes","\u002Ftools\u002Fkubernetes\u002Fpods-and-containers","07.tools\u002F02.kubernetes\u002F04.pods-and-containers",{"title":2886,"path":2887,"stem":2888},"Патерни використання Pod","\u002Ftools\u002Fkubernetes\u002Fpod-patterns","07.tools\u002F02.kubernetes\u002F05.pod-patterns",{"title":2890,"path":2891,"stem":2892},"Deployment — декларативне управління Pod","\u002Ftools\u002Fkubernetes\u002Fdeployment-basics","07.tools\u002F02.kubernetes\u002F06.deployment-basics",{"title":2894,"path":2895,"stem":2896},"Rolling Updates та управління життєвим циклом Deployment","\u002Ftools\u002Fkubernetes\u002Fdeployment-rolling-updates","07.tools\u002F02.kubernetes\u002F07.deployment-rolling-updates",{"title":2898,"path":2899,"stem":2900},"Service — мережева абстракція для Pod","\u002Ftools\u002Fkubernetes\u002Fservices-networking","07.tools\u002F02.kubernetes\u002F08.services-networking",{"title":2902,"icon":2903,"path":2904,"stem":2905,"children":2906,"page":59},"Software Engineering","i-lucide-code-2","\u002Fsoftware-engineering","09.software-engineering",[2907,2911,2915,2919,2923,2927,2931,2935,2939,2943,2947],{"title":2908,"path":2909,"stem":2910},"1. Аналіз предметної області. Експертні знання та складність","\u002Fsoftware-engineering\u002Fintro-subdomains","09.software-engineering\u002F01.intro-subdomains",{"title":2912,"path":2913,"stem":2914},"2. Обмежені контексти. Інтеграція обмежених контекстів","\u002Fsoftware-engineering\u002Fintegrating-limited-contexts","09.software-engineering\u002F02.integrating-limited-contexts",{"title":2916,"path":2917,"stem":2918},"3. Реалізація простої бізнес-логіки","\u002Fsoftware-engineering\u002Fsimple","09.software-engineering\u002F03.simple",{"title":2920,"path":2921,"stem":2922},"4. Опрацювання складної бізнес-логіки","\u002Fsoftware-engineering\u002Fcomplex-business-logic","09.software-engineering\u002F04.complex-business-logic",{"title":2924,"path":2925,"stem":2926},"5. Моделювання фактора часу. Подієво-орієнтована архітектура.","\u002Fsoftware-engineering\u002Fmodelling-the-time-factor","09.software-engineering\u002F05.modelling-the-time-factor",{"title":2928,"path":2929,"stem":2930},"6. Архітектурні патерни","\u002Fsoftware-engineering\u002Farchitectural-patterns","09.software-engineering\u002F06.architectural-patterns",{"title":2932,"path":2933,"stem":2934},"Паттерни взаємодії","\u002Fsoftware-engineering\u002Fpatterns-of-interaction","09.software-engineering\u002F07.patterns-of-interaction",{"title":2936,"path":2937,"stem":2938},"Евристика проєктування","\u002Fsoftware-engineering\u002Fdesign-heuristics","09.software-engineering\u002F08.design-heuristics",{"title":2940,"path":2941,"stem":2942},"Еволюція проєктних рішень","\u002Fsoftware-engineering\u002Fevolution-of-design-solutions","09.software-engineering\u002F09.evolution-of-design-solutions",{"title":2944,"path":2945,"stem":2946},"EventStorming","\u002Fsoftware-engineering\u002Feventstorming","09.software-engineering\u002F10.eventstorming",{"title":2948,"path":2949,"stem":2950},"DDD на практиці","\u002Fsoftware-engineering\u002Fddd-in-practice","09.software-engineering\u002F11.ddd-in-practice",{"title":2952,"icon":943,"path":2953,"stem":2954,"children":2955,"page":59},"DDD","\u002Fddd","10.ddd",[2956,2960,2964,2968,2972,2976,2980,2984,2988,2992,2996,3000,3004],{"title":2957,"path":2958,"stem":2959},"Аналіз предметної області","\u002Fddd\u002Fdomain-analysis","10.ddd\u002F01.domain-analysis",{"title":2961,"path":2962,"stem":2963},"Експертні знання про предметну область","\u002Fddd\u002Fdomain-expert-knowledge","10.ddd\u002F02.domain-expert-knowledge",{"title":2965,"path":2966,"stem":2967},"Як осмислити складність предметної області","\u002Fddd\u002Fmanaging-domain-complexity","10.ddd\u002F03.managing-domain-complexity",{"title":2969,"path":2970,"stem":2971},"Інтеграція обмежених контекстів","\u002Fddd\u002Fbounded-context-integration","10.ddd\u002F04.bounded-context-integration",{"title":2973,"path":2974,"stem":2975},"Реалізація простої бізнес-логіки","\u002Fddd\u002Fsimple-business-logic","10.ddd\u002F05.simple-business-logic",{"title":2977,"path":2978,"stem":2979},"Обробка складної бізнес-логіки","\u002Fddd\u002Fcomplex-business-logic","10.ddd\u002F06.complex-business-logic",{"title":2981,"path":2982,"stem":2983},"Моделювання фактора часу","\u002Fddd\u002Ftime-modeling","10.ddd\u002F07.time-modeling",{"title":2985,"path":2986,"stem":2987},"Глава 8. Архітектурні Патерни","\u002Fddd\u002Farchitectural-patterns","10.ddd\u002F08.architectural-patterns",{"title":2989,"path":2990,"stem":2991},"Глава 9. Патерни Взаємодії","\u002Fddd\u002Finteraction-patterns","10.ddd\u002F09.interaction-patterns",{"title":2993,"path":2994,"stem":2995},"Глава 10. Проектні Евристики","\u002Fddd\u002Fdesign-heuristics","10.ddd\u002F10.design-heuristics",{"title":2997,"path":2998,"stem":2999},"Глава 11. Еволюція Проектних Рішень","\u002Fddd\u002Fevolution-of-design-decisions","10.ddd\u002F11.evolution-of-design-decisions",{"title":3001,"path":3002,"stem":3003},"Глава 12. EventStorming","\u002Fddd\u002Fevent-storming","10.ddd\u002F12.event-storming",{"title":3005,"path":3006,"stem":3007},"Глава 13. DDD на Практиці","\u002Fddd\u002Fddd-in-practice","10.ddd\u002F13.ddd-in-practice",{"title":3009,"icon":3010,"path":3011,"stem":3012,"children":3013,"page":59},"Media Streaming","i-lucide-video","\u002Fmedia-streaming","11.media-streaming",[3014,3018,3022,3026,3030,3034,3038],{"title":3015,"path":3016,"stem":3017},"01. Магія Стрімінгу: Що відбувається, коли ви натискаєте \"Play\"","\u002Fmedia-streaming\u002Fintroduction","11.media-streaming\u002F01.introduction",{"title":3019,"path":3020,"stem":3021},"02. Анатомія Медіа: Кодеки, Контейнери та Стиснення","\u002Fmedia-streaming\u002Faudio-video-anatomy","11.media-streaming\u002F02.audio-video-anatomy",{"title":3023,"path":3024,"stem":3025},"03. The Gym: FFmpeg Deep Dive","\u002Fmedia-streaming\u002Fffmpeg-gym","11.media-streaming\u002F03.ffmpeg-gym",{"title":3027,"path":3028,"stem":3029},"04. HLS Protocol: HTTP Live Streaming у Деталях","\u002Fmedia-streaming\u002Fhls-protocol","11.media-streaming\u002F04.hls-protocol",{"title":3031,"path":3032,"stem":3033},"05. DASH Protocol: Відкритий Стандарт","\u002Fmedia-streaming\u002Fdash-protocol","11.media-streaming\u002F05.dash-protocol",{"title":3035,"path":3036,"stem":3037},"06. Масштабування: CDN та Adaptive Bitrate","\u002Fmedia-streaming\u002Fcdn-and-adaptive-bitrate","11.media-streaming\u002F06.cdn-and-adaptive-bitrate",{"title":3039,"path":3040,"stem":3041},"07. Війна із Затримкою (Latency)","\u002Fmedia-streaming\u002Frealtime-latency","11.media-streaming\u002F07.realtime-latency",{"title":3043,"icon":3044,"path":3045,"stem":3046,"children":3047,"page":59},"HTML & CSS","i-devicon-html5","\u002Fhtml-css","12.html-css",[3048,3052,3056,3060,3064,3068,3072,3076,3080,3084,3088,3092,3096,3100,3104,3108,3112,3116,3120,3124,3128,3132,3136,3140,3144,3148,3152,3156,3160,3164],{"title":3049,"path":3050,"stem":3051},"Вступ до HTML. Структура документа","\u002Fhtml-css\u002Fintro-html-structure","12.html-css\u002F01.intro-html-structure",{"title":3053,"path":3054,"stem":3055},"Форматування тексту в HTML","\u002Fhtml-css\u002Fhtml-text-formatting","12.html-css\u002F02.html-text-formatting",{"title":3057,"path":3058,"stem":3059},"Посилання та зображення в HTML","\u002Fhtml-css\u002Fhtml-links-images","12.html-css\u002F03.html-links-images",{"title":3061,"path":3062,"stem":3063},"Списки та таблиці в HTML","\u002Fhtml-css\u002Fhtml-lists-tables","12.html-css\u002F04.html-lists-tables",{"title":3065,"path":3066,"stem":3067},"Форми в HTML","\u002Fhtml-css\u002Fhtml-forms","12.html-css\u002F05.html-forms",{"title":3069,"path":3070,"stem":3071},"Семантичні елементи HTML5","\u002Fhtml-css\u002Fhtml-semantic-elements","12.html-css\u002F06.html-semantic-elements",{"title":3073,"path":3074,"stem":3075},"Мультимедіа та розширені елементи HTML","\u002Fhtml-css\u002Fhtml-multimedia-advanced","12.html-css\u002F07.html-multimedia-advanced",{"title":3077,"path":3078,"stem":3079},"Мікророзмітка та SEO в HTML","\u002Fhtml-css\u002Fhtml-microdata-seo","12.html-css\u002F08.html-microdata-seo",{"title":3081,"path":3082,"stem":3083},"Вступ до CSS. Селектори та специфічність","\u002Fhtml-css\u002Fcss-intro-selectors","12.html-css\u002F09.css-intro-selectors",{"title":3085,"path":3086,"stem":3087},"Блокова модель CSS. Відступи. Box Sizing","\u002Fhtml-css\u002Fcss-box-model","12.html-css\u002F10.css-box-model",{"title":3089,"path":3090,"stem":3091},"Розміри у CSS: повний довідник одиниць і ключових слів","\u002Fhtml-css\u002F10a.css-sizing","12.html-css\u002F10a.css-sizing",{"title":3093,"path":3094,"stem":3095},"Типографіка в CSS. Шрифти та текст","\u002Fhtml-css\u002Fcss-typography","12.html-css\u002F11.css-typography",{"title":3097,"path":3098,"stem":3099},"Кольори та фони в CSS","\u002Fhtml-css\u002Fcss-colors-backgrounds","12.html-css\u002F12.css-colors-backgrounds",{"title":3101,"path":3102,"stem":3103},"Тіні та фільтри в CSS","\u002Fhtml-css\u002F12b.css-shadows-filters","12.html-css\u002F12b.css-shadows-filters",{"title":3105,"path":3106,"stem":3107},"CSS Flexbox: Фундамент гнучких макетів","\u002Fhtml-css\u002Fcss-flexbox-fundamentals","12.html-css\u002F13.css-flexbox-fundamentals",{"title":3109,"path":3110,"stem":3111},"CSS Flexbox: Вирівнювання та Позиціонування","\u002Fhtml-css\u002Fcss-flexbox-alignment-sizing-and-patterns","12.html-css\u002F14.css-flexbox-alignment-sizing-and-patterns",{"title":3113,"path":3114,"stem":3115},"CSS Grid. Двовимірний макет. Частина 1","\u002Fhtml-css\u002Fcss-layout-grid","12.html-css\u002F15.css-layout-grid",{"title":3117,"path":3118,"stem":3119},"CSS Grid. Двовимірний макет. Частина 2","\u002Fhtml-css\u002Fcss-layout-grid-advanced","12.html-css\u002F16.css-layout-grid-advanced",{"title":3121,"path":3122,"stem":3123},"Позиціонування в CSS. Z-index. Stacking Context","\u002Fhtml-css\u002Fcss-positioning","12.html-css\u002F17.css-positioning",{"title":3125,"path":3126,"stem":3127},"CSS Анімації та Переходи","\u002Fhtml-css\u002Fcss-animations-transitions","12.html-css\u002F18.css-animations-transitions",{"title":3129,"path":3130,"stem":3131},"Адаптивний дизайн. Media Queries. Частина 1","\u002Fhtml-css\u002Fcss-responsive-media-queries","12.html-css\u002F19.css-responsive-media-queries",{"title":3133,"path":3134,"stem":3135},"Адаптивний дизайн. Частина 2: clamp(), Container Queries, @layer","\u002Fhtml-css\u002Fcss-responsive-advanced","12.html-css\u002F20.css-responsive-advanced",{"title":3137,"path":3138,"stem":3139},"CSS Custom Properties. Методології. Сучасний CSS","\u002Fhtml-css\u002Fcss-variables-methodologies","12.html-css\u002F21.css-variables-methodologies",{"title":3141,"path":3142,"stem":3143},"Сучасний CSS 2023–2025: Нові можливості","\u002Fhtml-css\u002Fcss-modern-features","12.html-css\u002F22.css-modern-features",{"title":3145,"path":3146,"stem":3147},"CSS Nesting, @layer, @scope та @property: нативний препроцесор","\u002Fhtml-css\u002F22a.css-nesting-modern-syntax","12.html-css\u002F22a.css-nesting-modern-syntax",{"title":3149,"path":3150,"stem":3151},"CSS для форм та інтерактивних станів","\u002Fhtml-css\u002Fcss-forms-interactive-states","12.html-css\u002F23.css-forms-interactive-states",{"title":3153,"path":3154,"stem":3155},"Доступність у CSS (CSS Accessibility)","\u002Fhtml-css\u002Fcss-accessibility","12.html-css\u002F24.css-accessibility",{"title":3157,"path":3158,"stem":3159},"CSS-функції та сучасні sizing primitives","\u002Fhtml-css\u002Fcss-functions-sizing","12.html-css\u002F25.css-functions-sizing",{"title":3161,"path":3162,"stem":3163},"Rendering Pipeline і CSS Performance","\u002Fhtml-css\u002Fcss-rendering-performance","12.html-css\u002F26.css-rendering-performance",{"title":3165,"path":3166,"stem":3167},"CSS Best Practices: типові ситуації та правильні рішення","\u002Fhtml-css\u002Fcss-best-practices","12.html-css\u002F27.css-best-practices",{"title":3169,"path":3170,"stem":3171,"children":3172,"page":59},"AWS","\u002Faws","13.aws",[3173,3177,3181,3185,3189,3193,3197,3201,3205,3209,3213,3217,3221,3225,3229,3233,3237,3241],{"title":3174,"path":3175,"stem":3176},"Реєстрація AWS акаунту та студентські програми","\u002Faws\u002Faccount-registration","13.aws\u002F00.account-registration",{"title":3178,"path":3179,"stem":3180},"Вступ до хмарних обчислень та AWS","\u002Faws\u002Fintroduction-to-cloud","13.aws\u002F01.introduction-to-cloud",{"title":3182,"path":3183,"stem":3184},"AWS IAM — Identity and Access Management","\u002Faws\u002Fiam","13.aws\u002F02.iam",{"title":3186,"path":3187,"stem":3188},"AWS IAM CLI — Довідник команд","\u002Faws\u002F02a.iam-doc","13.aws\u002F02a.iam-doc",{"title":3190,"path":3191,"stem":3192},"Docker та контейнеризація в AWS — ECR, ECS та Fargate","\u002Faws\u002Fdocker-ecs","13.aws\u002F03.docker-ecs",{"title":3194,"path":3195,"stem":3196},"AWS ECR \u002F ECS CLI — Довідник команд","\u002Faws\u002F03a.docker-ecs-doc","13.aws\u002F03a.docker-ecs-doc",{"title":3198,"path":3199,"stem":3200},"Amazon EC2 — Elastic Compute Cloud","\u002Faws\u002Fec2","13.aws\u002F04.ec2",{"title":3202,"path":3203,"stem":3204},"AWS EC2 CLI — Довідник команд","\u002Faws\u002F04a.ec2-doc","13.aws\u002F04a.ec2-doc",{"title":3206,"path":3207,"stem":3208},"Elastic Load Balancing та Auto Scaling","\u002Faws\u002Falb-asg","13.aws\u002F05.alb-asg",{"title":3210,"path":3211,"stem":3212},"Amazon S3 — Simple Storage Service","\u002Faws\u002Fs3","13.aws\u002F06.s3",{"title":3214,"path":3215,"stem":3216},"Amazon CloudFront — Content Delivery Network","\u002Faws\u002Fcloudfront","13.aws\u002F07.cloudfront",{"title":3218,"path":3219,"stem":3220},"Amazon RDS — Relational Database Service","\u002Faws\u002Frds","13.aws\u002F08.rds",{"title":3222,"path":3223,"stem":3224},"Amazon DynamoDB — NoSQL Database","\u002Faws\u002Fdynamodb","13.aws\u002F09.dynamodb",{"title":3226,"path":3227,"stem":3228},"AWS Lambda та Serverless Compute","\u002Faws\u002Flambda","13.aws\u002F10.lambda",{"title":3230,"path":3231,"stem":3232},"Amazon Bedrock - Foundation Models, RAG та Agents","\u002Faws\u002Fbedrock","13.aws\u002F22.bedrock",{"title":3234,"path":3235,"stem":3236},"Amazon Rekognition - Комп'ютерний зір","\u002Faws\u002Frekognition","13.aws\u002F23.rekognition",{"title":3238,"path":3239,"stem":3240},"Amazon Textract - Інтелектуальний аналіз документів","\u002Faws\u002Ftextract","13.aws\u002F24.textract",{"title":3242,"path":3243,"stem":3244},"Amazon Polly, Transcribe, Comprehend та Translate","\u002Faws\u002Faudio-nlp-services","13.aws\u002F25.audio-nlp-services",{"title":3246,"path":3247,"stem":3248,"children":3249,"page":59},"Tailwind","\u002Ftailwind","21.tailwind",[3250,3254,3258,3262,3266,3270,3274,3278,3282,3286,3290,3294],{"title":3251,"path":3252,"stem":3253},"Що таке Tailwind CSS і навіщо він потрібен","\u002Ftailwind\u002Ftailwind-intro-philosophy","21.tailwind\u002F01.tailwind-intro-philosophy",{"title":3255,"path":3256,"stem":3257},"Встановлення та налаштування Tailwind CSS v4","\u002Ftailwind\u002Ftailwind-installation-setup","21.tailwind\u002F02.tailwind-installation-setup",{"title":3259,"path":3260,"stem":3261},"Utility-класи: основи та система Tailwind","\u002Ftailwind\u002Ftailwind-utility-classes-core","21.tailwind\u002F03.tailwind-utility-classes-core",{"title":3263,"path":3264,"stem":3265},"Layout: Flexbox та Grid через Tailwind","\u002Ftailwind\u002Ftailwind-flexbox-grid","21.tailwind\u002F04.tailwind-flexbox-grid",{"title":3267,"path":3268,"stem":3269},"Кастомізація теми через @theme у Tailwind v4","\u002Ftailwind\u002Ftailwind-theme-customization","21.tailwind\u002F05.tailwind-theme-customization",{"title":3271,"path":3272,"stem":3273},"Варіанти: hover, focus, responsive, dark mode та нові v4","\u002Ftailwind\u002Ftailwind-variants-states","21.tailwind\u002F06.tailwind-variants-states",{"title":3275,"path":3276,"stem":3277},"Типографіка та система кольорів у Tailwind v4","\u002Ftailwind\u002Ftailwind-typography-colors","21.tailwind\u002F07.tailwind-typography-colors",{"title":3279,"path":3280,"stem":3281},"Компоненти та повторюваність: @apply, @utility та патерни","\u002Ftailwind\u002Ftailwind-components-patterns","21.tailwind\u002F08.tailwind-components-patterns",{"title":3283,"path":3284,"stem":3285},"Темна тема та система дизайн-токенів у Tailwind v4","\u002Ftailwind\u002Ftailwind-dark-mode-theming","21.tailwind\u002F09.tailwind-dark-mode-theming",{"title":3287,"path":3288,"stem":3289},"Довільні значення та контейнерні запити у Tailwind v4","\u002Ftailwind\u002Ftailwind-arbitrary-container-queries","21.tailwind\u002F10.tailwind-arbitrary-container-queries",{"title":3291,"path":3292,"stem":3293},"Анімації, трансформації та 3D у Tailwind v4","\u002Ftailwind\u002Ftailwind-animations-transforms","21.tailwind\u002F11.tailwind-animations-transforms",{"title":3295,"path":3296,"stem":3297},"Tailwind CLI, PostCSS та інтеграція з фреймворками","\u002Ftailwind\u002Ftailwind-cli-tooling","21.tailwind\u002F12.tailwind-cli-tooling",{"title":3299,"path":3300,"stem":3301},"Тестування компонентів діаграм","\u002Ftest-components","98.test-components",{"id":3303,"title":1680,"body":3304,"description":19349,"extension":19350,"links":19351,"meta":19352,"navigation":3407,"path":1681,"seo":19353,"stem":1682,"__hash__":19354},"docs\u002F01.csharp\u002F13.network-programming\u002F07.http-fundamentals.md",{"type":3305,"value":3306,"toc":19281},"minimark",[3307,3311,3316,3329,3345,3352,3359,3362,3366,3369,3583,3591,3598,3603,4053,4285,4287,4291,4295,4301,4305,4313,4650,4654,4918,4922,4925,5014,5017,5021,5084,5088,5610,5612,5616,5619,5785,5853,5860,5862,5866,5877,5881,5884,6112,6115,6201,6208,6212,6354,6500,6592,6594,6598,6601,6731,6742,6746,7037,7041,7449,7453,7627,7631,7812,7816,7823,7982,7984,7988,7995,7999,8002,8049,8320,8471,8488,8492,10753,10755,10759,10766,11040,11044,11240,11244,11640,11644,11996,12000,13120,13124,13139,13512,13514,13518,13525,13712,13716,13831,13835,13963,13992,13994,13998,14002,14005,14330,14334,14349,14383,14430,14434,15805,15807,15811,15824,15964,16445,16447,16451,16464,16492,16496,16644,16648,16712,16715,18646,18650,18879,18883,18977,18994,18996,19000,19003,19007,19048,19052,19119,19123,19180,19187,19189,19193,19196,19270,19277],[3308,3309,1680],"h1",{"id":3310},"http-протокол-вебу",[3312,3313,3315],"h2",{"id":3314},"від-теорії-до-практики-чому-http-існує","Від теорії до практики: чому HTTP існує",[3317,3318,3319,3320,3324,3325,3328],"p",{},"У попередніх розділах ми вивчили транспортний рівень — UDP та TCP. Обидва протоколи вирішують задачу ",[3321,3322,3323],"strong",{},"доставки"," байтів між процесами. Але що робити з цими байтами? Який сенс несуть вони для застосунку? Відповідь на це питання дає ",[3321,3326,3327],{},"прикладний рівень"," (Application Layer, Layer 7 моделі OSI).",[3317,3330,3331,3332,3335,3336,3340,3341,3344],{},"Саме на прикладному рівні живе ",[3321,3333,3334],{},"HTTP"," — HyperText Transfer Protocol. Він визначає не те, ",[3337,3338,3339],"em",{},"як"," байти доставляються (це справа TCP), а ",[3337,3342,3343],{},"що"," вони означають: який ресурс запитується, яким методом, яка відповідь очікується і що вона містить.",[3317,3346,3347,3348,3351],{},"HTTP є ",[3321,3349,3350],{},"основою World Wide Web"," і одним з найважливіших протоколів в історії комп'ютерних мереж. Кожного разу, коли ви відкриваєте браузер, кожен REST API виклик, кожне завантаження файлу — все це HTTP.",[3353,3354,3355,3358],"note",{},[3321,3356,3357],{},"Ключова ідея цього розділу:"," HTTP — це протокол прикладного рівня, що будується поверх TCP. Він визначає семантику запитів і відповідей: що саме клієнт хоче отримати, і що саме сервер зобов'язаний повернути. Розуміння HTTP є обов'язковою навичкою для будь-якого сучасного розробника.",[3360,3361],"hr",{},[3312,3363,3365],{"id":3364},"історія-та-еволюція-стандарту","Історія та еволюція стандарту",[3317,3367,3368],{},"HTTP пройшов довгий шлях від однорядкового протоколу до складної багаторівневої специфікації. Розуміння цього шляху пояснює багато сучасних рішень і «дивних» деталей протоколу.",[3370,3371,3372],"plant-uml",{},[3373,3374,3379],"pre",{"className":3375,"code":3376,"language":3377,"meta":3378,"style":3378},"language-plantuml shiki shiki-themes light-plus dark-plus dark-plus","@startmindmap\nskinparam style plain\nskinparam backgroundColor #ffffff\n\n* HTTP\n** HTTP\u002F0.9 (1991)\n*** Тім Бернерс-Лі, CERN\n*** Лише GET\n*** Лише HTML у відповіді\n*** Без заголовків\n** HTTP\u002F1.0 (1996)\n*** RFC 1945\n*** Додано заголовки\n*** POST, HEAD методи\n*** Нове з'єднання на кожен запит\n** HTTP\u002F1.1 (1997)\n*** RFC 2068 → RFC 7230–7235\n*** Keep-Alive за замовчуванням\n*** Chunked Transfer Encoding\n*** Віртуальний хостинг (Host header)\n*** Pipelining (погано працює на практиці)\n** HTTP\u002F2 (2015)\n*** RFC 7540\n*** Бінарний протокол\n*** Мультиплексування потоків\n*** Стиснення заголовків HPACK\n*** Server Push\n** HTTP\u002F3 (2022)\n*** RFC 9114\n*** Поверх QUIC (UDP)\n*** 0-RTT з'єднання\n*** Усунення HOL blocking\n@endmindmap\n","plantuml","",[3380,3381,3382,3390,3396,3402,3409,3415,3421,3427,3433,3439,3445,3451,3457,3463,3469,3475,3481,3487,3493,3499,3505,3511,3517,3523,3529,3535,3541,3547,3553,3559,3565,3571,3577],"code",{"__ignoreMap":3378},[3383,3384,3387],"span",{"class":3385,"line":3386},"line",1,[3383,3388,3389],{},"@startmindmap\n",[3383,3391,3393],{"class":3385,"line":3392},2,[3383,3394,3395],{},"skinparam style plain\n",[3383,3397,3399],{"class":3385,"line":3398},3,[3383,3400,3401],{},"skinparam backgroundColor #ffffff\n",[3383,3403,3405],{"class":3385,"line":3404},4,[3383,3406,3408],{"emptyLinePlaceholder":3407},true,"\n",[3383,3410,3412],{"class":3385,"line":3411},5,[3383,3413,3414],{},"* HTTP\n",[3383,3416,3418],{"class":3385,"line":3417},6,[3383,3419,3420],{},"** HTTP\u002F0.9 (1991)\n",[3383,3422,3424],{"class":3385,"line":3423},7,[3383,3425,3426],{},"*** Тім Бернерс-Лі, CERN\n",[3383,3428,3430],{"class":3385,"line":3429},8,[3383,3431,3432],{},"*** Лише GET\n",[3383,3434,3436],{"class":3385,"line":3435},9,[3383,3437,3438],{},"*** Лише HTML у відповіді\n",[3383,3440,3442],{"class":3385,"line":3441},10,[3383,3443,3444],{},"*** Без заголовків\n",[3383,3446,3448],{"class":3385,"line":3447},11,[3383,3449,3450],{},"** HTTP\u002F1.0 (1996)\n",[3383,3452,3454],{"class":3385,"line":3453},12,[3383,3455,3456],{},"*** RFC 1945\n",[3383,3458,3460],{"class":3385,"line":3459},13,[3383,3461,3462],{},"*** Додано заголовки\n",[3383,3464,3466],{"class":3385,"line":3465},14,[3383,3467,3468],{},"*** POST, HEAD методи\n",[3383,3470,3472],{"class":3385,"line":3471},15,[3383,3473,3474],{},"*** Нове з'єднання на кожен запит\n",[3383,3476,3478],{"class":3385,"line":3477},16,[3383,3479,3480],{},"** HTTP\u002F1.1 (1997)\n",[3383,3482,3484],{"class":3385,"line":3483},17,[3383,3485,3486],{},"*** RFC 2068 → RFC 7230–7235\n",[3383,3488,3490],{"class":3385,"line":3489},18,[3383,3491,3492],{},"*** Keep-Alive за замовчуванням\n",[3383,3494,3496],{"class":3385,"line":3495},19,[3383,3497,3498],{},"*** Chunked Transfer Encoding\n",[3383,3500,3502],{"class":3385,"line":3501},20,[3383,3503,3504],{},"*** Віртуальний хостинг (Host header)\n",[3383,3506,3508],{"class":3385,"line":3507},21,[3383,3509,3510],{},"*** Pipelining (погано працює на практиці)\n",[3383,3512,3514],{"class":3385,"line":3513},22,[3383,3515,3516],{},"** HTTP\u002F2 (2015)\n",[3383,3518,3520],{"class":3385,"line":3519},23,[3383,3521,3522],{},"*** RFC 7540\n",[3383,3524,3526],{"class":3385,"line":3525},24,[3383,3527,3528],{},"*** Бінарний протокол\n",[3383,3530,3532],{"class":3385,"line":3531},25,[3383,3533,3534],{},"*** Мультиплексування потоків\n",[3383,3536,3538],{"class":3385,"line":3537},26,[3383,3539,3540],{},"*** Стиснення заголовків HPACK\n",[3383,3542,3544],{"class":3385,"line":3543},27,[3383,3545,3546],{},"*** Server Push\n",[3383,3548,3550],{"class":3385,"line":3549},28,[3383,3551,3552],{},"** HTTP\u002F3 (2022)\n",[3383,3554,3556],{"class":3385,"line":3555},29,[3383,3557,3558],{},"*** RFC 9114\n",[3383,3560,3562],{"class":3385,"line":3561},30,[3383,3563,3564],{},"*** Поверх QUIC (UDP)\n",[3383,3566,3568],{"class":3385,"line":3567},31,[3383,3569,3570],{},"*** 0-RTT з'єднання\n",[3383,3572,3574],{"class":3385,"line":3573},32,[3383,3575,3576],{},"*** Усунення HOL blocking\n",[3383,3578,3580],{"class":3385,"line":3579},33,[3383,3581,3582],{},"@endmindmap\n",[3584,3585,3587,3590],"callout",{"color":3586,"icon":15},"primary",[3321,3588,3589],{},"RFC 7230 — офіційне визначення HTTP\u002F1.1:","\n\"The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems.\"",[3317,3592,3593,3594,3597],{},"Зверніть увагу на ключове слово ",[3321,3595,3596],{},"stateless"," — HTTP не зберігає стан між запитами. Кожен запит є незалежним, і сервер не пам'ятає попередніх взаємодій. Це свідоме архітектурне рішення, що забезпечує масштабованість, але й породжує потребу в механізмах на кшталт cookies та сесій (які ми розглянемо в наступному розділі).",[3599,3600,3602],"h3",{"id":3601},"детальна-хронологія-версій","Детальна хронологія версій",[3604,3605,3606,3610,3613,3623,3639,3642,3708,3711,3715,3718,3766,3800,3858,3864,3868,3871,3877,3889,3927,3933,3990,4000,4004,4007,4013,4019,4029,4035,4039,4046],"steps",{},[3599,3607,3609],{"id":3608},"http09-одного-рядка-достатньо-1991","HTTP\u002F0.9 — «Одного рядка достатньо» (1991)",[3317,3611,3612],{},"Тім Бернерс-Лі у 1991 році у CERN (Женева) запропонував першу версію HTTP. Протокол настільки простий, що його навіть не нумерували — назва «0.9» з'явилась ретроспективно, коли вийшла версія 1.0.",[3317,3614,3615,3618,3619,3622],{},[3321,3616,3617],{},"Можливості:"," лише один метод (",[3380,3620,3621],{},"GET","), лише HTML у відповіді, без заголовків, без статус-кодів, з'єднання закривається після кожного запиту.",[3373,3624,3628],{"className":3625,"code":3626,"language":3627,"meta":3378,"style":3378},"language-http shiki shiki-themes light-plus dark-plus dark-plus","GET \u002Findex.html\n","http",[3380,3629,3630],{"__ignoreMap":3378},[3383,3631,3632,3635],{"class":3385,"line":3386},[3383,3633,3621],{"class":3634},"s8xlr",[3383,3636,3638],{"class":3637},"sHH4Y"," \u002Findex.html\n",[3317,3640,3641],{},"Відповідь — просто HTML без жодних метаданих:",[3373,3643,3647],{"className":3644,"code":3645,"language":3646,"meta":3378,"style":3378},"language-html shiki shiki-themes light-plus dark-plus dark-plus","\u003Chtml>\n    \u003Cbody>\n        \u003Cp>Hello, World!\u003C\u002Fp>\n    \u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html",[3380,3648,3649,3661,3671,3691,3700],{"__ignoreMap":3378},[3383,3650,3651,3655,3658],{"class":3385,"line":3386},[3383,3652,3654],{"class":3653},"s0P7L","\u003C",[3383,3656,3646],{"class":3657},"sKtos",[3383,3659,3660],{"class":3653},">\n",[3383,3662,3663,3666,3669],{"class":3385,"line":3392},[3383,3664,3665],{"class":3653},"    \u003C",[3383,3667,3668],{"class":3657},"body",[3383,3670,3660],{"class":3653},[3383,3672,3673,3676,3678,3681,3684,3687,3689],{"class":3385,"line":3398},[3383,3674,3675],{"class":3653},"        \u003C",[3383,3677,3317],{"class":3657},[3383,3679,3680],{"class":3653},">",[3383,3682,3683],{"class":3637},"Hello, World!",[3383,3685,3686],{"class":3653},"\u003C\u002F",[3383,3688,3317],{"class":3657},[3383,3690,3660],{"class":3653},[3383,3692,3693,3696,3698],{"class":3385,"line":3404},[3383,3694,3695],{"class":3653},"    \u003C\u002F",[3383,3697,3668],{"class":3657},[3383,3699,3660],{"class":3653},[3383,3701,3702,3704,3706],{"class":3385,"line":3411},[3383,3703,3686],{"class":3653},[3383,3705,3646],{"class":3657},[3383,3707,3660],{"class":3653},[3317,3709,3710],{},"Якщо щось йде не так — з'єднання просто розривається. Жодного способу повідомити про помилку.",[3599,3712,3714],{"id":3713},"http10-заголовки-і-методи-rfc-1945-1996","HTTP\u002F1.0 — Заголовки і методи (RFC 1945, 1996)",[3317,3716,3717],{},"Публікація RFC 1945 у 1996 році (фактична специфікація практики, що вже склалась) принесла революційні зміни:",[3719,3720,3721,3739,3754,3760],"ul",{},[3722,3723,3724,3727,3728,3731,3732,3731,3735,3738],"li",{},[3321,3725,3726],{},"Заголовки"," (",[3380,3729,3730],{},"Content-Type",", ",[3380,3733,3734],{},"Content-Length",[3380,3736,3737],{},"Date"," тощо)",[3722,3740,3741,3743,3744,3747,3748,3751,3752],{},[3321,3742,48],{}," ",[3380,3745,3746],{},"POST"," та ",[3380,3749,3750],{},"HEAD"," на додачу до ",[3380,3753,3621],{},[3722,3755,3756,3759],{},[3321,3757,3758],{},"Статус-коди"," (200, 404, 500...)",[3722,3761,3762,3765],{},[3321,3763,3764],{},"Версія"," протоколу в запиті",[3373,3767,3769],{"className":3625,"code":3768,"language":3627,"meta":3378,"style":3378},"GET \u002Findex.html HTTP\u002F1.0\nAccept: text\u002Fhtml\n",[3380,3770,3771,3788],{"__ignoreMap":3378},[3383,3772,3773,3775,3778,3781,3784],{"class":3385,"line":3386},[3383,3774,3621],{"class":3634},[3383,3776,3777],{"class":3637}," \u002Findex.html ",[3383,3779,3334],{"class":3780},"su1O8",[3383,3782,3783],{"class":3637},"\u002F",[3383,3785,3787],{"class":3786},"sJj4R","1.0\n",[3383,3789,3790,3793,3796],{"class":3385,"line":3392},[3383,3791,3792],{"class":3657},"Accept",[3383,3794,3795],{"class":3780},":",[3383,3797,3799],{"class":3798},"sbdoH"," text\u002Fhtml\n",[3373,3801,3803],{"className":3625,"code":3802,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.0 200 OK\nContent-Type: text\u002Fhtml\nContent-Length: 137\n\n\u003Chtml>...\u003C\u002Fhtml>\n",[3380,3804,3805,3820,3828,3837,3841],{"__ignoreMap":3378},[3383,3806,3807,3809,3811,3814,3817],{"class":3385,"line":3386},[3383,3808,3334],{"class":3780},[3383,3810,3783],{"class":3637},[3383,3812,3813],{"class":3786},"1.0",[3383,3815,3816],{"class":3786}," 200",[3383,3818,3819],{"class":3798}," OK\n",[3383,3821,3822,3824,3826],{"class":3385,"line":3392},[3383,3823,3730],{"class":3657},[3383,3825,3795],{"class":3780},[3383,3827,3799],{"class":3798},[3383,3829,3830,3832,3834],{"class":3385,"line":3398},[3383,3831,3734],{"class":3657},[3383,3833,3795],{"class":3780},[3383,3835,3836],{"class":3798}," 137\n",[3383,3838,3839],{"class":3385,"line":3404},[3383,3840,3408],{"emptyLinePlaceholder":3407},[3383,3842,3843,3845,3847,3849,3852,3854,3856],{"class":3385,"line":3411},[3383,3844,3654],{"class":3653},[3383,3846,3646],{"class":3657},[3383,3848,3680],{"class":3653},[3383,3850,3851],{"class":3637},"...",[3383,3853,3686],{"class":3653},[3383,3855,3646],{"class":3657},[3383,3857,3660],{"class":3653},[3317,3859,3860,3863],{},[3321,3861,3862],{},"Критичне обмеження:"," кожен запит вимагав нового TCP-з'єднання. Сторінка з 30 зображеннями → 31 TCP-з'єднання (1 для HTML + 30 для зображень). Кожне з'єднання — це 3-way handshake + повільний старт TCP. При латентності 100мс — лише на рукостискання витрачалось 3 секунди.",[3599,3865,3867],{"id":3866},"http11-keep-alive-та-віртуальний-хостинг-rfc-20687230-19972014","HTTP\u002F1.1 — Keep-Alive та віртуальний хостинг (RFC 2068\u002F7230, 1997–2014)",[3317,3869,3870],{},"HTTP\u002F1.1 — найдовговічніша версія, що й досі широко використовується. Ключові нововведення:",[3317,3872,3873,3876],{},[3321,3874,3875],{},"Persistent connections (Keep-Alive):"," TCP-з'єднання залишається відкритим для багатьох запитів. Перший запит встановлює з'єднання, наступні йдуть по вже готовому каналу.",[3317,3878,3879,3885,3886,3888],{},[3321,3880,3881,3882,3795],{},"Обов'язковий заголовок ",[3380,3883,3884],{},"Host"," Один IP-сервер може обслуговувати тисячі доменів — саме ",[3380,3887,3884],{}," header дозволяє серверу зрозуміти, для якого сайту запит.",[3373,3890,3892],{"className":3625,"code":3891,"language":3627,"meta":3378,"style":3378},"GET \u002Fpage HTTP\u002F1.1\nHost: www.example.com\nConnection: keep-alive\n",[3380,3893,3894,3908,3917],{"__ignoreMap":3378},[3383,3895,3896,3898,3901,3903,3905],{"class":3385,"line":3386},[3383,3897,3621],{"class":3634},[3383,3899,3900],{"class":3637}," \u002Fpage ",[3383,3902,3334],{"class":3780},[3383,3904,3783],{"class":3637},[3383,3906,3907],{"class":3786},"1.1\n",[3383,3909,3910,3912,3914],{"class":3385,"line":3392},[3383,3911,3884],{"class":3657},[3383,3913,3795],{"class":3780},[3383,3915,3916],{"class":3798}," www.example.com\n",[3383,3918,3919,3922,3924],{"class":3385,"line":3398},[3383,3920,3921],{"class":3657},"Connection",[3383,3923,3795],{"class":3780},[3383,3925,3926],{"class":3798}," keep-alive\n",[3317,3928,3929,3932],{},[3321,3930,3931],{},"Chunked Transfer Encoding:"," Сервер може починати надсилати відповідь до того, як знає повний розмір:",[3373,3934,3936],{"className":3625,"code":3935,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nTransfer-Encoding: chunked\n\n1a\nПерший шматок даних...\nf\nДругий шматок.\n0\n\n",[3380,3937,3938,3951,3961,3965,3970,3975,3980,3985],{"__ignoreMap":3378},[3383,3939,3940,3942,3944,3947,3949],{"class":3385,"line":3386},[3383,3941,3334],{"class":3780},[3383,3943,3783],{"class":3637},[3383,3945,3946],{"class":3786},"1.1",[3383,3948,3816],{"class":3786},[3383,3950,3819],{"class":3798},[3383,3952,3953,3956,3958],{"class":3385,"line":3392},[3383,3954,3955],{"class":3657},"Transfer-Encoding",[3383,3957,3795],{"class":3780},[3383,3959,3960],{"class":3798}," chunked\n",[3383,3962,3963],{"class":3385,"line":3398},[3383,3964,3408],{"emptyLinePlaceholder":3407},[3383,3966,3967],{"class":3385,"line":3404},[3383,3968,3969],{"class":3637},"1a\n",[3383,3971,3972],{"class":3385,"line":3411},[3383,3973,3974],{"class":3637},"Перший шматок даних...\n",[3383,3976,3977],{"class":3385,"line":3417},[3383,3978,3979],{"class":3637},"f\n",[3383,3981,3982],{"class":3385,"line":3423},[3383,3983,3984],{"class":3637},"Другий шматок.\n",[3383,3986,3987],{"class":3385,"line":3429},[3383,3988,3989],{"class":3637},"0\n",[3317,3991,3992,3995,3996,3999],{},[3321,3993,3994],{},"Pipelining (теоретично):"," Клієнт може надсилати кілька запитів не чекаючи відповіді. На практиці — майже ніколи не використовується через проблему ",[3321,3997,3998],{},"Head-of-Line blocking",": відповіді повинні йти в тому ж порядку, що й запити. Якщо перший запит повільний — всі наступні чекають.",[3599,4001,4003],{"id":4002},"http2-бінарний-мультиплексинг-rfc-7540-2015","HTTP\u002F2 — Бінарний мультиплексинг (RFC 7540, 2015)",[3317,4005,4006],{},"Розроблений Google як протокол SPDY. Повністю зворотньо сумісний з HTTP (ті самі методи, коди, заголовки) — але радикально інший на транспортному рівні.",[3317,4008,4009,4012],{},[3321,4010,4011],{},"Бінарний фреймінг:"," замість текстового протоколу — двійковий. Ефективніший для парсингу, менше помилок.",[3317,4014,4015,4018],{},[3321,4016,4017],{},"Мультиплексування:"," кілька запитів одночасно в одному TCP-з'єднанні. Кожен запит — окремий «потік» (stream). Немає HOL blocking на рівні застосунку.",[3317,4020,4021,4024,4025,4028],{},[3321,4022,4023],{},"HPACK:"," Стиснення заголовків зі статичними та динамічними таблицями. Замість повторної відправки ",[3380,4026,4027],{},"Content-Type: application\u002Fjson"," — лише індекс у таблиці.",[3317,4030,4031,4034],{},[3321,4032,4033],{},"Server Push:"," Сервер може «заздалегідь» надіслати ресурси, що знадобляться клієнту (наприклад, CSS та JS разом з HTML).",[3599,4036,4038],{"id":4037},"http3-прощай-tcp-rfc-9114-2022","HTTP\u002F3 — Прощай, TCP (RFC 9114, 2022)",[3317,4040,4041,4042,4045],{},"Головна проблема HTTP\u002F2: ",[3321,4043,4044],{},"TCP HOL blocking",". Якщо один TCP-пакет загубився — всі потоки HTTP\u002F2 чекають його перепередачі, навіть не пов'язані між собою.",[3317,4047,4048,4049,4052],{},"HTTP\u002F3 замінює TCP на ",[3321,4050,4051],{},"QUIC"," — протокол транспортного рівня поверх UDP, розроблений Google. QUIC будує власний механізм надійності на рівні потоків, тому втрата пакету одного потоку не блокує інші.",[3370,4054,4055],{},[3373,4056,4058],{"className":3375,"code":4057,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nrectangle \"HTTP\u002F1.0\\n(1996)\" as h10 #fce4ec {\n    rectangle \"Нове TCP\\nна кожен запит\" as c10 #f48fb1\n}\n\nrectangle \"HTTP\u002F1.1\\n(1997)\" as h11 #fff9c4 {\n    rectangle \"Keep-Alive\\nPipelining (теор.)\" as c11 #ffe082\n}\n\nrectangle \"HTTP\u002F2\\n(2015)\" as h2 #e3f2fd {\n    rectangle \"Мультиплексинг\\nHPACK\\nServer Push\" as c2 #90caf9\n}\n\nrectangle \"HTTP\u002F3\\n(2022)\" as h3 #e8f5e9 {\n    rectangle \"QUIC (UDP)\\n0-RTT\\nПовне усунення\\nHOL blocking\" as c3 #a5d6a7\n}\n\nh10 -right-> h11 : Keep-Alive\nh11 -right-> h2 : Бінарний протокол\nh2 -right-> h3 : Замінює TCP\n\nnote bottom of h10\n  31 з'єднання\n  для 1 сторінки\n  з 30 img\nend note\n\nnote bottom of h11\n  1 з'єднання,\n  але черга запитів\nend note\n\nnote bottom of h2\n  Паралельні потоки,\n  але TCP HOL ще є\nend note\n\nnote bottom of h3\n  Повна паралельність,\n  навіть при втраті пакетів\nend note\n\n@enduml\n",[3380,4059,4060,4065,4069,4073,4077,4082,4087,4092,4096,4101,4106,4110,4114,4119,4124,4128,4132,4137,4142,4146,4150,4155,4160,4165,4169,4174,4179,4184,4189,4194,4198,4203,4208,4213,4218,4223,4229,4235,4241,4246,4251,4257,4263,4269,4274,4279],{"__ignoreMap":3378},[3383,4061,4062],{"class":3385,"line":3386},[3383,4063,4064],{},"@startuml\n",[3383,4066,4067],{"class":3385,"line":3392},[3383,4068,3395],{},[3383,4070,4071],{"class":3385,"line":3398},[3383,4072,3401],{},[3383,4074,4075],{"class":3385,"line":3404},[3383,4076,3408],{"emptyLinePlaceholder":3407},[3383,4078,4079],{"class":3385,"line":3411},[3383,4080,4081],{},"rectangle \"HTTP\u002F1.0\\n(1996)\" as h10 #fce4ec {\n",[3383,4083,4084],{"class":3385,"line":3417},[3383,4085,4086],{},"    rectangle \"Нове TCP\\nна кожен запит\" as c10 #f48fb1\n",[3383,4088,4089],{"class":3385,"line":3423},[3383,4090,4091],{},"}\n",[3383,4093,4094],{"class":3385,"line":3429},[3383,4095,3408],{"emptyLinePlaceholder":3407},[3383,4097,4098],{"class":3385,"line":3435},[3383,4099,4100],{},"rectangle \"HTTP\u002F1.1\\n(1997)\" as h11 #fff9c4 {\n",[3383,4102,4103],{"class":3385,"line":3441},[3383,4104,4105],{},"    rectangle \"Keep-Alive\\nPipelining (теор.)\" as c11 #ffe082\n",[3383,4107,4108],{"class":3385,"line":3447},[3383,4109,4091],{},[3383,4111,4112],{"class":3385,"line":3453},[3383,4113,3408],{"emptyLinePlaceholder":3407},[3383,4115,4116],{"class":3385,"line":3459},[3383,4117,4118],{},"rectangle \"HTTP\u002F2\\n(2015)\" as h2 #e3f2fd {\n",[3383,4120,4121],{"class":3385,"line":3465},[3383,4122,4123],{},"    rectangle \"Мультиплексинг\\nHPACK\\nServer Push\" as c2 #90caf9\n",[3383,4125,4126],{"class":3385,"line":3471},[3383,4127,4091],{},[3383,4129,4130],{"class":3385,"line":3477},[3383,4131,3408],{"emptyLinePlaceholder":3407},[3383,4133,4134],{"class":3385,"line":3483},[3383,4135,4136],{},"rectangle \"HTTP\u002F3\\n(2022)\" as h3 #e8f5e9 {\n",[3383,4138,4139],{"class":3385,"line":3489},[3383,4140,4141],{},"    rectangle \"QUIC (UDP)\\n0-RTT\\nПовне усунення\\nHOL blocking\" as c3 #a5d6a7\n",[3383,4143,4144],{"class":3385,"line":3495},[3383,4145,4091],{},[3383,4147,4148],{"class":3385,"line":3501},[3383,4149,3408],{"emptyLinePlaceholder":3407},[3383,4151,4152],{"class":3385,"line":3507},[3383,4153,4154],{},"h10 -right-> h11 : Keep-Alive\n",[3383,4156,4157],{"class":3385,"line":3513},[3383,4158,4159],{},"h11 -right-> h2 : Бінарний протокол\n",[3383,4161,4162],{"class":3385,"line":3519},[3383,4163,4164],{},"h2 -right-> h3 : Замінює TCP\n",[3383,4166,4167],{"class":3385,"line":3525},[3383,4168,3408],{"emptyLinePlaceholder":3407},[3383,4170,4171],{"class":3385,"line":3531},[3383,4172,4173],{},"note bottom of h10\n",[3383,4175,4176],{"class":3385,"line":3537},[3383,4177,4178],{},"  31 з'єднання\n",[3383,4180,4181],{"class":3385,"line":3543},[3383,4182,4183],{},"  для 1 сторінки\n",[3383,4185,4186],{"class":3385,"line":3549},[3383,4187,4188],{},"  з 30 img\n",[3383,4190,4191],{"class":3385,"line":3555},[3383,4192,4193],{},"end note\n",[3383,4195,4196],{"class":3385,"line":3561},[3383,4197,3408],{"emptyLinePlaceholder":3407},[3383,4199,4200],{"class":3385,"line":3567},[3383,4201,4202],{},"note bottom of h11\n",[3383,4204,4205],{"class":3385,"line":3573},[3383,4206,4207],{},"  1 з'єднання,\n",[3383,4209,4210],{"class":3385,"line":3579},[3383,4211,4212],{},"  але черга запитів\n",[3383,4214,4216],{"class":3385,"line":4215},34,[3383,4217,4193],{},[3383,4219,4221],{"class":3385,"line":4220},35,[3383,4222,3408],{"emptyLinePlaceholder":3407},[3383,4224,4226],{"class":3385,"line":4225},36,[3383,4227,4228],{},"note bottom of h2\n",[3383,4230,4232],{"class":3385,"line":4231},37,[3383,4233,4234],{},"  Паралельні потоки,\n",[3383,4236,4238],{"class":3385,"line":4237},38,[3383,4239,4240],{},"  але TCP HOL ще є\n",[3383,4242,4244],{"class":3385,"line":4243},39,[3383,4245,4193],{},[3383,4247,4249],{"class":3385,"line":4248},40,[3383,4250,3408],{"emptyLinePlaceholder":3407},[3383,4252,4254],{"class":3385,"line":4253},41,[3383,4255,4256],{},"note bottom of h3\n",[3383,4258,4260],{"class":3385,"line":4259},42,[3383,4261,4262],{},"  Повна паралельність,\n",[3383,4264,4266],{"class":3385,"line":4265},43,[3383,4267,4268],{},"  навіть при втраті пакетів\n",[3383,4270,4272],{"class":3385,"line":4271},44,[3383,4273,4193],{},[3383,4275,4277],{"class":3385,"line":4276},45,[3383,4278,3408],{"emptyLinePlaceholder":3407},[3383,4280,4282],{"class":3385,"line":4281},46,[3383,4283,4284],{},"@enduml\n",[3360,4286],{},[3312,4288,4290],{"id":4289},"url-уніфікований-локатор-ресурсів","URL: Уніфікований локатор ресурсів",[3599,4292,4294],{"id":4293},"що-таке-url","Що таке URL",[3317,4296,4297,4300],{},[3321,4298,4299],{},"URL"," (Uniform Resource Locator, RFC 3986) — це рядок, що однозначно ідентифікує ресурс у мережі та вказує спосіб отримання доступу до нього. Кожна частина URL несе чітко визначений сенс.",[3599,4302,4304],{"id":4303},"анатомія-url","Анатомія URL",[3373,4306,4311],{"className":4307,"code":4309,"language":4310},[4308],"language-text","https:\u002F\u002Fuser:password@api.example.com:8443\u002Fv1\u002Fusers\u002F42?role=admin&page=2#profile\n└──┬──┘ └──┬─────────┘ └──────┬──────┘ └┬─┘ └──────┬──────┘ └────────┬───────┘ └──┬──┘\nScheme  UserInfo          Host      Port    Path        Query          Fragment\n","text",[3380,4312,4309],{"__ignoreMap":3378},[3370,4314,4315],{},[3373,4316,4318],{"className":3375,"code":4317,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nrectangle \"URL\" #f5f5f5 {\n    rectangle \"scheme\\nhttps\" as scheme #e3f2fd\n    rectangle \":\u002F\u002F\" as sep1 #f5f5f5\n    rectangle \"userinfo\\nuser:pass\" as user #fff9c4\n    rectangle \"@\" as sep2 #f5f5f5\n    rectangle \"host\\napi.example.com\" as host #e8f5e9\n    rectangle \":\" as sep3 #f5f5f5\n    rectangle \"port\\n8443\" as port #fce4ec\n    rectangle \"path\\n\u002Fv1\u002Fusers\u002F42\" as path #fff3e0\n    rectangle \"?\" as sep4 #f5f5f5\n    rectangle \"query\\nrole=admin&page=2\" as query #f3e5f5\n    rectangle \"#\" as sep5 #f5f5f5\n    rectangle \"fragment\\nprofile\" as frag #e0f7fa\n\n    scheme -[hidden]right-> sep1\n    sep1 -[hidden]right-> user\n    user -[hidden]right-> sep2\n    sep2 -[hidden]right-> host\n    host -[hidden]right-> sep3\n    sep3 -[hidden]right-> port\n    port -[hidden]right-> path\n    path -[hidden]right-> sep4\n    sep4 -[hidden]right-> query\n    query -[hidden]right-> sep5\n    sep5 -[hidden]right-> frag\n}\n\nnote bottom of scheme\n  http або https.\n  Визначає протокол.\nend note\n\nnote bottom of host\n  Доменне ім'я або IP.\n  Резолвиться через DNS.\nend note\n\nnote bottom of port\n  За замовчуванням:\n  http → 80\n  https → 443\nend note\n\nnote bottom of path\n  Ієрархічний\n  ідентифікатор\n  ресурсу.\nend note\n\nnote bottom of query\n  Параметри фільтрації,\n  сортування, пагінації.\n  key=value&key2=value2\nend note\n\nnote bottom of frag\n  НЕ надсилається\n  серверу!\n  Тільки браузер.\nend note\n\n@enduml\n",[3380,4319,4320,4324,4328,4332,4336,4341,4346,4351,4356,4361,4366,4371,4376,4381,4386,4391,4396,4401,4405,4410,4415,4420,4425,4430,4435,4440,4445,4450,4455,4460,4464,4468,4473,4478,4483,4487,4491,4496,4501,4506,4510,4514,4519,4524,4529,4534,4538,4543,4549,4555,4561,4567,4572,4577,4583,4589,4595,4601,4606,4611,4617,4623,4629,4635,4640,4645],{"__ignoreMap":3378},[3383,4321,4322],{"class":3385,"line":3386},[3383,4323,4064],{},[3383,4325,4326],{"class":3385,"line":3392},[3383,4327,3395],{},[3383,4329,4330],{"class":3385,"line":3398},[3383,4331,3401],{},[3383,4333,4334],{"class":3385,"line":3404},[3383,4335,3408],{"emptyLinePlaceholder":3407},[3383,4337,4338],{"class":3385,"line":3411},[3383,4339,4340],{},"rectangle \"URL\" #f5f5f5 {\n",[3383,4342,4343],{"class":3385,"line":3417},[3383,4344,4345],{},"    rectangle \"scheme\\nhttps\" as scheme #e3f2fd\n",[3383,4347,4348],{"class":3385,"line":3423},[3383,4349,4350],{},"    rectangle \":\u002F\u002F\" as sep1 #f5f5f5\n",[3383,4352,4353],{"class":3385,"line":3429},[3383,4354,4355],{},"    rectangle \"userinfo\\nuser:pass\" as user #fff9c4\n",[3383,4357,4358],{"class":3385,"line":3435},[3383,4359,4360],{},"    rectangle \"@\" as sep2 #f5f5f5\n",[3383,4362,4363],{"class":3385,"line":3441},[3383,4364,4365],{},"    rectangle \"host\\napi.example.com\" as host #e8f5e9\n",[3383,4367,4368],{"class":3385,"line":3447},[3383,4369,4370],{},"    rectangle \":\" as sep3 #f5f5f5\n",[3383,4372,4373],{"class":3385,"line":3453},[3383,4374,4375],{},"    rectangle \"port\\n8443\" as port #fce4ec\n",[3383,4377,4378],{"class":3385,"line":3459},[3383,4379,4380],{},"    rectangle \"path\\n\u002Fv1\u002Fusers\u002F42\" as path #fff3e0\n",[3383,4382,4383],{"class":3385,"line":3465},[3383,4384,4385],{},"    rectangle \"?\" as sep4 #f5f5f5\n",[3383,4387,4388],{"class":3385,"line":3471},[3383,4389,4390],{},"    rectangle \"query\\nrole=admin&page=2\" as query #f3e5f5\n",[3383,4392,4393],{"class":3385,"line":3477},[3383,4394,4395],{},"    rectangle \"#\" as sep5 #f5f5f5\n",[3383,4397,4398],{"class":3385,"line":3483},[3383,4399,4400],{},"    rectangle \"fragment\\nprofile\" as frag #e0f7fa\n",[3383,4402,4403],{"class":3385,"line":3489},[3383,4404,3408],{"emptyLinePlaceholder":3407},[3383,4406,4407],{"class":3385,"line":3495},[3383,4408,4409],{},"    scheme -[hidden]right-> sep1\n",[3383,4411,4412],{"class":3385,"line":3501},[3383,4413,4414],{},"    sep1 -[hidden]right-> user\n",[3383,4416,4417],{"class":3385,"line":3507},[3383,4418,4419],{},"    user -[hidden]right-> sep2\n",[3383,4421,4422],{"class":3385,"line":3513},[3383,4423,4424],{},"    sep2 -[hidden]right-> host\n",[3383,4426,4427],{"class":3385,"line":3519},[3383,4428,4429],{},"    host -[hidden]right-> sep3\n",[3383,4431,4432],{"class":3385,"line":3525},[3383,4433,4434],{},"    sep3 -[hidden]right-> port\n",[3383,4436,4437],{"class":3385,"line":3531},[3383,4438,4439],{},"    port -[hidden]right-> path\n",[3383,4441,4442],{"class":3385,"line":3537},[3383,4443,4444],{},"    path -[hidden]right-> sep4\n",[3383,4446,4447],{"class":3385,"line":3543},[3383,4448,4449],{},"    sep4 -[hidden]right-> query\n",[3383,4451,4452],{"class":3385,"line":3549},[3383,4453,4454],{},"    query -[hidden]right-> sep5\n",[3383,4456,4457],{"class":3385,"line":3555},[3383,4458,4459],{},"    sep5 -[hidden]right-> frag\n",[3383,4461,4462],{"class":3385,"line":3561},[3383,4463,4091],{},[3383,4465,4466],{"class":3385,"line":3567},[3383,4467,3408],{"emptyLinePlaceholder":3407},[3383,4469,4470],{"class":3385,"line":3573},[3383,4471,4472],{},"note bottom of scheme\n",[3383,4474,4475],{"class":3385,"line":3579},[3383,4476,4477],{},"  http або https.\n",[3383,4479,4480],{"class":3385,"line":4215},[3383,4481,4482],{},"  Визначає протокол.\n",[3383,4484,4485],{"class":3385,"line":4220},[3383,4486,4193],{},[3383,4488,4489],{"class":3385,"line":4225},[3383,4490,3408],{"emptyLinePlaceholder":3407},[3383,4492,4493],{"class":3385,"line":4231},[3383,4494,4495],{},"note bottom of host\n",[3383,4497,4498],{"class":3385,"line":4237},[3383,4499,4500],{},"  Доменне ім'я або IP.\n",[3383,4502,4503],{"class":3385,"line":4243},[3383,4504,4505],{},"  Резолвиться через DNS.\n",[3383,4507,4508],{"class":3385,"line":4248},[3383,4509,4193],{},[3383,4511,4512],{"class":3385,"line":4253},[3383,4513,3408],{"emptyLinePlaceholder":3407},[3383,4515,4516],{"class":3385,"line":4259},[3383,4517,4518],{},"note bottom of port\n",[3383,4520,4521],{"class":3385,"line":4265},[3383,4522,4523],{},"  За замовчуванням:\n",[3383,4525,4526],{"class":3385,"line":4271},[3383,4527,4528],{},"  http → 80\n",[3383,4530,4531],{"class":3385,"line":4276},[3383,4532,4533],{},"  https → 443\n",[3383,4535,4536],{"class":3385,"line":4281},[3383,4537,4193],{},[3383,4539,4541],{"class":3385,"line":4540},47,[3383,4542,3408],{"emptyLinePlaceholder":3407},[3383,4544,4546],{"class":3385,"line":4545},48,[3383,4547,4548],{},"note bottom of path\n",[3383,4550,4552],{"class":3385,"line":4551},49,[3383,4553,4554],{},"  Ієрархічний\n",[3383,4556,4558],{"class":3385,"line":4557},50,[3383,4559,4560],{},"  ідентифікатор\n",[3383,4562,4564],{"class":3385,"line":4563},51,[3383,4565,4566],{},"  ресурсу.\n",[3383,4568,4570],{"class":3385,"line":4569},52,[3383,4571,4193],{},[3383,4573,4575],{"class":3385,"line":4574},53,[3383,4576,3408],{"emptyLinePlaceholder":3407},[3383,4578,4580],{"class":3385,"line":4579},54,[3383,4581,4582],{},"note bottom of query\n",[3383,4584,4586],{"class":3385,"line":4585},55,[3383,4587,4588],{},"  Параметри фільтрації,\n",[3383,4590,4592],{"class":3385,"line":4591},56,[3383,4593,4594],{},"  сортування, пагінації.\n",[3383,4596,4598],{"class":3385,"line":4597},57,[3383,4599,4600],{},"  key=value&key2=value2\n",[3383,4602,4604],{"class":3385,"line":4603},58,[3383,4605,4193],{},[3383,4607,4609],{"class":3385,"line":4608},59,[3383,4610,3408],{"emptyLinePlaceholder":3407},[3383,4612,4614],{"class":3385,"line":4613},60,[3383,4615,4616],{},"note bottom of frag\n",[3383,4618,4620],{"class":3385,"line":4619},61,[3383,4621,4622],{},"  НЕ надсилається\n",[3383,4624,4626],{"class":3385,"line":4625},62,[3383,4627,4628],{},"  серверу!\n",[3383,4630,4632],{"class":3385,"line":4631},63,[3383,4633,4634],{},"  Тільки браузер.\n",[3383,4636,4638],{"class":3385,"line":4637},64,[3383,4639,4193],{},[3383,4641,4643],{"class":3385,"line":4642},65,[3383,4644,3408],{"emptyLinePlaceholder":3407},[3383,4646,4648],{"class":3385,"line":4647},66,[3383,4649,4284],{},[3599,4651,4653],{"id":4652},"детальний-розбір-кожної-компоненти","Детальний розбір кожної компоненти",[4655,4656,4657,4706,4717,4734,4749,4818,4881],"field-group",{},[4658,4659,4662,4665],"field",{"name":4660,"type":4661},"Scheme (протокол)","string (обов'язковий)",[3317,4663,4664],{},"Визначає протокол доступу до ресурсу. Реєстронезалежний. Поширені схеми:",[3719,4666,4667,4672,4678,4684,4694,4700],{},[3722,4668,4669,4671],{},[3380,4670,3627],{}," — незахищений HTTP (порт 80 за замовчуванням)",[3722,4673,4674,4677],{},[3380,4675,4676],{},"https"," — HTTP over TLS (порт 443 за замовчуванням)",[3722,4679,4680,4683],{},[3380,4681,4682],{},"ftp"," — File Transfer Protocol (порт 21)",[3722,4685,4686,4689,4690,4693],{},[3380,4687,4688],{},"ws"," \u002F ",[3380,4691,4692],{},"wss"," — WebSocket (незахищений \u002F захищений)",[3722,4695,4696,4699],{},[3380,4697,4698],{},"mailto"," — email-адреса (не HTTP)",[3722,4701,4702,4705],{},[3380,4703,4704],{},"file"," — локальна файлова система",[4658,4707,4710,3727,4713,4716],{"name":4708,"type":4709},"Authority = [userinfo@] host [:port]","string",[3321,4711,4712],{},"Userinfo",[3380,4714,4715],{},"user:password@",") — базова автентифікація в URL. Застаріла практика — паролі видно в логах та адресному рядку. Ніколи не використовуйте у production.",[4658,4718,4719,4721,4722,4725,4726,4729,4730,4733],{"name":3884,"type":4709},[3321,4720,3884],{}," — доменне ім'я (",[3380,4723,4724],{},"api.example.com",") або IPv4 (",[3380,4727,4728],{},"192.168.1.1",") або IPv6 у дужках (",[3380,4731,4732],{},"[::1]","). Регістронезалежний. Резолвиться через DNS у IP-адресу.",[4658,4735,4738,4740,4741,4744,4745,4748],{"name":4736,"type":4737},"Port","number",[3321,4739,4736],{}," — число від 1 до 65535. Якщо не вказано — використовується порт за замовчуванням для схеми. ",[3380,4742,4743],{},"https:\u002F\u002Fexample.com:443\u002F"," = ",[3380,4746,4747],{},"https:\u002F\u002Fexample.com\u002F"," (443 — порт за замовчуванням для HTTPS).",[4658,4750,4752,4761,4764,4789,4792],{"name":4751,"type":4709},"Path (шлях)",[3317,4753,4754,4755,4757,4758,4760],{},"Ієрархічний ідентифікатор ресурсу. Починається з ",[3380,4756,3783],{},". Компоненти розділяються ",[3380,4759,3783],{},".",[3317,4762,4763],{},"Правила:",[3719,4765,4766,4780,4786],{},[3722,4767,4768,4771,4772,4775,4776,4779],{},[3380,4769,4770],{},"%XX"," — URL-кодування небезпечних символів (пробіл → ",[3380,4773,4774],{},"%20"," або ",[3380,4777,4778],{},"+"," у query)",[3722,4781,4782,4785],{},[3380,4783,4784],{},".."," — піддиректорія вгору (сервери повинні нормалізувати!)",[3722,4787,4788],{},"Регістрочутливий на Unix-серверах, регістронезалежний на Windows IIS",[3317,4790,4791],{},"Паттерни REST API:",[3719,4793,4794,4800,4806,4812],{},[3722,4795,4796,4799],{},[3380,4797,4798],{},"\u002Fusers"," — колекція",[3722,4801,4802,4805],{},[3380,4803,4804],{},"\u002Fusers\u002F42"," — конкретний ресурс за ID",[3722,4807,4808,4811],{},[3380,4809,4810],{},"\u002Fusers\u002F42\u002Forders"," — вкладений ресурс",[3722,4813,4814,4817],{},[3380,4815,4816],{},"\u002Fusers\u002F42\u002Forders\u002F7\u002Fitems"," — глибоко вкладений",[4658,4819,4822,4837,4872,4875],{"name":4820,"type":4821},"Query String (рядок запиту)","key=value пари",[3317,4823,4824,4825,4828,4829,4832,4833,4836],{},"Параметри, що передаються після ",[3380,4826,4827],{},"?",". Пари ",[3380,4830,4831],{},"key=value"," розділяються ",[3380,4834,4835],{},"&",". Порядок не гарантований (але на практиці зберігається).",[3317,4838,4839,4840,4842,4843,3727,4845,4842,4848,3727,4851,4842,4854,3727,4856,4842,4859,3727,4862,4842,4865,3727,4868,4871],{},"Символи, що потребують URL-кодування: пробіл (",[3380,4841,4774],{},"), ",[3380,4844,4835],{},[3380,4846,4847],{},"%26",[3380,4849,4850],{},"=",[3380,4852,4853],{},"%3D",[3380,4855,4778],{},[3380,4857,4858],{},"%2B",[3380,4860,4861],{},"#",[3380,4863,4864],{},"%23",[3380,4866,4867],{},"%",[3380,4869,4870],{},"%25",").",[3317,4873,4874],{},"Типові використання:",[3373,4876,4879],{"className":4877,"code":4878,"language":4310},[4308],"?search=HTTP%20протокол     — пошук\n?page=2&limit=20            — пагінація\n?sort=name&order=asc        — сортування\n?filter[role]=admin         — фільтрація (нестандартний синтаксис)\n?ids[]=1&ids[]=2&ids[]=3    — масив значень\n?callback=myFunc            — JSONP (застаріло)\n",[3380,4880,4878],{"__ignoreMap":3378},[4658,4882,4884,4894,4915],{"name":4883,"type":4709},"Fragment (фрагмент)",[3317,4885,4886,4887,4889,4890,4893],{},"Частина після ",[3380,4888,4861],{},". ",[3321,4891,4892],{},"Ніколи не надсилається серверу"," — обробляється виключно браузером. Використовується для:",[3719,4895,4896,4903,4909],{},[3722,4897,4898,4899,4902],{},"Навігації до розділу сторінки (",[3380,4900,4901],{},"#section-headers",")",[3722,4904,4905,4906,4902],{},"Single Page Application routing (",[3380,4907,4908],{},"#\u002Fusers\u002F42",[3722,4910,4911,4912,4902],{},"OAuth redirect URI state (",[3380,4913,4914],{},"#access_token=...",[3317,4916,4917],{},"Сервер взагалі не знає, який фрагмент вказав клієнт.",[3599,4919,4921],{"id":4920},"url-vs-uri-vs-urn","URL vs URI vs URN",[3317,4923,4924],{},"Ці терміни часто плутають:",[4926,4927,4928,4947],"table",{},[4929,4930,4931],"thead",{},[4932,4933,4934,4938,4941,4944],"tr",{},[4935,4936,4937],"th",{},"Термін",[4935,4939,4940],{},"Розшифровка",[4935,4942,4943],{},"Що ідентифікує",[4935,4945,4946],{},"Приклад",[4948,4949,4950,4972,4992],"tbody",{},[4932,4951,4952,4958,4961,4964],{},[4953,4954,4955],"td",{},[3321,4956,4957],{},"URI",[4953,4959,4960],{},"Uniform Resource Identifier",[4953,4962,4963],{},"Будь-який ресурс",[4953,4965,4966,3731,4969],{},[3380,4967,4968],{},"https:\u002F\u002F...",[3380,4970,4971],{},"urn:isbn:...",[4932,4973,4974,4978,4981,4987],{},[4953,4975,4976],{},[3321,4977,4299],{},[4953,4979,4980],{},"Uniform Resource Locator",[4953,4982,4983,4984],{},"Ресурс + ",[3321,4985,4986],{},"де знаходиться",[4953,4988,4989],{},[3380,4990,4991],{},"https:\u002F\u002Fapi.example.com\u002Fusers",[4932,4993,4994,4999,5002,5009],{},[4953,4995,4996],{},[3321,4997,4998],{},"URN",[4953,5000,5001],{},"Uniform Resource Name",[4953,5003,5004,5005,5008],{},"Ресурс за ",[3321,5006,5007],{},"іменем"," (без локації)",[4953,5010,5011],{},[3380,5012,5013],{},"urn:isbn:978-3-16-148410-0",[3317,5015,5016],{},"URL — підмножина URI. Будь-який URL є URI, але не кожен URI є URL.",[3599,5018,5020],{"id":5019},"абсолютні-та-відносні-url","Абсолютні та відносні URL",[3373,5022,5024],{"className":3625,"code":5023,"language":3627,"meta":3378,"style":3378},"# Абсолютний URL — повний, самодостатній\nhttps:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\u002F42\n\n# Відносний від схеми (protocol-relative) — рідко, але буває\n\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\n\n# Відносний від кореня хоста\n\u002Fv1\u002Fusers\u002F42\n\n# Відносний від поточного шляху\n..\u002Forders        → \u002Fv1\u002Forders  (якщо поточний \u002Fv1\u002Fusers\u002F42)\n.\u002Fprofile        → \u002Fv1\u002Fusers\u002Fprofile\n",[3380,5025,5026,5032,5037,5041,5046,5051,5055,5060,5065,5069,5074,5079],{"__ignoreMap":3378},[3383,5027,5028],{"class":3385,"line":3386},[3383,5029,5031],{"class":5030},"spJ8K","# Абсолютний URL — повний, самодостатній\n",[3383,5033,5034],{"class":3385,"line":3392},[3383,5035,5036],{"class":3637},"https:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\u002F42\n",[3383,5038,5039],{"class":3385,"line":3398},[3383,5040,3408],{"emptyLinePlaceholder":3407},[3383,5042,5043],{"class":3385,"line":3404},[3383,5044,5045],{"class":5030},"# Відносний від схеми (protocol-relative) — рідко, але буває\n",[3383,5047,5048],{"class":3385,"line":3411},[3383,5049,5050],{"class":5030},"\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\n",[3383,5052,5053],{"class":3385,"line":3417},[3383,5054,3408],{"emptyLinePlaceholder":3407},[3383,5056,5057],{"class":3385,"line":3423},[3383,5058,5059],{"class":5030},"# Відносний від кореня хоста\n",[3383,5061,5062],{"class":3385,"line":3429},[3383,5063,5064],{"class":3637},"\u002Fv1\u002Fusers\u002F42\n",[3383,5066,5067],{"class":3385,"line":3435},[3383,5068,3408],{"emptyLinePlaceholder":3407},[3383,5070,5071],{"class":3385,"line":3441},[3383,5072,5073],{"class":5030},"# Відносний від поточного шляху\n",[3383,5075,5076],{"class":3385,"line":3447},[3383,5077,5078],{"class":3637},"..\u002Forders        → \u002Fv1\u002Forders  (якщо поточний \u002Fv1\u002Fusers\u002F42)\n",[3383,5080,5081],{"class":3385,"line":3453},[3383,5082,5083],{"class":3637},".\u002Fprofile        → \u002Fv1\u002Fusers\u002Fprofile\n",[3599,5085,5087],{"id":5086},"url-кодування-у-c","URL-кодування у C#",[3373,5089,5094],{"className":5090,"code":5091,"language":5092,"meta":5093,"style":3378},"language-csharp shiki shiki-themes light-plus dark-plus dark-plus","using System.Net;\n\n\u002F\u002F ── Кодування компонент URL ──────────────────────────────────────────────────\n\nstring rawQuery = \"Пошук HTTP протоколу & cookies\";\n\n\u002F\u002F Uri.EscapeDataString — для кодування значення параметра (пробіл → %20)\nstring encoded = Uri.EscapeDataString(rawQuery);\n\u002F\u002F → \"%D0%9F%D0%BE%D1%88%D1%83%D0%BA%20HTTP%20%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%83%20%26%20cookies\"\n\n\u002F\u002F Uri.EscapeUriString — для кодування повного URI (зберігає структурні символи)\nstring uri = Uri.EscapeUriString(\"https:\u002F\u002Fexample.com\u002Fшлях?ключ=значення\");\n\n\u002F\u002F Декодування\nstring decoded = Uri.UnescapeDataString(encoded);\n\n\u002F\u002F ── Побудова URL з параметрами ───────────────────────────────────────────────\n\n\u002F\u002F Через UriBuilder — структурований підхід\nvar builder = new UriBuilder(\"https:\u002F\u002Fapi.example.com\")\n{\n    Path = \"\u002Fv1\u002Fusers\",\n    Port = -1, \u002F\u002F -1 = порт за замовчуванням (не додавати до URL)\n};\n\n\u002F\u002F Query string — Dictionary + Uri.EscapeDataString (не потребує System.Web)\nvar queryParams = new Dictionary\u003Cstring, string>\n{\n    [\"page\"] = \"2\",\n    [\"limit\"] = \"20\",\n    [\"search\"] = \"HTTP протокол\"\n};\n\nbuilder.Query = string.Join(\"&\",\n    queryParams.Select(kvp =>\n        $\"{Uri.EscapeDataString(kvp.Key)}={Uri.EscapeDataString(kvp.Value)}\"));\n\nConsole.WriteLine(builder.Uri);\n\u002F\u002F https:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers?page=2&limit=20&search=HTTP%20%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB\n\n\u002F\u002F ── Короткий рядковий варіант ──────────────────────────────────────────────\nstring baseUrl = \"https:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\";\nstring fullUrl = $\"{baseUrl}?page=2&limit=20&search={Uri.EscapeDataString(\\\"HTTP протокол\\\")}\";\n","csharp","showLineNumbers",[3380,5095,5096,5113,5117,5122,5126,5141,5145,5150,5177,5182,5186,5191,5214,5218,5223,5246,5250,5255,5259,5264,5288,5293,5306,5322,5327,5331,5336,5360,5364,5380,5394,5406,5410,5414,5440,5458,5512,5516,5536,5541,5545,5550,5564],{"__ignoreMap":3378},[3383,5097,5098,5101,5105,5107,5110],{"class":3385,"line":3386},[3383,5099,5100],{"class":3634},"using",[3383,5102,5104],{"class":5103},"sN1BT"," System",[3383,5106,4760],{"class":3637},[3383,5108,5109],{"class":5103},"Net",[3383,5111,5112],{"class":3637},";\n",[3383,5114,5115],{"class":3385,"line":3392},[3383,5116,3408],{"emptyLinePlaceholder":3407},[3383,5118,5119],{"class":3385,"line":3398},[3383,5120,5121],{"class":5030},"\u002F\u002F ── Кодування компонент URL ──────────────────────────────────────────────────\n",[3383,5123,5124],{"class":3385,"line":3404},[3383,5125,3408],{"emptyLinePlaceholder":3407},[3383,5127,5128,5130,5134,5136,5139],{"class":3385,"line":3411},[3383,5129,4709],{"class":3780},[3383,5131,5133],{"class":5132},"siwwj"," rawQuery",[3383,5135,4744],{"class":3637},[3383,5137,5138],{"class":3798},"\"Пошук HTTP протоколу & cookies\"",[3383,5140,5112],{"class":3637},[3383,5142,5143],{"class":3385,"line":3417},[3383,5144,3408],{"emptyLinePlaceholder":3407},[3383,5146,5147],{"class":3385,"line":3423},[3383,5148,5149],{"class":5030},"\u002F\u002F Uri.EscapeDataString — для кодування значення параметра (пробіл → %20)\n",[3383,5151,5152,5154,5157,5159,5162,5164,5168,5171,5174],{"class":3385,"line":3429},[3383,5153,4709],{"class":3780},[3383,5155,5156],{"class":5132}," encoded",[3383,5158,4744],{"class":3637},[3383,5160,5161],{"class":5132},"Uri",[3383,5163,4760],{"class":3637},[3383,5165,5167],{"class":5166},"s8Opu","EscapeDataString",[3383,5169,5170],{"class":3637},"(",[3383,5172,5173],{"class":5132},"rawQuery",[3383,5175,5176],{"class":3637},");\n",[3383,5178,5179],{"class":3385,"line":3435},[3383,5180,5181],{"class":5030},"\u002F\u002F → \"%D0%9F%D0%BE%D1%88%D1%83%D0%BA%20HTTP%20%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB%D1%83%20%26%20cookies\"\n",[3383,5183,5184],{"class":3385,"line":3441},[3383,5185,3408],{"emptyLinePlaceholder":3407},[3383,5187,5188],{"class":3385,"line":3447},[3383,5189,5190],{"class":5030},"\u002F\u002F Uri.EscapeUriString — для кодування повного URI (зберігає структурні символи)\n",[3383,5192,5193,5195,5198,5200,5202,5204,5207,5209,5212],{"class":3385,"line":3453},[3383,5194,4709],{"class":3780},[3383,5196,5197],{"class":5132}," uri",[3383,5199,4744],{"class":3637},[3383,5201,5161],{"class":5132},[3383,5203,4760],{"class":3637},[3383,5205,5206],{"class":5166},"EscapeUriString",[3383,5208,5170],{"class":3637},[3383,5210,5211],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fшлях?ключ=значення\"",[3383,5213,5176],{"class":3637},[3383,5215,5216],{"class":3385,"line":3459},[3383,5217,3408],{"emptyLinePlaceholder":3407},[3383,5219,5220],{"class":3385,"line":3465},[3383,5221,5222],{"class":5030},"\u002F\u002F Декодування\n",[3383,5224,5225,5227,5230,5232,5234,5236,5239,5241,5244],{"class":3385,"line":3471},[3383,5226,4709],{"class":3780},[3383,5228,5229],{"class":5132}," decoded",[3383,5231,4744],{"class":3637},[3383,5233,5161],{"class":5132},[3383,5235,4760],{"class":3637},[3383,5237,5238],{"class":5166},"UnescapeDataString",[3383,5240,5170],{"class":3637},[3383,5242,5243],{"class":5132},"encoded",[3383,5245,5176],{"class":3637},[3383,5247,5248],{"class":3385,"line":3477},[3383,5249,3408],{"emptyLinePlaceholder":3407},[3383,5251,5252],{"class":3385,"line":3483},[3383,5253,5254],{"class":5030},"\u002F\u002F ── Побудова URL з параметрами ───────────────────────────────────────────────\n",[3383,5256,5257],{"class":3385,"line":3489},[3383,5258,3408],{"emptyLinePlaceholder":3407},[3383,5260,5261],{"class":3385,"line":3495},[3383,5262,5263],{"class":5030},"\u002F\u002F Через UriBuilder — структурований підхід\n",[3383,5265,5266,5269,5272,5274,5277,5280,5282,5285],{"class":3385,"line":3501},[3383,5267,5268],{"class":3780},"var",[3383,5270,5271],{"class":5132}," builder",[3383,5273,4744],{"class":3637},[3383,5275,5276],{"class":3780},"new",[3383,5278,5279],{"class":5103}," UriBuilder",[3383,5281,5170],{"class":3637},[3383,5283,5284],{"class":3798},"\"https:\u002F\u002Fapi.example.com\"",[3383,5286,5287],{"class":3637},")\n",[3383,5289,5290],{"class":3385,"line":3507},[3383,5291,5292],{"class":3637},"{\n",[3383,5294,5295,5298,5300,5303],{"class":3385,"line":3513},[3383,5296,5297],{"class":5132},"    Path",[3383,5299,4744],{"class":3637},[3383,5301,5302],{"class":3798},"\"\u002Fv1\u002Fusers\"",[3383,5304,5305],{"class":3637},",\n",[3383,5307,5308,5311,5314,5317,5319],{"class":3385,"line":3519},[3383,5309,5310],{"class":5132},"    Port",[3383,5312,5313],{"class":3637}," = -",[3383,5315,5316],{"class":3786},"1",[3383,5318,3731],{"class":3637},[3383,5320,5321],{"class":5030},"\u002F\u002F -1 = порт за замовчуванням (не додавати до URL)\n",[3383,5323,5324],{"class":3385,"line":3525},[3383,5325,5326],{"class":3637},"};\n",[3383,5328,5329],{"class":3385,"line":3531},[3383,5330,3408],{"emptyLinePlaceholder":3407},[3383,5332,5333],{"class":3385,"line":3537},[3383,5334,5335],{"class":5030},"\u002F\u002F Query string — Dictionary + Uri.EscapeDataString (не потребує System.Web)\n",[3383,5337,5338,5340,5343,5345,5347,5350,5352,5354,5356,5358],{"class":3385,"line":3543},[3383,5339,5268],{"class":3780},[3383,5341,5342],{"class":5132}," queryParams",[3383,5344,4744],{"class":3637},[3383,5346,5276],{"class":3780},[3383,5348,5349],{"class":5103}," Dictionary",[3383,5351,3654],{"class":3637},[3383,5353,4709],{"class":3780},[3383,5355,3731],{"class":3637},[3383,5357,4709],{"class":3780},[3383,5359,3660],{"class":3637},[3383,5361,5362],{"class":3385,"line":3549},[3383,5363,5292],{"class":3637},[3383,5365,5366,5369,5372,5375,5378],{"class":3385,"line":3555},[3383,5367,5368],{"class":3637},"    [",[3383,5370,5371],{"class":3798},"\"page\"",[3383,5373,5374],{"class":3637},"] = ",[3383,5376,5377],{"class":3798},"\"2\"",[3383,5379,5305],{"class":3637},[3383,5381,5382,5384,5387,5389,5392],{"class":3385,"line":3561},[3383,5383,5368],{"class":3637},[3383,5385,5386],{"class":3798},"\"limit\"",[3383,5388,5374],{"class":3637},[3383,5390,5391],{"class":3798},"\"20\"",[3383,5393,5305],{"class":3637},[3383,5395,5396,5398,5401,5403],{"class":3385,"line":3567},[3383,5397,5368],{"class":3637},[3383,5399,5400],{"class":3798},"\"search\"",[3383,5402,5374],{"class":3637},[3383,5404,5405],{"class":3798},"\"HTTP протокол\"\n",[3383,5407,5408],{"class":3385,"line":3573},[3383,5409,5326],{"class":3637},[3383,5411,5412],{"class":3385,"line":3579},[3383,5413,3408],{"emptyLinePlaceholder":3407},[3383,5415,5416,5419,5421,5424,5426,5428,5430,5433,5435,5438],{"class":3385,"line":4215},[3383,5417,5418],{"class":5132},"builder",[3383,5420,4760],{"class":3637},[3383,5422,5423],{"class":5132},"Query",[3383,5425,4744],{"class":3637},[3383,5427,4709],{"class":3780},[3383,5429,4760],{"class":3637},[3383,5431,5432],{"class":5166},"Join",[3383,5434,5170],{"class":3637},[3383,5436,5437],{"class":3798},"\"&\"",[3383,5439,5305],{"class":3637},[3383,5441,5442,5445,5447,5450,5452,5455],{"class":3385,"line":4220},[3383,5443,5444],{"class":5132},"    queryParams",[3383,5446,4760],{"class":3637},[3383,5448,5449],{"class":5166},"Select",[3383,5451,5170],{"class":3637},[3383,5453,5454],{"class":5132},"kvp",[3383,5456,5457],{"class":3637}," =>\n",[3383,5459,5460,5463,5467,5469,5471,5473,5475,5477,5479,5482,5485,5487,5489,5491,5493,5495,5497,5499,5501,5504,5506,5509],{"class":3385,"line":4225},[3383,5461,5462],{"class":3798},"        $\"",[3383,5464,5466],{"class":5465},"sD7JJ","{",[3383,5468,5161],{"class":5132},[3383,5470,4760],{"class":5465},[3383,5472,5167],{"class":5166},[3383,5474,5170],{"class":5465},[3383,5476,5454],{"class":5132},[3383,5478,4760],{"class":5465},[3383,5480,5481],{"class":5132},"Key",[3383,5483,5484],{"class":5465},")}",[3383,5486,4850],{"class":3798},[3383,5488,5466],{"class":5465},[3383,5490,5161],{"class":5132},[3383,5492,4760],{"class":5465},[3383,5494,5167],{"class":5166},[3383,5496,5170],{"class":5465},[3383,5498,5454],{"class":5132},[3383,5500,4760],{"class":5465},[3383,5502,5503],{"class":5132},"Value",[3383,5505,5484],{"class":5465},[3383,5507,5508],{"class":3798},"\"",[3383,5510,5511],{"class":3637},"));\n",[3383,5513,5514],{"class":3385,"line":4231},[3383,5515,3408],{"emptyLinePlaceholder":3407},[3383,5517,5518,5521,5523,5526,5528,5530,5532,5534],{"class":3385,"line":4237},[3383,5519,5520],{"class":5132},"Console",[3383,5522,4760],{"class":3637},[3383,5524,5525],{"class":5166},"WriteLine",[3383,5527,5170],{"class":3637},[3383,5529,5418],{"class":5132},[3383,5531,4760],{"class":3637},[3383,5533,5161],{"class":5132},[3383,5535,5176],{"class":3637},[3383,5537,5538],{"class":3385,"line":4243},[3383,5539,5540],{"class":5030},"\u002F\u002F https:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers?page=2&limit=20&search=HTTP%20%D0%BF%D1%80%D0%BE%D1%82%D0%BE%D0%BA%D0%BE%D0%BB\n",[3383,5542,5543],{"class":3385,"line":4248},[3383,5544,3408],{"emptyLinePlaceholder":3407},[3383,5546,5547],{"class":3385,"line":4253},[3383,5548,5549],{"class":5030},"\u002F\u002F ── Короткий рядковий варіант ──────────────────────────────────────────────\n",[3383,5551,5552,5554,5557,5559,5562],{"class":3385,"line":4259},[3383,5553,4709],{"class":3780},[3383,5555,5556],{"class":5132}," baseUrl",[3383,5558,4744],{"class":3637},[3383,5560,5561],{"class":3798},"\"https:\u002F\u002Fapi.example.com\u002Fv1\u002Fusers\"",[3383,5563,5112],{"class":3637},[3383,5565,5566,5568,5571,5573,5576,5578,5581,5584,5587,5589,5591,5593,5595,5598,5601,5605,5608],{"class":3385,"line":4265},[3383,5567,4709],{"class":3780},[3383,5569,5570],{"class":5132}," fullUrl",[3383,5572,4744],{"class":3637},[3383,5574,5575],{"class":3798},"$\"",[3383,5577,5466],{"class":5465},[3383,5579,5580],{"class":5132},"baseUrl",[3383,5582,5583],{"class":5465},"}",[3383,5585,5586],{"class":3798},"?page=2&limit=20&search=",[3383,5588,5466],{"class":5465},[3383,5590,5161],{"class":5132},[3383,5592,4760],{"class":5465},[3383,5594,5167],{"class":5166},[3383,5596,5597],{"class":5465},"(\\",[3383,5599,5600],{"class":3798},"\"HTTP протокол",[3383,5602,5604],{"class":5603},"sjcCO","\\\"",[3383,5606,5607],{"class":3798},")}\"",[3383,5609,5112],{"class":5465},[3360,5611],{},[3312,5613,5615],{"id":5614},"місце-http-у-стеці-tcpip","Місце HTTP у стеці TCP\u002FIP",[3317,5617,5618],{},"Перш ніж розбирати деталі протоколу, критично важливо розуміти, де саме він знаходиться у стеці мережевих протоколів та на чому базується.",[3370,5620,5621],{},[3373,5622,5624],{"className":3375,"code":5623,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nrectangle \"Прикладний рівень (Application)\" #e8f5e9 {\n    rectangle \"HTTP \u002F HTTPS\" as http #a5d6a7\n    rectangle \"WebSocket \u002F gRPC \u002F GraphQL\" as ws #c8e6c9\n}\n\nrectangle \"Транспортний рівень (Transport)\" #e3f2fd {\n    rectangle \"TCP (надійна доставка)\" as tcp #90caf9\n    rectangle \"QUIC (HTTP\u002F3)\" as quic #bbdefb\n}\n\nrectangle \"Мережевий рівень (Network)\" #fff3e0 {\n    rectangle \"IP (адресація та маршрутизація)\" as ip #ffe0b2\n}\n\nrectangle \"Канальний рівень (Data Link)\" #fce4ec {\n    rectangle \"Ethernet \u002F Wi-Fi\" as eth #f48fb1\n}\n\nhttp -down-> tcp : поверх TCP\\n(порт 80\u002F443)\nws -down-> tcp\nquic -down-> ip : поверх UDP\ntcp -down-> ip\nip -down-> eth\n\nnote right of http\n    HTTP\u002F1.1 та HTTP\u002F2\n    використовують TCP.\n    HTTP\u002F3 — QUIC (UDP).\nend note\n\n@enduml\n",[3380,5625,5626,5630,5634,5638,5642,5647,5652,5657,5661,5665,5670,5675,5680,5684,5688,5693,5698,5702,5706,5711,5716,5720,5724,5729,5734,5739,5744,5749,5753,5758,5763,5768,5773,5777,5781],{"__ignoreMap":3378},[3383,5627,5628],{"class":3385,"line":3386},[3383,5629,4064],{},[3383,5631,5632],{"class":3385,"line":3392},[3383,5633,3395],{},[3383,5635,5636],{"class":3385,"line":3398},[3383,5637,3401],{},[3383,5639,5640],{"class":3385,"line":3404},[3383,5641,3408],{"emptyLinePlaceholder":3407},[3383,5643,5644],{"class":3385,"line":3411},[3383,5645,5646],{},"rectangle \"Прикладний рівень (Application)\" #e8f5e9 {\n",[3383,5648,5649],{"class":3385,"line":3417},[3383,5650,5651],{},"    rectangle \"HTTP \u002F HTTPS\" as http #a5d6a7\n",[3383,5653,5654],{"class":3385,"line":3423},[3383,5655,5656],{},"    rectangle \"WebSocket \u002F gRPC \u002F GraphQL\" as ws #c8e6c9\n",[3383,5658,5659],{"class":3385,"line":3429},[3383,5660,4091],{},[3383,5662,5663],{"class":3385,"line":3435},[3383,5664,3408],{"emptyLinePlaceholder":3407},[3383,5666,5667],{"class":3385,"line":3441},[3383,5668,5669],{},"rectangle \"Транспортний рівень (Transport)\" #e3f2fd {\n",[3383,5671,5672],{"class":3385,"line":3447},[3383,5673,5674],{},"    rectangle \"TCP (надійна доставка)\" as tcp #90caf9\n",[3383,5676,5677],{"class":3385,"line":3453},[3383,5678,5679],{},"    rectangle \"QUIC (HTTP\u002F3)\" as quic #bbdefb\n",[3383,5681,5682],{"class":3385,"line":3459},[3383,5683,4091],{},[3383,5685,5686],{"class":3385,"line":3465},[3383,5687,3408],{"emptyLinePlaceholder":3407},[3383,5689,5690],{"class":3385,"line":3471},[3383,5691,5692],{},"rectangle \"Мережевий рівень (Network)\" #fff3e0 {\n",[3383,5694,5695],{"class":3385,"line":3477},[3383,5696,5697],{},"    rectangle \"IP (адресація та маршрутизація)\" as ip #ffe0b2\n",[3383,5699,5700],{"class":3385,"line":3483},[3383,5701,4091],{},[3383,5703,5704],{"class":3385,"line":3489},[3383,5705,3408],{"emptyLinePlaceholder":3407},[3383,5707,5708],{"class":3385,"line":3495},[3383,5709,5710],{},"rectangle \"Канальний рівень (Data Link)\" #fce4ec {\n",[3383,5712,5713],{"class":3385,"line":3501},[3383,5714,5715],{},"    rectangle \"Ethernet \u002F Wi-Fi\" as eth #f48fb1\n",[3383,5717,5718],{"class":3385,"line":3507},[3383,5719,4091],{},[3383,5721,5722],{"class":3385,"line":3513},[3383,5723,3408],{"emptyLinePlaceholder":3407},[3383,5725,5726],{"class":3385,"line":3519},[3383,5727,5728],{},"http -down-> tcp : поверх TCP\\n(порт 80\u002F443)\n",[3383,5730,5731],{"class":3385,"line":3525},[3383,5732,5733],{},"ws -down-> tcp\n",[3383,5735,5736],{"class":3385,"line":3531},[3383,5737,5738],{},"quic -down-> ip : поверх UDP\n",[3383,5740,5741],{"class":3385,"line":3537},[3383,5742,5743],{},"tcp -down-> ip\n",[3383,5745,5746],{"class":3385,"line":3543},[3383,5747,5748],{},"ip -down-> eth\n",[3383,5750,5751],{"class":3385,"line":3549},[3383,5752,3408],{"emptyLinePlaceholder":3407},[3383,5754,5755],{"class":3385,"line":3555},[3383,5756,5757],{},"note right of http\n",[3383,5759,5760],{"class":3385,"line":3561},[3383,5761,5762],{},"    HTTP\u002F1.1 та HTTP\u002F2\n",[3383,5764,5765],{"class":3385,"line":3567},[3383,5766,5767],{},"    використовують TCP.\n",[3383,5769,5770],{"class":3385,"line":3573},[3383,5771,5772],{},"    HTTP\u002F3 — QUIC (UDP).\n",[3383,5774,5775],{"class":3385,"line":3579},[3383,5776,4193],{},[3383,5778,5779],{"class":3385,"line":4215},[3383,5780,3408],{"emptyLinePlaceholder":3407},[3383,5782,5783],{"class":3385,"line":4220},[3383,5784,4284],{},[4926,5786,5787,5800],{},[4929,5788,5789],{},[4932,5790,5791,5794,5797],{},[4935,5792,5793],{},"Рівень",[4935,5795,5796],{},"Протокол",[4935,5798,5799],{},"Відповідає за",[4948,5801,5802,5814,5827,5840],{},[4932,5803,5804,5807,5811],{},[4953,5805,5806],{},"Прикладний",[4953,5808,5809],{},[3321,5810,3334],{},[4953,5812,5813],{},"Семантика запитів і відповідей",[4932,5815,5816,5819,5824],{},[4953,5817,5818],{},"Транспортний",[4953,5820,5821],{},[3321,5822,5823],{},"TCP",[4953,5825,5826],{},"Надійна доставка, порядок, без втрат",[4932,5828,5829,5832,5837],{},[4953,5830,5831],{},"Мережевий",[4953,5833,5834],{},[3321,5835,5836],{},"IP",[4953,5838,5839],{},"Маршрутизація між мережами",[4932,5841,5842,5845,5850],{},[4953,5843,5844],{},"Канальний",[4953,5846,5847],{},[3321,5848,5849],{},"Ethernet\u002FWi-Fi",[4953,5851,5852],{},"Доставка в межах одного сегменту",[5854,5855,5856,5859],"tip",{},[3321,5857,5858],{},"Практичне значення для розробника:"," коли ваш HTTP-запит «зависає», проблема може бути на будь-якому рівні. DNS не резолвиться (прикладний рівень), TCP SYN не отримав SYN-ACK (транспортний), маршрут недоступний (мережевий), або WiFi погано працює (канальний). Розуміння стеку допомагає правильно діагностувати.",[3360,5861],{},[3312,5863,5865],{"id":5864},"анатомія-http-повідомлення","Анатомія HTTP-повідомлення",[3317,5867,5868,5869,5872,5873,5876],{},"HTTP-повідомлення бувають двох типів: ",[3321,5870,5871],{},"запит"," (Request) від клієнта до сервера та ",[3321,5874,5875],{},"відповідь"," (Response) від сервера до клієнта. Обидва мають однакову загальну структуру, але різні перші рядки.",[3599,5878,5880],{"id":5879},"структура-http-запиту","Структура HTTP-запиту",[3317,5882,5883],{},"Кожен HTTP-запит складається з трьох частин: стартового рядка, заголовків та (опціонально) тіла.",[3370,5885,5886],{},[3373,5887,5889],{"className":3375,"code":5888,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nrectangle \"HTTP Request\" #fff3e0 {\n    rectangle \"Request Line\" as rl #ffe0b2 {\n        rectangle \"Method\\nGET\" as m #ffcc80\n        rectangle \"Request Target\\n\u002Fapi\u002Fusers?page=1\" as rt #ffcc80\n        rectangle \"HTTP Version\\nHTTP\u002F1.1\" as v #ffcc80\n        m -[hidden]right-> rt\n        rt -[hidden]right-> v\n    }\n    rectangle \"Headers\" as h #e3f2fd {\n        rectangle \"Host: api.example.com\" as h1 #bbdefb\n        rectangle \"Accept: application\u002Fjson\" as h2 #bbdefb\n        rectangle \"Authorization: Bearer eyJ...\" as h3 #bbdefb\n        rectangle \"Content-Type: application\u002Fjson\" as h4 #bbdefb\n        h1 -[hidden]down-> h2\n        h2 -[hidden]down-> h3\n        h3 -[hidden]down-> h4\n    }\n    rectangle \"Empty Line (CRLF)\" as el #f5f5f5\n    rectangle \"Body (payload)\\n{\\\"name\\\": \\\"Alice\\\"}\" as b #e8f5e9\n    rl -[hidden]down-> h\n    h -[hidden]down-> el\n    el -[hidden]down-> b\n}\n\nnote right of rl\n  Обов'язковий.\n  Визначає метод,\n  ресурс і версію.\nend note\n\nnote right of h\n  Один або більше.\n  Формат: \"Name: Value CRLF\"\n  Закінчуються порожнім рядком.\nend note\n\nnote right of b\n  Опціональне.\n  Є у POST, PUT, PATCH.\n  Відсутнє у GET, HEAD, DELETE.\nend note\n\n@enduml\n",[3380,5890,5891,5895,5899,5903,5907,5912,5917,5922,5927,5932,5937,5942,5947,5952,5957,5962,5967,5972,5977,5982,5987,5991,5996,6001,6006,6011,6016,6020,6024,6029,6034,6039,6044,6048,6052,6057,6062,6067,6072,6076,6080,6085,6090,6095,6100,6104,6108],{"__ignoreMap":3378},[3383,5892,5893],{"class":3385,"line":3386},[3383,5894,4064],{},[3383,5896,5897],{"class":3385,"line":3392},[3383,5898,3395],{},[3383,5900,5901],{"class":3385,"line":3398},[3383,5902,3401],{},[3383,5904,5905],{"class":3385,"line":3404},[3383,5906,3408],{"emptyLinePlaceholder":3407},[3383,5908,5909],{"class":3385,"line":3411},[3383,5910,5911],{},"rectangle \"HTTP Request\" #fff3e0 {\n",[3383,5913,5914],{"class":3385,"line":3417},[3383,5915,5916],{},"    rectangle \"Request Line\" as rl #ffe0b2 {\n",[3383,5918,5919],{"class":3385,"line":3423},[3383,5920,5921],{},"        rectangle \"Method\\nGET\" as m #ffcc80\n",[3383,5923,5924],{"class":3385,"line":3429},[3383,5925,5926],{},"        rectangle \"Request Target\\n\u002Fapi\u002Fusers?page=1\" as rt #ffcc80\n",[3383,5928,5929],{"class":3385,"line":3435},[3383,5930,5931],{},"        rectangle \"HTTP Version\\nHTTP\u002F1.1\" as v #ffcc80\n",[3383,5933,5934],{"class":3385,"line":3441},[3383,5935,5936],{},"        m -[hidden]right-> rt\n",[3383,5938,5939],{"class":3385,"line":3447},[3383,5940,5941],{},"        rt -[hidden]right-> v\n",[3383,5943,5944],{"class":3385,"line":3453},[3383,5945,5946],{},"    }\n",[3383,5948,5949],{"class":3385,"line":3459},[3383,5950,5951],{},"    rectangle \"Headers\" as h #e3f2fd {\n",[3383,5953,5954],{"class":3385,"line":3465},[3383,5955,5956],{},"        rectangle \"Host: api.example.com\" as h1 #bbdefb\n",[3383,5958,5959],{"class":3385,"line":3471},[3383,5960,5961],{},"        rectangle \"Accept: application\u002Fjson\" as h2 #bbdefb\n",[3383,5963,5964],{"class":3385,"line":3477},[3383,5965,5966],{},"        rectangle \"Authorization: Bearer eyJ...\" as h3 #bbdefb\n",[3383,5968,5969],{"class":3385,"line":3483},[3383,5970,5971],{},"        rectangle \"Content-Type: application\u002Fjson\" as h4 #bbdefb\n",[3383,5973,5974],{"class":3385,"line":3489},[3383,5975,5976],{},"        h1 -[hidden]down-> h2\n",[3383,5978,5979],{"class":3385,"line":3495},[3383,5980,5981],{},"        h2 -[hidden]down-> h3\n",[3383,5983,5984],{"class":3385,"line":3501},[3383,5985,5986],{},"        h3 -[hidden]down-> h4\n",[3383,5988,5989],{"class":3385,"line":3507},[3383,5990,5946],{},[3383,5992,5993],{"class":3385,"line":3513},[3383,5994,5995],{},"    rectangle \"Empty Line (CRLF)\" as el #f5f5f5\n",[3383,5997,5998],{"class":3385,"line":3519},[3383,5999,6000],{},"    rectangle \"Body (payload)\\n{\\\"name\\\": \\\"Alice\\\"}\" as b #e8f5e9\n",[3383,6002,6003],{"class":3385,"line":3525},[3383,6004,6005],{},"    rl -[hidden]down-> h\n",[3383,6007,6008],{"class":3385,"line":3531},[3383,6009,6010],{},"    h -[hidden]down-> el\n",[3383,6012,6013],{"class":3385,"line":3537},[3383,6014,6015],{},"    el -[hidden]down-> b\n",[3383,6017,6018],{"class":3385,"line":3543},[3383,6019,4091],{},[3383,6021,6022],{"class":3385,"line":3549},[3383,6023,3408],{"emptyLinePlaceholder":3407},[3383,6025,6026],{"class":3385,"line":3555},[3383,6027,6028],{},"note right of rl\n",[3383,6030,6031],{"class":3385,"line":3561},[3383,6032,6033],{},"  Обов'язковий.\n",[3383,6035,6036],{"class":3385,"line":3567},[3383,6037,6038],{},"  Визначає метод,\n",[3383,6040,6041],{"class":3385,"line":3573},[3383,6042,6043],{},"  ресурс і версію.\n",[3383,6045,6046],{"class":3385,"line":3579},[3383,6047,4193],{},[3383,6049,6050],{"class":3385,"line":4215},[3383,6051,3408],{"emptyLinePlaceholder":3407},[3383,6053,6054],{"class":3385,"line":4220},[3383,6055,6056],{},"note right of h\n",[3383,6058,6059],{"class":3385,"line":4225},[3383,6060,6061],{},"  Один або більше.\n",[3383,6063,6064],{"class":3385,"line":4231},[3383,6065,6066],{},"  Формат: \"Name: Value CRLF\"\n",[3383,6068,6069],{"class":3385,"line":4237},[3383,6070,6071],{},"  Закінчуються порожнім рядком.\n",[3383,6073,6074],{"class":3385,"line":4243},[3383,6075,4193],{},[3383,6077,6078],{"class":3385,"line":4248},[3383,6079,3408],{"emptyLinePlaceholder":3407},[3383,6081,6082],{"class":3385,"line":4253},[3383,6083,6084],{},"note right of b\n",[3383,6086,6087],{"class":3385,"line":4259},[3383,6088,6089],{},"  Опціональне.\n",[3383,6091,6092],{"class":3385,"line":4265},[3383,6093,6094],{},"  Є у POST, PUT, PATCH.\n",[3383,6096,6097],{"class":3385,"line":4271},[3383,6098,6099],{},"  Відсутнє у GET, HEAD, DELETE.\n",[3383,6101,6102],{"class":3385,"line":4276},[3383,6103,4193],{},[3383,6105,6106],{"class":3385,"line":4281},[3383,6107,3408],{"emptyLinePlaceholder":3407},[3383,6109,6110],{"class":3385,"line":4540},[3383,6111,4284],{},[3317,6113,6114],{},"У «сирому» вигляді (як передається по TCP) HTTP-запит виглядає так:",[3373,6116,6118],{"className":3625,"code":6117,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers?page=1&limit=10 HTTP\u002F1.1\nHost: api.example.com\nAccept: application\u002Fjson\nAccept-Language: uk-UA,uk;q=0.9\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\nUser-Agent: Mozilla\u002F5.0 (compatible; MyApp\u002F1.0)\nConnection: keep-alive\n\u003Cempty line \\n\\r>\n",[3380,6119,6120,6133,6142,6151,6161,6171,6181,6189],{"__ignoreMap":3378},[3383,6121,6122,6124,6127,6129,6131],{"class":3385,"line":3386},[3383,6123,3621],{"class":3634},[3383,6125,6126],{"class":3637}," \u002Fapi\u002Fusers?page=1&limit=10 ",[3383,6128,3334],{"class":3780},[3383,6130,3783],{"class":3637},[3383,6132,3907],{"class":3786},[3383,6134,6135,6137,6139],{"class":3385,"line":3392},[3383,6136,3884],{"class":3657},[3383,6138,3795],{"class":3780},[3383,6140,6141],{"class":3798}," api.example.com\n",[3383,6143,6144,6146,6148],{"class":3385,"line":3398},[3383,6145,3792],{"class":3657},[3383,6147,3795],{"class":3780},[3383,6149,6150],{"class":3798}," application\u002Fjson\n",[3383,6152,6153,6156,6158],{"class":3385,"line":3404},[3383,6154,6155],{"class":3657},"Accept-Language",[3383,6157,3795],{"class":3780},[3383,6159,6160],{"class":3798}," uk-UA,uk;q=0.9\n",[3383,6162,6163,6166,6168],{"class":3385,"line":3411},[3383,6164,6165],{"class":3657},"Authorization",[3383,6167,3795],{"class":3780},[3383,6169,6170],{"class":3798}," Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\n",[3383,6172,6173,6176,6178],{"class":3385,"line":3417},[3383,6174,6175],{"class":3657},"User-Agent",[3383,6177,3795],{"class":3780},[3383,6179,6180],{"class":3798}," Mozilla\u002F5.0 (compatible; MyApp\u002F1.0)\n",[3383,6182,6183,6185,6187],{"class":3385,"line":3423},[3383,6184,3921],{"class":3657},[3383,6186,3795],{"class":3780},[3383,6188,3926],{"class":3798},[3383,6190,6191,6193,6196,6199],{"class":3385,"line":3429},[3383,6192,3654],{"class":3653},[3383,6194,6195],{"class":3657},"empty",[3383,6197,6198],{"class":3637}," line \\n\\r",[3383,6200,3660],{"class":3653},[3353,6202,6203,6204,6207],{},"Порожній рядок після заголовків є ",[3321,6205,6206],{},"обов'язковим"," — він сигналізує серверу, що всі заголовки передані. Якщо є тіло (наприклад, у POST-запиті), воно іде безпосередньо після цього порожнього рядка.",[3599,6209,6211],{"id":6210},"структура-http-відповіді","Структура HTTP-відповіді",[3370,6213,6214],{},[3373,6215,6217],{"className":3375,"code":6216,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nrectangle \"HTTP Response\" #e8f5e9 {\n    rectangle \"Status Line\" as sl #c8e6c9 {\n        rectangle \"HTTP Version\\nHTTP\u002F1.1\" as v #a5d6a7\n        rectangle \"Status Code\\n200\" as sc #a5d6a7\n        rectangle \"Reason Phrase\\nOK\" as rp #a5d6a7\n        v -[hidden]right-> sc\n        sc -[hidden]right-> rp\n    }\n    rectangle \"Response Headers\" as rh #e3f2fd {\n        rectangle \"Content-Type: application\u002Fjson; charset=utf-8\" as rh1 #bbdefb\n        rectangle \"Content-Length: 348\" as rh2 #bbdefb\n        rectangle \"Cache-Control: max-age=3600\" as rh3 #bbdefb\n        rectangle \"X-Request-Id: a3f8b2c1\" as rh4 #bbdefb\n        rh1 -[hidden]down-> rh2\n        rh2 -[hidden]down-> rh3\n        rh3 -[hidden]down-> rh4\n    }\n    rectangle \"Empty Line (CRLF)\" as el #f5f5f5\n    rectangle \"Response Body\\n[{\\\"id\\\":1,\\\"name\\\":\\\"Alice\\\"}, ...]\" as rb #fff9c4\n    sl -[hidden]down-> rh\n    rh -[hidden]down-> el\n    el -[hidden]down-> rb\n}\n\n@enduml\n",[3380,6218,6219,6223,6227,6231,6235,6240,6245,6250,6255,6260,6265,6270,6274,6279,6284,6289,6294,6299,6304,6309,6314,6318,6322,6327,6332,6337,6342,6346,6350],{"__ignoreMap":3378},[3383,6220,6221],{"class":3385,"line":3386},[3383,6222,4064],{},[3383,6224,6225],{"class":3385,"line":3392},[3383,6226,3395],{},[3383,6228,6229],{"class":3385,"line":3398},[3383,6230,3401],{},[3383,6232,6233],{"class":3385,"line":3404},[3383,6234,3408],{"emptyLinePlaceholder":3407},[3383,6236,6237],{"class":3385,"line":3411},[3383,6238,6239],{},"rectangle \"HTTP Response\" #e8f5e9 {\n",[3383,6241,6242],{"class":3385,"line":3417},[3383,6243,6244],{},"    rectangle \"Status Line\" as sl #c8e6c9 {\n",[3383,6246,6247],{"class":3385,"line":3423},[3383,6248,6249],{},"        rectangle \"HTTP Version\\nHTTP\u002F1.1\" as v #a5d6a7\n",[3383,6251,6252],{"class":3385,"line":3429},[3383,6253,6254],{},"        rectangle \"Status Code\\n200\" as sc #a5d6a7\n",[3383,6256,6257],{"class":3385,"line":3435},[3383,6258,6259],{},"        rectangle \"Reason Phrase\\nOK\" as rp #a5d6a7\n",[3383,6261,6262],{"class":3385,"line":3441},[3383,6263,6264],{},"        v -[hidden]right-> sc\n",[3383,6266,6267],{"class":3385,"line":3447},[3383,6268,6269],{},"        sc -[hidden]right-> rp\n",[3383,6271,6272],{"class":3385,"line":3453},[3383,6273,5946],{},[3383,6275,6276],{"class":3385,"line":3459},[3383,6277,6278],{},"    rectangle \"Response Headers\" as rh #e3f2fd {\n",[3383,6280,6281],{"class":3385,"line":3465},[3383,6282,6283],{},"        rectangle \"Content-Type: application\u002Fjson; charset=utf-8\" as rh1 #bbdefb\n",[3383,6285,6286],{"class":3385,"line":3471},[3383,6287,6288],{},"        rectangle \"Content-Length: 348\" as rh2 #bbdefb\n",[3383,6290,6291],{"class":3385,"line":3477},[3383,6292,6293],{},"        rectangle \"Cache-Control: max-age=3600\" as rh3 #bbdefb\n",[3383,6295,6296],{"class":3385,"line":3483},[3383,6297,6298],{},"        rectangle \"X-Request-Id: a3f8b2c1\" as rh4 #bbdefb\n",[3383,6300,6301],{"class":3385,"line":3489},[3383,6302,6303],{},"        rh1 -[hidden]down-> rh2\n",[3383,6305,6306],{"class":3385,"line":3495},[3383,6307,6308],{},"        rh2 -[hidden]down-> rh3\n",[3383,6310,6311],{"class":3385,"line":3501},[3383,6312,6313],{},"        rh3 -[hidden]down-> rh4\n",[3383,6315,6316],{"class":3385,"line":3507},[3383,6317,5946],{},[3383,6319,6320],{"class":3385,"line":3513},[3383,6321,5995],{},[3383,6323,6324],{"class":3385,"line":3519},[3383,6325,6326],{},"    rectangle \"Response Body\\n[{\\\"id\\\":1,\\\"name\\\":\\\"Alice\\\"}, ...]\" as rb #fff9c4\n",[3383,6328,6329],{"class":3385,"line":3525},[3383,6330,6331],{},"    sl -[hidden]down-> rh\n",[3383,6333,6334],{"class":3385,"line":3531},[3383,6335,6336],{},"    rh -[hidden]down-> el\n",[3383,6338,6339],{"class":3385,"line":3537},[3383,6340,6341],{},"    el -[hidden]down-> rb\n",[3383,6343,6344],{"class":3385,"line":3543},[3383,6345,4091],{},[3383,6347,6348],{"class":3385,"line":3549},[3383,6349,3408],{"emptyLinePlaceholder":3407},[3383,6351,6352],{"class":3385,"line":3555},[3383,6353,4284],{},[3373,6355,6357],{"className":3625,"code":6356,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson; charset=utf-8\nContent-Length: 348\nCache-Control: max-age=3600, public\nX-Request-Id: a3f8b2c1-d9e2-4f1a-b7c3-8e9d0a1f2b3c\nDate: Sun, 17 May 2026 09:00:00 GMT\n\n[\n  {\"id\": 1, \"name\": \"Alice\", \"email\": \"alice@example.com\"},\n  {\"id\": 2, \"name\": \"Bob\", \"email\": \"bob@example.com\"}\n]\n",[3380,6358,6359,6371,6380,6389,6399,6409,6418,6422,6427,6464,6495],{"__ignoreMap":3378},[3383,6360,6361,6363,6365,6367,6369],{"class":3385,"line":3386},[3383,6362,3334],{"class":3780},[3383,6364,3783],{"class":3637},[3383,6366,3946],{"class":3786},[3383,6368,3816],{"class":3786},[3383,6370,3819],{"class":3798},[3383,6372,6373,6375,6377],{"class":3385,"line":3392},[3383,6374,3730],{"class":3657},[3383,6376,3795],{"class":3780},[3383,6378,6379],{"class":3798}," application\u002Fjson; charset=utf-8\n",[3383,6381,6382,6384,6386],{"class":3385,"line":3398},[3383,6383,3734],{"class":3657},[3383,6385,3795],{"class":3780},[3383,6387,6388],{"class":3798}," 348\n",[3383,6390,6391,6394,6396],{"class":3385,"line":3404},[3383,6392,6393],{"class":3657},"Cache-Control",[3383,6395,3795],{"class":3780},[3383,6397,6398],{"class":3798}," max-age=3600, public\n",[3383,6400,6401,6404,6406],{"class":3385,"line":3411},[3383,6402,6403],{"class":3657},"X-Request-Id",[3383,6405,3795],{"class":3780},[3383,6407,6408],{"class":3798}," a3f8b2c1-d9e2-4f1a-b7c3-8e9d0a1f2b3c\n",[3383,6410,6411,6413,6415],{"class":3385,"line":3417},[3383,6412,3737],{"class":3657},[3383,6414,3795],{"class":3780},[3383,6416,6417],{"class":3798}," Sun, 17 May 2026 09:00:00 GMT\n",[3383,6419,6420],{"class":3385,"line":3423},[3383,6421,3408],{"emptyLinePlaceholder":3407},[3383,6423,6424],{"class":3385,"line":3429},[3383,6425,6426],{"class":3637},"[\n",[3383,6428,6429,6432,6436,6439,6441,6443,6446,6448,6451,6453,6456,6458,6461],{"class":3385,"line":3435},[3383,6430,6431],{"class":3637},"  {",[3383,6433,6435],{"class":6434},"sLwNe","\"id\"",[3383,6437,6438],{"class":3637},": ",[3383,6440,5316],{"class":3786},[3383,6442,3731],{"class":3637},[3383,6444,6445],{"class":6434},"\"name\"",[3383,6447,6438],{"class":3637},[3383,6449,6450],{"class":3798},"\"Alice\"",[3383,6452,3731],{"class":3637},[3383,6454,6455],{"class":6434},"\"email\"",[3383,6457,6438],{"class":3637},[3383,6459,6460],{"class":3798},"\"alice@example.com\"",[3383,6462,6463],{"class":3637},"},\n",[3383,6465,6466,6468,6470,6472,6475,6477,6479,6481,6484,6486,6488,6490,6493],{"class":3385,"line":3441},[3383,6467,6431],{"class":3637},[3383,6469,6435],{"class":6434},[3383,6471,6438],{"class":3637},[3383,6473,6474],{"class":3786},"2",[3383,6476,3731],{"class":3637},[3383,6478,6445],{"class":6434},[3383,6480,6438],{"class":3637},[3383,6482,6483],{"class":3798},"\"Bob\"",[3383,6485,3731],{"class":3637},[3383,6487,6455],{"class":6434},[3383,6489,6438],{"class":3637},[3383,6491,6492],{"class":3798},"\"bob@example.com\"",[3383,6494,4091],{"class":3637},[3383,6496,6497],{"class":3385,"line":3447},[3383,6498,6499],{"class":3637},"]\n",[4655,6501,6502,6520,6545,6563,6577],{},[4658,6503,6505,6506,3731,6509,4775,6512,6515,6516,6519],{"name":6504,"type":4709},"HTTP-Version","Версія протоколу: ",[3380,6507,6508],{},"HTTP\u002F1.0",[3380,6510,6511],{},"HTTP\u002F1.1",[3380,6513,6514],{},"HTTP\u002F2",". У HTTP\u002F2 статусний рядок передається у бінарному форматі через псевдо-заголовок ",[3380,6517,6518],{},":status",", але семантика залишається тією самою.",[4658,6521,6524,6525,6528,6529,6532,6533,6536,6537,6540,6541,6544],{"name":6522,"type":6523},"Status-Code","uint16 (3 цифри)","Тризначний числовий код, що вказує на результат обробки запиту. Перша цифра визначає клас відповіді: ",[3380,6526,6527],{},"1xx"," — інформаційні, ",[3380,6530,6531],{},"2xx"," — успішні, ",[3380,6534,6535],{},"3xx"," — редиректи, ",[3380,6538,6539],{},"4xx"," — помилки клієнта, ",[3380,6542,6543],{},"5xx"," — помилки сервера.",[4658,6546,6548,6549,3731,6552,3731,6555,6558,6559,6562],{"name":6547,"type":4709},"Reason-Phrase","Текстовий опис статус-коду для людини: ",[3380,6550,6551],{},"OK",[3380,6553,6554],{},"Not Found",[3380,6556,6557],{},"Internal Server Error",". У HTTP\u002F2 цей рядок відсутній — лише числовий код. Застосунки ",[3321,6560,6561],{},"не повинні"," покладатись на reason phrase у своїй логіці.",[4658,6564,6567,6568,4744,6570,6573,6574,4760],{"name":6565,"type":6566},"Headers","key: value пари","Метадані повідомлення. Заголовки регістронезалежні (",[3380,6569,3730],{},[3380,6571,6572],{},"content-type","). Один заголовок може мати кілька значень, розділених комою: ",[3380,6575,6576],{},"Accept: text\u002Fhtml, application\u002Fjson",[4658,6578,6581,6582,6584,6585,6587,6588,6591],{"name":6579,"type":6580},"Body","byte[]","Корисне навантаження відповіді. Формат визначається заголовком ",[3380,6583,3730],{},". Розмір — заголовком ",[3380,6586,3734],{}," (або через ",[3380,6589,6590],{},"Transfer-Encoding: chunked"," для потокової передачі невідомого розміру).",[3360,6593],{},[3312,6595,6597],{"id":6596},"http-в-дії-повні-сценарії-запитвідповідь","HTTP в дії: повні сценарії запит–відповідь",[3317,6599,6600],{},"Подивімося, як виглядають реальні HTTP-діалоги між клієнтом і сервером. Саме такий текст передається по TCP-з'єднанню — символ за символом, без жодних абстракцій.",[3370,6602,6603],{},[3373,6604,6606],{"className":3375,"code":6605,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nactor \"Клієнт\\n(браузер \u002F HttpClient)\" as client\nparticipant \"Сервер\" as server #e8f5e9\n\nclient -> server : TCP з'єднання\\n(3-way handshake)\nnote right : SYN → SYN-ACK → ACK\n\nclient -> server : HTTP Request\\n(текст через TCP)\nnote left\n  GET \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\n  Host: api.example.com\n  Accept: application\u002Fjson\n  [порожній рядок]\nend note\n\nserver --> client : HTTP Response\\n(текст через TCP)\nnote right\n  HTTP\u002F1.1 200 OK\n  Content-Type: application\u002Fjson\n  [порожній рядок]\n  {\"id\":1,\"name\":\"Alice\"}\nend note\n\n@enduml\n",[3380,6607,6608,6612,6616,6620,6624,6629,6634,6638,6643,6648,6652,6657,6662,6667,6672,6677,6682,6686,6690,6695,6700,6705,6710,6714,6719,6723,6727],{"__ignoreMap":3378},[3383,6609,6610],{"class":3385,"line":3386},[3383,6611,4064],{},[3383,6613,6614],{"class":3385,"line":3392},[3383,6615,3395],{},[3383,6617,6618],{"class":3385,"line":3398},[3383,6619,3401],{},[3383,6621,6622],{"class":3385,"line":3404},[3383,6623,3408],{"emptyLinePlaceholder":3407},[3383,6625,6626],{"class":3385,"line":3411},[3383,6627,6628],{},"actor \"Клієнт\\n(браузер \u002F HttpClient)\" as client\n",[3383,6630,6631],{"class":3385,"line":3417},[3383,6632,6633],{},"participant \"Сервер\" as server #e8f5e9\n",[3383,6635,6636],{"class":3385,"line":3423},[3383,6637,3408],{"emptyLinePlaceholder":3407},[3383,6639,6640],{"class":3385,"line":3429},[3383,6641,6642],{},"client -> server : TCP з'єднання\\n(3-way handshake)\n",[3383,6644,6645],{"class":3385,"line":3435},[3383,6646,6647],{},"note right : SYN → SYN-ACK → ACK\n",[3383,6649,6650],{"class":3385,"line":3441},[3383,6651,3408],{"emptyLinePlaceholder":3407},[3383,6653,6654],{"class":3385,"line":3447},[3383,6655,6656],{},"client -> server : HTTP Request\\n(текст через TCP)\n",[3383,6658,6659],{"class":3385,"line":3453},[3383,6660,6661],{},"note left\n",[3383,6663,6664],{"class":3385,"line":3459},[3383,6665,6666],{},"  GET \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\n",[3383,6668,6669],{"class":3385,"line":3465},[3383,6670,6671],{},"  Host: api.example.com\n",[3383,6673,6674],{"class":3385,"line":3471},[3383,6675,6676],{},"  Accept: application\u002Fjson\n",[3383,6678,6679],{"class":3385,"line":3477},[3383,6680,6681],{},"  [порожній рядок]\n",[3383,6683,6684],{"class":3385,"line":3483},[3383,6685,4193],{},[3383,6687,6688],{"class":3385,"line":3489},[3383,6689,3408],{"emptyLinePlaceholder":3407},[3383,6691,6692],{"class":3385,"line":3495},[3383,6693,6694],{},"server --> client : HTTP Response\\n(текст через TCP)\n",[3383,6696,6697],{"class":3385,"line":3501},[3383,6698,6699],{},"note right\n",[3383,6701,6702],{"class":3385,"line":3507},[3383,6703,6704],{},"  HTTP\u002F1.1 200 OK\n",[3383,6706,6707],{"class":3385,"line":3513},[3383,6708,6709],{},"  Content-Type: application\u002Fjson\n",[3383,6711,6712],{"class":3385,"line":3519},[3383,6713,6681],{},[3383,6715,6716],{"class":3385,"line":3525},[3383,6717,6718],{},"  {\"id\":1,\"name\":\"Alice\"}\n",[3383,6720,6721],{"class":3385,"line":3531},[3383,6722,4193],{},[3383,6724,6725],{"class":3385,"line":3537},[3383,6726,3408],{"emptyLinePlaceholder":3407},[3383,6728,6729],{"class":3385,"line":3543},[3383,6730,4284],{},[3353,6732,6733,6734,6737,6738,6741],{},"HTTP — це ",[3321,6735,6736],{},"текстовий протокол",". Кожен запит і відповідь — це набір ASCII-рядків, що передаються через TCP. Можна відкрити термінал, підключитися через ",[3380,6739,6740],{},"telnet api.example.com 80"," і вручну надрукувати HTTP-запит — і сервер відповість. Цей факт підкреслює простоту і прозорість протоколу.",[3599,6743,6745],{"id":6744},"сценарій-1-get-отримання-ресурсу","Сценарій 1: GET — отримання ресурсу",[6747,6748,6749,6821,6944],"tabs",{},[6750,6751,6753,6814],"tabs-item",{"label":6752},"Запит",[3373,6754,6756],{"className":3625,"code":6755,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers\u002F42 HTTP\u002F1.1\nHost: api.example.com\nAccept: application\u002Fjson\nAccept-Encoding: gzip, deflate, br\nUser-Agent: dotnet-httpclient\u002F8.0\nConnection: keep-alive\n\n",[3380,6757,6758,6771,6779,6787,6797,6806],{"__ignoreMap":3378},[3383,6759,6760,6762,6765,6767,6769],{"class":3385,"line":3386},[3383,6761,3621],{"class":3634},[3383,6763,6764],{"class":3637}," \u002Fapi\u002Fusers\u002F42 ",[3383,6766,3334],{"class":3780},[3383,6768,3783],{"class":3637},[3383,6770,3907],{"class":3786},[3383,6772,6773,6775,6777],{"class":3385,"line":3392},[3383,6774,3884],{"class":3657},[3383,6776,3795],{"class":3780},[3383,6778,6141],{"class":3798},[3383,6780,6781,6783,6785],{"class":3385,"line":3398},[3383,6782,3792],{"class":3657},[3383,6784,3795],{"class":3780},[3383,6786,6150],{"class":3798},[3383,6788,6789,6792,6794],{"class":3385,"line":3404},[3383,6790,6791],{"class":3657},"Accept-Encoding",[3383,6793,3795],{"class":3780},[3383,6795,6796],{"class":3798}," gzip, deflate, br\n",[3383,6798,6799,6801,6803],{"class":3385,"line":3411},[3383,6800,6175],{"class":3657},[3383,6802,3795],{"class":3780},[3383,6804,6805],{"class":3798}," dotnet-httpclient\u002F8.0\n",[3383,6807,6808,6810,6812],{"class":3385,"line":3417},[3383,6809,3921],{"class":3657},[3383,6811,3795],{"class":3780},[3383,6813,3926],{"class":3798},[3317,6815,6816,6817,6820],{},"Зверніть увагу на ",[3321,6818,6819],{},"порожній рядок"," наприкінці — він обов'язковий. Саме він сигналізує серверу, що всі заголовки передано.",[6750,6822,6824],{"label":6823},"200 OK",[3373,6825,6827],{"className":3625,"code":6826,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson; charset=utf-8\nContent-Length: 112\nCache-Control: max-age=60, public\nETag: \"a3f8b2c1\"\nDate: Thu, 22 May 2026 10:00:00 GMT\n\n{\n  \"id\": 42,\n  \"name\": \"Олег Коваленко\",\n  \"email\": \"oleg@example.com\",\n  \"role\": \"developer\"\n}\n",[3380,6828,6829,6841,6849,6858,6867,6877,6886,6890,6894,6906,6918,6930,6940],{"__ignoreMap":3378},[3383,6830,6831,6833,6835,6837,6839],{"class":3385,"line":3386},[3383,6832,3334],{"class":3780},[3383,6834,3783],{"class":3637},[3383,6836,3946],{"class":3786},[3383,6838,3816],{"class":3786},[3383,6840,3819],{"class":3798},[3383,6842,6843,6845,6847],{"class":3385,"line":3392},[3383,6844,3730],{"class":3657},[3383,6846,3795],{"class":3780},[3383,6848,6379],{"class":3798},[3383,6850,6851,6853,6855],{"class":3385,"line":3398},[3383,6852,3734],{"class":3657},[3383,6854,3795],{"class":3780},[3383,6856,6857],{"class":3798}," 112\n",[3383,6859,6860,6862,6864],{"class":3385,"line":3404},[3383,6861,6393],{"class":3657},[3383,6863,3795],{"class":3780},[3383,6865,6866],{"class":3798}," max-age=60, public\n",[3383,6868,6869,6872,6874],{"class":3385,"line":3411},[3383,6870,6871],{"class":3657},"ETag",[3383,6873,3795],{"class":3780},[3383,6875,6876],{"class":3798}," \"a3f8b2c1\"\n",[3383,6878,6879,6881,6883],{"class":3385,"line":3417},[3383,6880,3737],{"class":3657},[3383,6882,3795],{"class":3780},[3383,6884,6885],{"class":3798}," Thu, 22 May 2026 10:00:00 GMT\n",[3383,6887,6888],{"class":3385,"line":3423},[3383,6889,3408],{"emptyLinePlaceholder":3407},[3383,6891,6892],{"class":3385,"line":3429},[3383,6893,5292],{"class":3637},[3383,6895,6896,6899,6901,6904],{"class":3385,"line":3435},[3383,6897,6898],{"class":6434},"  \"id\"",[3383,6900,6438],{"class":3637},[3383,6902,6903],{"class":3786},"42",[3383,6905,5305],{"class":3637},[3383,6907,6908,6911,6913,6916],{"class":3385,"line":3441},[3383,6909,6910],{"class":6434},"  \"name\"",[3383,6912,6438],{"class":3637},[3383,6914,6915],{"class":3798},"\"Олег Коваленко\"",[3383,6917,5305],{"class":3637},[3383,6919,6920,6923,6925,6928],{"class":3385,"line":3447},[3383,6921,6922],{"class":6434},"  \"email\"",[3383,6924,6438],{"class":3637},[3383,6926,6927],{"class":3798},"\"oleg@example.com\"",[3383,6929,5305],{"class":3637},[3383,6931,6932,6935,6937],{"class":3385,"line":3453},[3383,6933,6934],{"class":6434},"  \"role\"",[3383,6936,6438],{"class":3637},[3383,6938,6939],{"class":3798},"\"developer\"\n",[3383,6941,6942],{"class":3385,"line":3459},[3383,6943,4091],{"class":3637},[6750,6945,6947,6957,6990,7034],{"label":6946},"304 Not Modified (кеш)",[3317,6948,6949,6950,6953,6954,3795],{},"Якщо клієнт додає ",[3380,6951,6952],{},"If-None-Match"," і ресурс не змінився — сервер відповідає ",[3321,6955,6956],{},"без тіла",[3373,6958,6960],{"className":3625,"code":6959,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers\u002F42 HTTP\u002F1.1\nHost: api.example.com\nIf-None-Match: \"a3f8b2c1\"\n\n",[3380,6961,6962,6974,6982],{"__ignoreMap":3378},[3383,6963,6964,6966,6968,6970,6972],{"class":3385,"line":3386},[3383,6965,3621],{"class":3634},[3383,6967,6764],{"class":3637},[3383,6969,3334],{"class":3780},[3383,6971,3783],{"class":3637},[3383,6973,3907],{"class":3786},[3383,6975,6976,6978,6980],{"class":3385,"line":3392},[3383,6977,3884],{"class":3657},[3383,6979,3795],{"class":3780},[3383,6981,6141],{"class":3798},[3383,6983,6984,6986,6988],{"class":3385,"line":3398},[3383,6985,6952],{"class":3657},[3383,6987,3795],{"class":3780},[3383,6989,6876],{"class":3798},[3373,6991,6993],{"className":3625,"code":6992,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 304 Not Modified\nETag: \"a3f8b2c1\"\nCache-Control: max-age=60, public\nDate: Thu, 22 May 2026 10:05:00 GMT\n",[3380,6994,6995,7009,7017,7025],{"__ignoreMap":3378},[3383,6996,6997,6999,7001,7003,7006],{"class":3385,"line":3386},[3383,6998,3334],{"class":3780},[3383,7000,3783],{"class":3637},[3383,7002,3946],{"class":3786},[3383,7004,7005],{"class":3786}," 304",[3383,7007,7008],{"class":3798}," Not Modified\n",[3383,7010,7011,7013,7015],{"class":3385,"line":3392},[3383,7012,6871],{"class":3657},[3383,7014,3795],{"class":3780},[3383,7016,6876],{"class":3798},[3383,7018,7019,7021,7023],{"class":3385,"line":3398},[3383,7020,6393],{"class":3657},[3383,7022,3795],{"class":3780},[3383,7024,6866],{"class":3798},[3383,7026,7027,7029,7031],{"class":3385,"line":3404},[3383,7028,3737],{"class":3657},[3383,7030,3795],{"class":3780},[3383,7032,7033],{"class":3798}," Thu, 22 May 2026 10:05:00 GMT\n",[3317,7035,7036],{},"Тіло відсутнє — клієнт використовує кешовану версію. Трафік зекономлено.",[3599,7038,7040],{"id":7039},"сценарій-2-post-створення-ресурсу","Сценарій 2: POST — створення ресурсу",[6747,7042,7043,7148,7278],{},[6750,7044,7045,7139],{"label":6752},[3373,7046,7048],{"className":3625,"code":7047,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\nContent-Length: 100\nAccept: application\u002Fjson\n\n{\n  \"name\": \"Марія Шевченко\",\n  \"email\": \"maria@example.com\",\n  \"role\": \"designer\"\n}\n",[3380,7049,7050,7063,7071,7079,7088,7096,7100,7104,7115,7126,7135],{"__ignoreMap":3378},[3383,7051,7052,7054,7057,7059,7061],{"class":3385,"line":3386},[3383,7053,3746],{"class":3634},[3383,7055,7056],{"class":3637}," \u002Fapi\u002Fusers ",[3383,7058,3334],{"class":3780},[3383,7060,3783],{"class":3637},[3383,7062,3907],{"class":3786},[3383,7064,7065,7067,7069],{"class":3385,"line":3392},[3383,7066,3884],{"class":3657},[3383,7068,3795],{"class":3780},[3383,7070,6141],{"class":3798},[3383,7072,7073,7075,7077],{"class":3385,"line":3398},[3383,7074,3730],{"class":3657},[3383,7076,3795],{"class":3780},[3383,7078,6150],{"class":3798},[3383,7080,7081,7083,7085],{"class":3385,"line":3404},[3383,7082,3734],{"class":3657},[3383,7084,3795],{"class":3780},[3383,7086,7087],{"class":3798}," 100\n",[3383,7089,7090,7092,7094],{"class":3385,"line":3411},[3383,7091,3792],{"class":3657},[3383,7093,3795],{"class":3780},[3383,7095,6150],{"class":3798},[3383,7097,7098],{"class":3385,"line":3417},[3383,7099,3408],{"emptyLinePlaceholder":3407},[3383,7101,7102],{"class":3385,"line":3423},[3383,7103,5292],{"class":3637},[3383,7105,7106,7108,7110,7113],{"class":3385,"line":3429},[3383,7107,6910],{"class":6434},[3383,7109,6438],{"class":3637},[3383,7111,7112],{"class":3798},"\"Марія Шевченко\"",[3383,7114,5305],{"class":3637},[3383,7116,7117,7119,7121,7124],{"class":3385,"line":3435},[3383,7118,6922],{"class":6434},[3383,7120,6438],{"class":3637},[3383,7122,7123],{"class":3798},"\"maria@example.com\"",[3383,7125,5305],{"class":3637},[3383,7127,7128,7130,7132],{"class":3385,"line":3441},[3383,7129,6934],{"class":6434},[3383,7131,6438],{"class":3637},[3383,7133,7134],{"class":3798},"\"designer\"\n",[3383,7136,7137],{"class":3385,"line":3447},[3383,7138,4091],{"class":3637},[3317,7140,7141,7142,4889,7145,7147],{},"Тіло йде після ",[3321,7143,7144],{},"порожнього рядка",[3380,7146,3734],{}," вказує серверу, скільки байтів читати.",[6750,7149,7151,7270],{"label":7150},"201 Created",[3373,7152,7154],{"className":3625,"code":7153,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 201 Created\nContent-Type: application\u002Fjson; charset=utf-8\nContent-Length: 138\nLocation: \u002Fapi\u002Fusers\u002F43\nDate: Thu, 22 May 2026 10:01:00 GMT\n\n{\n  \"id\": 43,\n  \"name\": \"Марія Шевченко\",\n  \"email\": \"maria@example.com\",\n  \"role\": \"designer\",\n  \"created_at\": \"2026-05-22T10:01:00Z\"\n}\n",[3380,7155,7156,7170,7178,7187,7197,7206,7210,7214,7225,7235,7245,7256,7266],{"__ignoreMap":3378},[3383,7157,7158,7160,7162,7164,7167],{"class":3385,"line":3386},[3383,7159,3334],{"class":3780},[3383,7161,3783],{"class":3637},[3383,7163,3946],{"class":3786},[3383,7165,7166],{"class":3786}," 201",[3383,7168,7169],{"class":3798}," Created\n",[3383,7171,7172,7174,7176],{"class":3385,"line":3392},[3383,7173,3730],{"class":3657},[3383,7175,3795],{"class":3780},[3383,7177,6379],{"class":3798},[3383,7179,7180,7182,7184],{"class":3385,"line":3398},[3383,7181,3734],{"class":3657},[3383,7183,3795],{"class":3780},[3383,7185,7186],{"class":3798}," 138\n",[3383,7188,7189,7192,7194],{"class":3385,"line":3404},[3383,7190,7191],{"class":3657},"Location",[3383,7193,3795],{"class":3780},[3383,7195,7196],{"class":3798}," \u002Fapi\u002Fusers\u002F43\n",[3383,7198,7199,7201,7203],{"class":3385,"line":3411},[3383,7200,3737],{"class":3657},[3383,7202,3795],{"class":3780},[3383,7204,7205],{"class":3798}," Thu, 22 May 2026 10:01:00 GMT\n",[3383,7207,7208],{"class":3385,"line":3417},[3383,7209,3408],{"emptyLinePlaceholder":3407},[3383,7211,7212],{"class":3385,"line":3423},[3383,7213,5292],{"class":3637},[3383,7215,7216,7218,7220,7223],{"class":3385,"line":3429},[3383,7217,6898],{"class":6434},[3383,7219,6438],{"class":3637},[3383,7221,7222],{"class":3786},"43",[3383,7224,5305],{"class":3637},[3383,7226,7227,7229,7231,7233],{"class":3385,"line":3435},[3383,7228,6910],{"class":6434},[3383,7230,6438],{"class":3637},[3383,7232,7112],{"class":3798},[3383,7234,5305],{"class":3637},[3383,7236,7237,7239,7241,7243],{"class":3385,"line":3441},[3383,7238,6922],{"class":6434},[3383,7240,6438],{"class":3637},[3383,7242,7123],{"class":3798},[3383,7244,5305],{"class":3637},[3383,7246,7247,7249,7251,7254],{"class":3385,"line":3447},[3383,7248,6934],{"class":6434},[3383,7250,6438],{"class":3637},[3383,7252,7253],{"class":3798},"\"designer\"",[3383,7255,5305],{"class":3637},[3383,7257,7258,7261,7263],{"class":3385,"line":3453},[3383,7259,7260],{"class":6434},"  \"created_at\"",[3383,7262,6438],{"class":3637},[3383,7264,7265],{"class":3798},"\"2026-05-22T10:01:00Z\"\n",[3383,7267,7268],{"class":3385,"line":3459},[3383,7269,4091],{"class":3637},[3317,7271,7272,7275,7276,4760],{},[3380,7273,7274],{},"Location: \u002Fapi\u002Fusers\u002F43"," — URL нового ресурсу, обов'язковий при ",[3380,7277,7150],{},[6750,7279,7281,7346],{"label":7280},"422 Validation Error",[3373,7282,7284],{"className":3625,"code":7283,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\n  \"name\": \"\",\n  \"email\": \"not-an-email\"\n}\n",[3380,7285,7286,7298,7306,7314,7318,7322,7333,7342],{"__ignoreMap":3378},[3383,7287,7288,7290,7292,7294,7296],{"class":3385,"line":3386},[3383,7289,3746],{"class":3634},[3383,7291,7056],{"class":3637},[3383,7293,3334],{"class":3780},[3383,7295,3783],{"class":3637},[3383,7297,3907],{"class":3786},[3383,7299,7300,7302,7304],{"class":3385,"line":3392},[3383,7301,3884],{"class":3657},[3383,7303,3795],{"class":3780},[3383,7305,6141],{"class":3798},[3383,7307,7308,7310,7312],{"class":3385,"line":3398},[3383,7309,3730],{"class":3657},[3383,7311,3795],{"class":3780},[3383,7313,6150],{"class":3798},[3383,7315,7316],{"class":3385,"line":3404},[3383,7317,3408],{"emptyLinePlaceholder":3407},[3383,7319,7320],{"class":3385,"line":3411},[3383,7321,5292],{"class":3637},[3383,7323,7324,7326,7328,7331],{"class":3385,"line":3417},[3383,7325,6910],{"class":6434},[3383,7327,6438],{"class":3637},[3383,7329,7330],{"class":3798},"\"\"",[3383,7332,5305],{"class":3637},[3383,7334,7335,7337,7339],{"class":3385,"line":3423},[3383,7336,6922],{"class":6434},[3383,7338,6438],{"class":3637},[3383,7340,7341],{"class":3798},"\"not-an-email\"\n",[3383,7343,7344],{"class":3385,"line":3429},[3383,7345,4091],{"class":3637},[3373,7347,7349],{"className":3625,"code":7348,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 422 Unprocessable Entity\nContent-Type: application\u002Fproblem+json\n\n{\n  \"status\": 422,\n  \"title\": \"Validation Error\",\n  \"errors\": {\n    \"name\": [\"Не може бути порожнім\"],\n    \"email\": [\"Невалідний формат email\"]\n  }\n}\n",[3380,7350,7351,7365,7374,7378,7382,7394,7406,7414,7428,7440,7445],{"__ignoreMap":3378},[3383,7352,7353,7355,7357,7359,7362],{"class":3385,"line":3386},[3383,7354,3334],{"class":3780},[3383,7356,3783],{"class":3637},[3383,7358,3946],{"class":3786},[3383,7360,7361],{"class":3786}," 422",[3383,7363,7364],{"class":3798}," Unprocessable Entity\n",[3383,7366,7367,7369,7371],{"class":3385,"line":3392},[3383,7368,3730],{"class":3657},[3383,7370,3795],{"class":3780},[3383,7372,7373],{"class":3798}," application\u002Fproblem+json\n",[3383,7375,7376],{"class":3385,"line":3398},[3383,7377,3408],{"emptyLinePlaceholder":3407},[3383,7379,7380],{"class":3385,"line":3404},[3383,7381,5292],{"class":3637},[3383,7383,7384,7387,7389,7392],{"class":3385,"line":3411},[3383,7385,7386],{"class":6434},"  \"status\"",[3383,7388,6438],{"class":3637},[3383,7390,7391],{"class":3786},"422",[3383,7393,5305],{"class":3637},[3383,7395,7396,7399,7401,7404],{"class":3385,"line":3417},[3383,7397,7398],{"class":6434},"  \"title\"",[3383,7400,6438],{"class":3637},[3383,7402,7403],{"class":3798},"\"Validation Error\"",[3383,7405,5305],{"class":3637},[3383,7407,7408,7411],{"class":3385,"line":3423},[3383,7409,7410],{"class":6434},"  \"errors\"",[3383,7412,7413],{"class":3637},": {\n",[3383,7415,7416,7419,7422,7425],{"class":3385,"line":3429},[3383,7417,7418],{"class":6434},"    \"name\"",[3383,7420,7421],{"class":3637},": [",[3383,7423,7424],{"class":3798},"\"Не може бути порожнім\"",[3383,7426,7427],{"class":3637},"],\n",[3383,7429,7430,7433,7435,7438],{"class":3385,"line":3435},[3383,7431,7432],{"class":6434},"    \"email\"",[3383,7434,7421],{"class":3637},[3383,7436,7437],{"class":3798},"\"Невалідний формат email\"",[3383,7439,6499],{"class":3637},[3383,7441,7442],{"class":3385,"line":3441},[3383,7443,7444],{"class":3637},"  }\n",[3383,7446,7447],{"class":3385,"line":3447},[3383,7448,4091],{"class":3637},[3599,7450,7452],{"id":7451},"сценарій-3-delete-та-ідемпотентність","Сценарій 3: DELETE та ідемпотентність",[6747,7454,7455,7519],{},[6750,7456,7458,7485,7513],{"label":7457},"Перший DELETE",[3373,7459,7461],{"className":3625,"code":7460,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fusers\u002F43 HTTP\u002F1.1\nHost: api.example.com\n\n",[3380,7462,7463,7477],{"__ignoreMap":3378},[3383,7464,7465,7468,7471,7473,7475],{"class":3385,"line":3386},[3383,7466,7467],{"class":3634},"DELETE",[3383,7469,7470],{"class":3637}," \u002Fapi\u002Fusers\u002F43 ",[3383,7472,3334],{"class":3780},[3383,7474,3783],{"class":3637},[3383,7476,3907],{"class":3786},[3383,7478,7479,7481,7483],{"class":3385,"line":3392},[3383,7480,3884],{"class":3657},[3383,7482,3795],{"class":3780},[3383,7484,6141],{"class":3798},[3373,7486,7488],{"className":3625,"code":7487,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 204 No Content\nDate: Thu, 22 May 2026 10:02:00 GMT\n",[3380,7489,7490,7504],{"__ignoreMap":3378},[3383,7491,7492,7494,7496,7498,7501],{"class":3385,"line":3386},[3383,7493,3334],{"class":3780},[3383,7495,3783],{"class":3637},[3383,7497,3946],{"class":3786},[3383,7499,7500],{"class":3786}," 204",[3383,7502,7503],{"class":3798}," No Content\n",[3383,7505,7506,7508,7510],{"class":3385,"line":3392},[3383,7507,3737],{"class":3657},[3383,7509,3795],{"class":3780},[3383,7511,7512],{"class":3798}," Thu, 22 May 2026 10:02:00 GMT\n",[3317,7514,7515,7518],{},[3380,7516,7517],{},"204 No Content"," — успіх без тіла. Ресурс видалено.",[6750,7520,7522,7546,7617],{"label":7521},"Повторний DELETE",[3373,7523,7524],{"className":3625,"code":7460,"language":3627,"meta":3378,"style":3378},[3380,7525,7526,7538],{"__ignoreMap":3378},[3383,7527,7528,7530,7532,7534,7536],{"class":3385,"line":3386},[3383,7529,7467],{"class":3634},[3383,7531,7470],{"class":3637},[3383,7533,3334],{"class":3780},[3383,7535,3783],{"class":3637},[3383,7537,3907],{"class":3786},[3383,7539,7540,7542,7544],{"class":3385,"line":3392},[3383,7541,3884],{"class":3657},[3383,7543,3795],{"class":3780},[3383,7545,6141],{"class":3798},[3373,7547,7549],{"className":3625,"code":7548,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 404 Not Found\nContent-Type: application\u002Fproblem+json\n\n{\n  \"status\": 404,\n  \"title\": \"Not Found\",\n  \"detail\": \"Користувача з ID 43 не існує\"\n}\n",[3380,7550,7551,7565,7573,7577,7581,7592,7603,7613],{"__ignoreMap":3378},[3383,7552,7553,7555,7557,7559,7562],{"class":3385,"line":3386},[3383,7554,3334],{"class":3780},[3383,7556,3783],{"class":3637},[3383,7558,3946],{"class":3786},[3383,7560,7561],{"class":3786}," 404",[3383,7563,7564],{"class":3798}," Not Found\n",[3383,7566,7567,7569,7571],{"class":3385,"line":3392},[3383,7568,3730],{"class":3657},[3383,7570,3795],{"class":3780},[3383,7572,7373],{"class":3798},[3383,7574,7575],{"class":3385,"line":3398},[3383,7576,3408],{"emptyLinePlaceholder":3407},[3383,7578,7579],{"class":3385,"line":3404},[3383,7580,5292],{"class":3637},[3383,7582,7583,7585,7587,7590],{"class":3385,"line":3411},[3383,7584,7386],{"class":6434},[3383,7586,6438],{"class":3637},[3383,7588,7589],{"class":3786},"404",[3383,7591,5305],{"class":3637},[3383,7593,7594,7596,7598,7601],{"class":3385,"line":3417},[3383,7595,7398],{"class":6434},[3383,7597,6438],{"class":3637},[3383,7599,7600],{"class":3798},"\"Not Found\"",[3383,7602,5305],{"class":3637},[3383,7604,7605,7608,7610],{"class":3385,"line":3423},[3383,7606,7607],{"class":6434},"  \"detail\"",[3383,7609,6438],{"class":3637},[3383,7611,7612],{"class":3798},"\"Користувача з ID 43 не існує\"\n",[3383,7614,7615],{"class":3385,"line":3429},[3383,7616,4091],{"class":3637},[3317,7618,7619,7620,7622,7623,7626],{},"Ресурс вже видалено → ",[3380,7621,7589],{},". Стан системи не змінився — це і є ",[3321,7624,7625],{},"ідемпотентність"," DELETE.",[3599,7628,7630],{"id":7629},"сценарій-4-редирект-http-https","Сценарій 4: Редирект HTTP → HTTPS",[6747,7632,7633,7703],{},[6750,7634,7636,7663,7700],{"label":7635},"Незахищений запит → редирект",[3373,7637,7639],{"className":3625,"code":7638,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fdata HTTP\u002F1.1\nHost: example.com\n\n",[3380,7640,7641,7654],{"__ignoreMap":3378},[3383,7642,7643,7645,7648,7650,7652],{"class":3385,"line":3386},[3383,7644,3621],{"class":3634},[3383,7646,7647],{"class":3637}," \u002Fapi\u002Fdata ",[3383,7649,3334],{"class":3780},[3383,7651,3783],{"class":3637},[3383,7653,3907],{"class":3786},[3383,7655,7656,7658,7660],{"class":3385,"line":3392},[3383,7657,3884],{"class":3657},[3383,7659,3795],{"class":3780},[3383,7661,7662],{"class":3798}," example.com\n",[3373,7664,7666],{"className":3625,"code":7665,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 301 Moved Permanently\nLocation: https:\u002F\u002Fexample.com\u002Fapi\u002Fdata\nContent-Length: 0\n",[3380,7667,7668,7682,7691],{"__ignoreMap":3378},[3383,7669,7670,7672,7674,7676,7679],{"class":3385,"line":3386},[3383,7671,3334],{"class":3780},[3383,7673,3783],{"class":3637},[3383,7675,3946],{"class":3786},[3383,7677,7678],{"class":3786}," 301",[3383,7680,7681],{"class":3798}," Moved Permanently\n",[3383,7683,7684,7686,7688],{"class":3385,"line":3392},[3383,7685,7191],{"class":3657},[3383,7687,3795],{"class":3780},[3383,7689,7690],{"class":3798}," https:\u002F\u002Fexample.com\u002Fapi\u002Fdata\n",[3383,7692,7693,7695,7697],{"class":3385,"line":3398},[3383,7694,3734],{"class":3657},[3383,7696,3795],{"class":3780},[3383,7698,7699],{"class":3798}," 0\n",[3317,7701,7702],{},"Сервер не обробляє запит — одразу перенаправляє на HTTPS.",[6750,7704,7706,7739,7793,7798],{"label":7705},"Повторний запит через HTTPS",[3373,7707,7709],{"className":3625,"code":7708,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fdata HTTP\u002F1.1\nHost: example.com\nConnection: keep-alive\n\n",[3380,7710,7711,7723,7731],{"__ignoreMap":3378},[3383,7712,7713,7715,7717,7719,7721],{"class":3385,"line":3386},[3383,7714,3621],{"class":3634},[3383,7716,7647],{"class":3637},[3383,7718,3334],{"class":3780},[3383,7720,3783],{"class":3637},[3383,7722,3907],{"class":3786},[3383,7724,7725,7727,7729],{"class":3385,"line":3392},[3383,7726,3884],{"class":3657},[3383,7728,3795],{"class":3780},[3383,7730,7662],{"class":3798},[3383,7732,7733,7735,7737],{"class":3385,"line":3398},[3383,7734,3921],{"class":3657},[3383,7736,3795],{"class":3780},[3383,7738,3926],{"class":3798},[3373,7740,7742],{"className":3625,"code":7741,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\nStrict-Transport-Security: max-age=31536000; includeSubDomains\n\n{\"data\": [...]}\n",[3380,7743,7744,7756,7764,7774,7778],{"__ignoreMap":3378},[3383,7745,7746,7748,7750,7752,7754],{"class":3385,"line":3386},[3383,7747,3334],{"class":3780},[3383,7749,3783],{"class":3637},[3383,7751,3946],{"class":3786},[3383,7753,3816],{"class":3786},[3383,7755,3819],{"class":3798},[3383,7757,7758,7760,7762],{"class":3385,"line":3392},[3383,7759,3730],{"class":3657},[3383,7761,3795],{"class":3780},[3383,7763,6150],{"class":3798},[3383,7765,7766,7769,7771],{"class":3385,"line":3398},[3383,7767,7768],{"class":3657},"Strict-Transport-Security",[3383,7770,3795],{"class":3780},[3383,7772,7773],{"class":3798}," max-age=31536000; includeSubDomains\n",[3383,7775,7776],{"class":3385,"line":3404},[3383,7777,3408],{"emptyLinePlaceholder":3407},[3383,7779,7780,7782,7785,7787,7790],{"class":3385,"line":3411},[3383,7781,5466],{"class":3637},[3383,7783,7784],{"class":6434},"\"data\"",[3383,7786,7421],{"class":3637},[3383,7788,3851],{"class":7789},"se1LK",[3383,7791,7792],{"class":3637},"]}\n",[3317,7794,7795,7797],{},[3380,7796,7768],{}," гарантує, що всі майбутні запити одразу підуть через HTTPS.",[3317,7799,7800,7801,7803,7804,7807,7808,7811],{},"На рівні HTTP\u002F1.1 текст запиту виглядає так само, як звичайний HTTP — ",[3380,7802,4676],{}," у рядку запиту відсутній. Різниця на транспортному рівні: TCP-з'єднання встановлено через ",[3321,7805,7806],{},"TLS"," на порту ",[3321,7809,7810],{},"443",", і весь текст передається у зашифрованому вигляді.",[3599,7813,7815],{"id":7814},"мінімальний-vs-реальний-запит","Мінімальний vs. реальний запит",[3317,7817,7818,7819,7822],{},"Браузери автоматично додають десятки заголовків. ",[3380,7820,7821],{},"HttpClient"," у .NET — лише необхідний мінімум:",[7824,7825,7826,7867],"card-group",{},[7827,7828,7831,7864],"card",{"icon":7829,"title":7830},"i-lucide-terminal","Мінімальний (HttpClient)",[3373,7832,7834],{"className":3625,"code":7833,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nAccept: application\u002Fjson\n\n",[3380,7835,7836,7848,7856],{"__ignoreMap":3378},[3383,7837,7838,7840,7842,7844,7846],{"class":3385,"line":3386},[3383,7839,3621],{"class":3634},[3383,7841,7056],{"class":3637},[3383,7843,3334],{"class":3780},[3383,7845,3783],{"class":3637},[3383,7847,3907],{"class":3786},[3383,7849,7850,7852,7854],{"class":3385,"line":3392},[3383,7851,3884],{"class":3657},[3383,7853,3795],{"class":3780},[3383,7855,6141],{"class":3798},[3383,7857,7858,7860,7862],{"class":3385,"line":3398},[3383,7859,3792],{"class":3657},[3383,7861,3795],{"class":3780},[3383,7863,6150],{"class":3798},[3317,7865,7866],{},"Лише те, що потрібно серверу для обробки.",[7827,7868,7870,7979],{"icon":1930,"title":7869},"Реальний (браузер Chrome)",[3373,7871,7873],{"className":3625,"code":7872,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nAccept: text\u002Fhtml,application\u002Fxhtml+xml,*\u002F*;q=0.8\nAccept-Language: uk-UA,uk;q=0.9,en;q=0.8\nAccept-Encoding: gzip, deflate, br, zstd\nConnection: keep-alive\nUser-Agent: Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) Chrome\u002F124.0\nSec-Fetch-Dest: empty\nSec-Fetch-Mode: cors\nSec-Fetch-Site: same-origin\nDNT: 1\n\n",[3380,7874,7875,7887,7895,7904,7913,7922,7930,7939,7949,7959,7969],{"__ignoreMap":3378},[3383,7876,7877,7879,7881,7883,7885],{"class":3385,"line":3386},[3383,7878,3621],{"class":3634},[3383,7880,7056],{"class":3637},[3383,7882,3334],{"class":3780},[3383,7884,3783],{"class":3637},[3383,7886,3907],{"class":3786},[3383,7888,7889,7891,7893],{"class":3385,"line":3392},[3383,7890,3884],{"class":3657},[3383,7892,3795],{"class":3780},[3383,7894,6141],{"class":3798},[3383,7896,7897,7899,7901],{"class":3385,"line":3398},[3383,7898,3792],{"class":3657},[3383,7900,3795],{"class":3780},[3383,7902,7903],{"class":3798}," text\u002Fhtml,application\u002Fxhtml+xml,*\u002F*;q=0.8\n",[3383,7905,7906,7908,7910],{"class":3385,"line":3404},[3383,7907,6155],{"class":3657},[3383,7909,3795],{"class":3780},[3383,7911,7912],{"class":3798}," uk-UA,uk;q=0.9,en;q=0.8\n",[3383,7914,7915,7917,7919],{"class":3385,"line":3411},[3383,7916,6791],{"class":3657},[3383,7918,3795],{"class":3780},[3383,7920,7921],{"class":3798}," gzip, deflate, br, zstd\n",[3383,7923,7924,7926,7928],{"class":3385,"line":3417},[3383,7925,3921],{"class":3657},[3383,7927,3795],{"class":3780},[3383,7929,3926],{"class":3798},[3383,7931,7932,7934,7936],{"class":3385,"line":3423},[3383,7933,6175],{"class":3657},[3383,7935,3795],{"class":3780},[3383,7937,7938],{"class":3798}," Mozilla\u002F5.0 (Windows NT 10.0; Win64; x64) Chrome\u002F124.0\n",[3383,7940,7941,7944,7946],{"class":3385,"line":3429},[3383,7942,7943],{"class":3657},"Sec-Fetch-Dest",[3383,7945,3795],{"class":3780},[3383,7947,7948],{"class":3798}," empty\n",[3383,7950,7951,7954,7956],{"class":3385,"line":3435},[3383,7952,7953],{"class":3657},"Sec-Fetch-Mode",[3383,7955,3795],{"class":3780},[3383,7957,7958],{"class":3798}," cors\n",[3383,7960,7961,7964,7966],{"class":3385,"line":3441},[3383,7962,7963],{"class":3657},"Sec-Fetch-Site",[3383,7965,3795],{"class":3780},[3383,7967,7968],{"class":3798}," same-origin\n",[3383,7970,7971,7974,7976],{"class":3385,"line":3447},[3383,7972,7973],{"class":3657},"DNT",[3383,7975,3795],{"class":3780},[3383,7977,7978],{"class":3798}," 1\n",[3317,7980,7981],{},"Браузер додає узгодження формату, мови, кодування та заголовки безпеки.",[3360,7983],{},[3312,7985,7987],{"id":7986},"http-методи-повний-академічний-розбір","HTTP-методи: повний академічний розбір",[3317,7989,7990,7991,7994],{},"HTTP-метод визначає ",[3321,7992,7993],{},"намір"," клієнта — що саме він хоче зробити з ресурсом. RFC 7231 визначає вісім стандартних методів, кожен з яких має чітку семантику та важливі властивості.",[3599,7996,7998],{"id":7997},"класифікація-методів","Класифікація методів",[3317,8000,8001],{},"Два критично важливих поняття для розуміння методів:",[7824,8003,8004,8029],{},[7827,8005,8008,8022],{"icon":8006,"title":8007},"i-lucide-repeat","Ідемпотентність (Idempotency)",[3317,8009,8010,8011,8014,8015,8018,8019,4760],{},"Метод є ",[3321,8012,8013],{},"ідемпотентним",", якщо повторне виконання ",[3321,8016,8017],{},"ідентичного"," запиту дає той самий ефект, що і одноразове виконання. Тобто: ",[3380,8020,8021],{},"f(f(x)) = f(x)",[3317,8023,8024,8025,8028],{},"Практичне значення: при мережевому збої клієнт може безпечно ",[3321,8026,8027],{},"повторити"," ідемпотентний запит, не боячись подвійного ефекту.",[7827,8030,8033,8043],{"icon":8031,"title":8032},"i-lucide-shield","Безпечність (Safety)",[3317,8034,8010,8035,8038,8039,8042],{},[3321,8036,8037],{},"безпечним",", якщо він ",[3321,8040,8041],{},"не змінює"," стан сервера (read-only операція). Безпечні методи можна кешувати, і вони не мають побічних ефектів.",[3317,8044,8045,8046,8048],{},"Важливо: всі безпечні методи є ідемпотентними, але не навпаки. ",[3380,8047,7467],{}," — ідемпотентний, але не безпечний.",[3370,8050,8051],{},[3373,8052,8054],{"className":3375,"code":8053,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nclass \"GET\" as GET #a5d6a7 {\n    + safe: true\n    + idempotent: true\n    + body: не рекомендується\n    ---\n    Отримати ресурс\n}\n\nclass \"POST\" as POST #ef9a9a {\n    + safe: false\n    + idempotent: false\n    + body: обов'язково\n    ---\n    Створити ресурс або дія\n}\n\nclass \"PUT\" as PUT #ffe082 {\n    + safe: false\n    + idempotent: true\n    + body: обов'язково\n    ---\n    Замінити ресурс повністю\n}\n\nclass \"PATCH\" as PATCH #ffcc80 {\n    + safe: false\n    + idempotent: false*\n    + body: обов'язково\n    ---\n    Частково змінити ресурс\n}\n\nclass \"DELETE\" as DELETE #f48fb1 {\n    + safe: false\n    + idempotent: true\n    + body: ігнорується\n    ---\n    Видалити ресурс\n}\n\nclass \"HEAD\" as HEAD #b3e5fc {\n    + safe: true\n    + idempotent: true\n    + body: відсутнє\n    ---\n    GET без тіла відповіді\n}\n\nclass \"OPTIONS\" as OPTIONS #e1bee7 {\n    + safe: true\n    + idempotent: true\n    ---\n    Дізнатись можливості\n}\n\n@enduml\n",[3380,8055,8056,8060,8064,8068,8072,8077,8082,8087,8092,8097,8102,8106,8110,8115,8120,8125,8130,8134,8139,8143,8147,8152,8156,8160,8164,8168,8173,8177,8181,8186,8190,8195,8199,8203,8208,8212,8216,8221,8225,8229,8234,8238,8243,8247,8251,8256,8260,8264,8269,8273,8278,8282,8286,8291,8295,8299,8303,8308,8312,8316],{"__ignoreMap":3378},[3383,8057,8058],{"class":3385,"line":3386},[3383,8059,4064],{},[3383,8061,8062],{"class":3385,"line":3392},[3383,8063,3395],{},[3383,8065,8066],{"class":3385,"line":3398},[3383,8067,3401],{},[3383,8069,8070],{"class":3385,"line":3404},[3383,8071,3408],{"emptyLinePlaceholder":3407},[3383,8073,8074],{"class":3385,"line":3411},[3383,8075,8076],{},"class \"GET\" as GET #a5d6a7 {\n",[3383,8078,8079],{"class":3385,"line":3417},[3383,8080,8081],{},"    + safe: true\n",[3383,8083,8084],{"class":3385,"line":3423},[3383,8085,8086],{},"    + idempotent: true\n",[3383,8088,8089],{"class":3385,"line":3429},[3383,8090,8091],{},"    + body: не рекомендується\n",[3383,8093,8094],{"class":3385,"line":3435},[3383,8095,8096],{},"    ---\n",[3383,8098,8099],{"class":3385,"line":3441},[3383,8100,8101],{},"    Отримати ресурс\n",[3383,8103,8104],{"class":3385,"line":3447},[3383,8105,4091],{},[3383,8107,8108],{"class":3385,"line":3453},[3383,8109,3408],{"emptyLinePlaceholder":3407},[3383,8111,8112],{"class":3385,"line":3459},[3383,8113,8114],{},"class \"POST\" as POST #ef9a9a {\n",[3383,8116,8117],{"class":3385,"line":3465},[3383,8118,8119],{},"    + safe: false\n",[3383,8121,8122],{"class":3385,"line":3471},[3383,8123,8124],{},"    + idempotent: false\n",[3383,8126,8127],{"class":3385,"line":3477},[3383,8128,8129],{},"    + body: обов'язково\n",[3383,8131,8132],{"class":3385,"line":3483},[3383,8133,8096],{},[3383,8135,8136],{"class":3385,"line":3489},[3383,8137,8138],{},"    Створити ресурс або дія\n",[3383,8140,8141],{"class":3385,"line":3495},[3383,8142,4091],{},[3383,8144,8145],{"class":3385,"line":3501},[3383,8146,3408],{"emptyLinePlaceholder":3407},[3383,8148,8149],{"class":3385,"line":3507},[3383,8150,8151],{},"class \"PUT\" as PUT #ffe082 {\n",[3383,8153,8154],{"class":3385,"line":3513},[3383,8155,8119],{},[3383,8157,8158],{"class":3385,"line":3519},[3383,8159,8086],{},[3383,8161,8162],{"class":3385,"line":3525},[3383,8163,8129],{},[3383,8165,8166],{"class":3385,"line":3531},[3383,8167,8096],{},[3383,8169,8170],{"class":3385,"line":3537},[3383,8171,8172],{},"    Замінити ресурс повністю\n",[3383,8174,8175],{"class":3385,"line":3543},[3383,8176,4091],{},[3383,8178,8179],{"class":3385,"line":3549},[3383,8180,3408],{"emptyLinePlaceholder":3407},[3383,8182,8183],{"class":3385,"line":3555},[3383,8184,8185],{},"class \"PATCH\" as PATCH #ffcc80 {\n",[3383,8187,8188],{"class":3385,"line":3561},[3383,8189,8119],{},[3383,8191,8192],{"class":3385,"line":3567},[3383,8193,8194],{},"    + idempotent: false*\n",[3383,8196,8197],{"class":3385,"line":3573},[3383,8198,8129],{},[3383,8200,8201],{"class":3385,"line":3579},[3383,8202,8096],{},[3383,8204,8205],{"class":3385,"line":4215},[3383,8206,8207],{},"    Частково змінити ресурс\n",[3383,8209,8210],{"class":3385,"line":4220},[3383,8211,4091],{},[3383,8213,8214],{"class":3385,"line":4225},[3383,8215,3408],{"emptyLinePlaceholder":3407},[3383,8217,8218],{"class":3385,"line":4231},[3383,8219,8220],{},"class \"DELETE\" as DELETE #f48fb1 {\n",[3383,8222,8223],{"class":3385,"line":4237},[3383,8224,8119],{},[3383,8226,8227],{"class":3385,"line":4243},[3383,8228,8086],{},[3383,8230,8231],{"class":3385,"line":4248},[3383,8232,8233],{},"    + body: ігнорується\n",[3383,8235,8236],{"class":3385,"line":4253},[3383,8237,8096],{},[3383,8239,8240],{"class":3385,"line":4259},[3383,8241,8242],{},"    Видалити ресурс\n",[3383,8244,8245],{"class":3385,"line":4265},[3383,8246,4091],{},[3383,8248,8249],{"class":3385,"line":4271},[3383,8250,3408],{"emptyLinePlaceholder":3407},[3383,8252,8253],{"class":3385,"line":4276},[3383,8254,8255],{},"class \"HEAD\" as HEAD #b3e5fc {\n",[3383,8257,8258],{"class":3385,"line":4281},[3383,8259,8081],{},[3383,8261,8262],{"class":3385,"line":4540},[3383,8263,8086],{},[3383,8265,8266],{"class":3385,"line":4545},[3383,8267,8268],{},"    + body: відсутнє\n",[3383,8270,8271],{"class":3385,"line":4551},[3383,8272,8096],{},[3383,8274,8275],{"class":3385,"line":4557},[3383,8276,8277],{},"    GET без тіла відповіді\n",[3383,8279,8280],{"class":3385,"line":4563},[3383,8281,4091],{},[3383,8283,8284],{"class":3385,"line":4569},[3383,8285,3408],{"emptyLinePlaceholder":3407},[3383,8287,8288],{"class":3385,"line":4574},[3383,8289,8290],{},"class \"OPTIONS\" as OPTIONS #e1bee7 {\n",[3383,8292,8293],{"class":3385,"line":4579},[3383,8294,8081],{},[3383,8296,8297],{"class":3385,"line":4585},[3383,8298,8086],{},[3383,8300,8301],{"class":3385,"line":4591},[3383,8302,8096],{},[3383,8304,8305],{"class":3385,"line":4597},[3383,8306,8307],{},"    Дізнатись можливості\n",[3383,8309,8310],{"class":3385,"line":4603},[3383,8311,4091],{},[3383,8313,8314],{"class":3385,"line":4608},[3383,8315,3408],{"emptyLinePlaceholder":3407},[3383,8317,8318],{"class":3385,"line":4613},[3383,8319,4284],{},[4926,8321,8322,8341],{},[4929,8323,8324],{},[4932,8325,8326,8329,8333,8336,8338],{},[4935,8327,8328],{},"Метод",[4935,8330,8332],{"align":8331},"center","Safe",[4935,8334,8335],{"align":8331},"Idempotent",[4935,8337,6579],{"align":8331},[4935,8339,8340],{},"Типове використання",[4948,8342,8343,8360,8375,8391,8406,8422,8439,8454],{},[4932,8344,8345,8349,8352,8354,8357],{},[4953,8346,8347],{},[3380,8348,3621],{},[4953,8350,8351],{"align":8331},"✅",[4953,8353,8351],{"align":8331},[4953,8355,8356],{"align":8331},"❌",[4953,8358,8359],{},"Отримати список або ресурс",[4932,8361,8362,8366,8368,8370,8372],{},[4953,8363,8364],{},[3380,8365,3750],{},[4953,8367,8351],{"align":8331},[4953,8369,8351],{"align":8331},[4953,8371,8356],{"align":8331},[4953,8373,8374],{},"Перевірити існування, metadata",[4932,8376,8377,8382,8384,8386,8388],{},[4953,8378,8379],{},[3380,8380,8381],{},"OPTIONS",[4953,8383,8351],{"align":8331},[4953,8385,8351],{"align":8331},[4953,8387,8356],{"align":8331},[4953,8389,8390],{},"CORS preflight, можливості",[4932,8392,8393,8397,8399,8401,8403],{},[4953,8394,8395],{},[3380,8396,3746],{},[4953,8398,8356],{"align":8331},[4953,8400,8356],{"align":8331},[4953,8402,8351],{"align":8331},[4953,8404,8405],{},"Створити ресурс, надіслати форму",[4932,8407,8408,8413,8415,8417,8419],{},[4953,8409,8410],{},[3380,8411,8412],{},"PUT",[4953,8414,8356],{"align":8331},[4953,8416,8351],{"align":8331},[4953,8418,8351],{"align":8331},[4953,8420,8421],{},"Замінити ресурс повністю",[4932,8423,8424,8429,8431,8434,8436],{},[4953,8425,8426],{},[3380,8427,8428],{},"PATCH",[4953,8430,8356],{"align":8331},[4953,8432,8433],{"align":8331},"❌*",[4953,8435,8351],{"align":8331},[4953,8437,8438],{},"Часткове оновлення",[4932,8440,8441,8445,8447,8449,8451],{},[4953,8442,8443],{},[3380,8444,7467],{},[4953,8446,8356],{"align":8331},[4953,8448,8351],{"align":8331},[4953,8450,8356],{"align":8331},[4953,8452,8453],{},"Видалити ресурс",[4932,8455,8456,8461,8463,8465,8468],{},[4953,8457,8458],{},[3380,8459,8460],{},"CONNECT",[4953,8462,8356],{"align":8331},[4953,8464,8356],{"align":8331},[4953,8466,8467],{"align":8331},"—",[4953,8469,8470],{},"Проксі-тунель",[3353,8472,8473,3743,8476,8479,8480,8483,8484,8487],{},[3321,8474,8475],{},"Чому PATCH не ідемпотентний?",[3380,8477,8478],{},"PATCH {\"increment\": 1}"," збільшить лічильник щоразу по-іншому. Але ",[3380,8481,8482],{},"PATCH {\"name\": \"Alice\"}"," — фактично ідемпотентний. Ідемпотентність PATCH залежить від ",[3321,8485,8486],{},"семантики"," операції, а не від самого методу.",[3599,8489,8491],{"id":8490},"детальний-розбір-кожного-методу","Детальний розбір кожного методу",[8493,8494,8495,8919,9341,9677,10063,10333,10545],"accordion",{},[8496,8497,8500,8512,8517,8559,8662,8667,8701,8767,8772,8807,8900,8905],"accordion-item",{"icon":8498,"label":8499},"i-lucide-download","GET — отримання ресурсу",[3317,8501,8502,8504,8505,8508,8509,8511],{},[3380,8503,3621],{}," запитує ",[3321,8506,8507],{},"представлення"," ресурсу. Параметри передаються лише через ",[3321,8510,4299],{}," (query string). Ніколи не передавайте чутливі дані через GET — URL логується у браузері, проксі та серверних access-логах.",[3317,8513,8514],{},[3321,8515,8516],{},"Приклад 1: Отримання списку",[3373,8518,8520],{"className":3625,"code":8519,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nAccept: application\u002Fjson\nAuthorization: Bearer eyJhbGci...\n",[3380,8521,8522,8534,8542,8550],{"__ignoreMap":3378},[3383,8523,8524,8526,8528,8530,8532],{"class":3385,"line":3386},[3383,8525,3621],{"class":3634},[3383,8527,7056],{"class":3637},[3383,8529,3334],{"class":3780},[3383,8531,3783],{"class":3637},[3383,8533,3907],{"class":3786},[3383,8535,8536,8538,8540],{"class":3385,"line":3392},[3383,8537,3884],{"class":3657},[3383,8539,3795],{"class":3780},[3383,8541,6141],{"class":3798},[3383,8543,8544,8546,8548],{"class":3385,"line":3398},[3383,8545,3792],{"class":3657},[3383,8547,3795],{"class":3780},[3383,8549,6150],{"class":3798},[3383,8551,8552,8554,8556],{"class":3385,"line":3404},[3383,8553,6165],{"class":3657},[3383,8555,3795],{"class":3780},[3383,8557,8558],{"class":3798}," Bearer eyJhbGci...\n",[3373,8560,8562],{"className":3625,"code":8561,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\nX-Total-Count: 2\n\n{\n  \"users\": [\n    {\"id\": 1, \"name\": \"Іван\"},\n    {\"id\": 2, \"name\": \"Марія\"}\n  ]\n}\n",[3380,8563,8564,8576,8584,8594,8598,8602,8610,8632,8653,8658],{"__ignoreMap":3378},[3383,8565,8566,8568,8570,8572,8574],{"class":3385,"line":3386},[3383,8567,3334],{"class":3780},[3383,8569,3783],{"class":3637},[3383,8571,3946],{"class":3786},[3383,8573,3816],{"class":3786},[3383,8575,3819],{"class":3798},[3383,8577,8578,8580,8582],{"class":3385,"line":3392},[3383,8579,3730],{"class":3657},[3383,8581,3795],{"class":3780},[3383,8583,6150],{"class":3798},[3383,8585,8586,8589,8591],{"class":3385,"line":3398},[3383,8587,8588],{"class":3657},"X-Total-Count",[3383,8590,3795],{"class":3780},[3383,8592,8593],{"class":3798}," 2\n",[3383,8595,8596],{"class":3385,"line":3404},[3383,8597,3408],{"emptyLinePlaceholder":3407},[3383,8599,8600],{"class":3385,"line":3411},[3383,8601,5292],{"class":3637},[3383,8603,8604,8607],{"class":3385,"line":3417},[3383,8605,8606],{"class":6434},"  \"users\"",[3383,8608,8609],{"class":3637},": [\n",[3383,8611,8612,8615,8617,8619,8621,8623,8625,8627,8630],{"class":3385,"line":3423},[3383,8613,8614],{"class":3637},"    {",[3383,8616,6435],{"class":6434},[3383,8618,6438],{"class":3637},[3383,8620,5316],{"class":3786},[3383,8622,3731],{"class":3637},[3383,8624,6445],{"class":6434},[3383,8626,6438],{"class":3637},[3383,8628,8629],{"class":3798},"\"Іван\"",[3383,8631,6463],{"class":3637},[3383,8633,8634,8636,8638,8640,8642,8644,8646,8648,8651],{"class":3385,"line":3429},[3383,8635,8614],{"class":3637},[3383,8637,6435],{"class":6434},[3383,8639,6438],{"class":3637},[3383,8641,6474],{"class":3786},[3383,8643,3731],{"class":3637},[3383,8645,6445],{"class":6434},[3383,8647,6438],{"class":3637},[3383,8649,8650],{"class":3798},"\"Марія\"",[3383,8652,4091],{"class":3637},[3383,8654,8655],{"class":3385,"line":3435},[3383,8656,8657],{"class":3637},"  ]\n",[3383,8659,8660],{"class":3385,"line":3441},[3383,8661,4091],{"class":3637},[3317,8663,8664],{},[3321,8665,8666],{},"Приклад 2: Отримання конкретного ресурсу",[3373,8668,8670],{"className":3625,"code":8669,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\nAccept: application\u002Fjson\n",[3380,8671,8672,8685,8693],{"__ignoreMap":3378},[3383,8673,8674,8676,8679,8681,8683],{"class":3385,"line":3386},[3383,8675,3621],{"class":3634},[3383,8677,8678],{"class":3637}," \u002Fapi\u002Fusers\u002F1 ",[3383,8680,3334],{"class":3780},[3383,8682,3783],{"class":3637},[3383,8684,3907],{"class":3786},[3383,8686,8687,8689,8691],{"class":3385,"line":3392},[3383,8688,3884],{"class":3657},[3383,8690,3795],{"class":3780},[3383,8692,6141],{"class":3798},[3383,8694,8695,8697,8699],{"class":3385,"line":3398},[3383,8696,3792],{"class":3657},[3383,8698,3795],{"class":3780},[3383,8700,6150],{"class":3798},[3373,8702,8704],{"className":3625,"code":8703,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 1,\n  \"name\": \"Іван\",\n  \"email\": \"ivan@example.com\"\n}\n",[3380,8705,8706,8718,8726,8730,8734,8744,8754,8763],{"__ignoreMap":3378},[3383,8707,8708,8710,8712,8714,8716],{"class":3385,"line":3386},[3383,8709,3334],{"class":3780},[3383,8711,3783],{"class":3637},[3383,8713,3946],{"class":3786},[3383,8715,3816],{"class":3786},[3383,8717,3819],{"class":3798},[3383,8719,8720,8722,8724],{"class":3385,"line":3392},[3383,8721,3730],{"class":3657},[3383,8723,3795],{"class":3780},[3383,8725,6150],{"class":3798},[3383,8727,8728],{"class":3385,"line":3398},[3383,8729,3408],{"emptyLinePlaceholder":3407},[3383,8731,8732],{"class":3385,"line":3404},[3383,8733,5292],{"class":3637},[3383,8735,8736,8738,8740,8742],{"class":3385,"line":3411},[3383,8737,6898],{"class":6434},[3383,8739,6438],{"class":3637},[3383,8741,5316],{"class":3786},[3383,8743,5305],{"class":3637},[3383,8745,8746,8748,8750,8752],{"class":3385,"line":3417},[3383,8747,6910],{"class":6434},[3383,8749,6438],{"class":3637},[3383,8751,8629],{"class":3798},[3383,8753,5305],{"class":3637},[3383,8755,8756,8758,8760],{"class":3385,"line":3423},[3383,8757,6922],{"class":6434},[3383,8759,6438],{"class":3637},[3383,8761,8762],{"class":3798},"\"ivan@example.com\"\n",[3383,8764,8765],{"class":3385,"line":3429},[3383,8766,4091],{"class":3637},[3317,8768,8769],{},[3321,8770,8771],{},"Приклад 3: Фільтрація, сортування, пагінація",[3373,8773,8775],{"className":3625,"code":8774,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fproducts?category=electronics&sort=price&order=asc&page=2&limit=10 HTTP\u002F1.1\nHost: shop.example.com\nAccept: application\u002Fjson\n",[3380,8776,8777,8790,8799],{"__ignoreMap":3378},[3383,8778,8779,8781,8784,8786,8788],{"class":3385,"line":3386},[3383,8780,3621],{"class":3634},[3383,8782,8783],{"class":3637}," \u002Fapi\u002Fproducts?category=electronics&sort=price&order=asc&page=2&limit=10 ",[3383,8785,3334],{"class":3780},[3383,8787,3783],{"class":3637},[3383,8789,3907],{"class":3786},[3383,8791,8792,8794,8796],{"class":3385,"line":3392},[3383,8793,3884],{"class":3657},[3383,8795,3795],{"class":3780},[3383,8797,8798],{"class":3798}," shop.example.com\n",[3383,8800,8801,8803,8805],{"class":3385,"line":3398},[3383,8802,3792],{"class":3657},[3383,8804,3795],{"class":3780},[3383,8806,6150],{"class":3798},[3373,8808,8810],{"className":3625,"code":8809,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\nX-Total-Count: 143\n\n{\n  \"data\": [...],\n  \"meta\": {\"total\": 143, \"page\": 2, \"per_page\": 10}\n}\n",[3380,8811,8812,8824,8832,8841,8845,8849,8860,8896],{"__ignoreMap":3378},[3383,8813,8814,8816,8818,8820,8822],{"class":3385,"line":3386},[3383,8815,3334],{"class":3780},[3383,8817,3783],{"class":3637},[3383,8819,3946],{"class":3786},[3383,8821,3816],{"class":3786},[3383,8823,3819],{"class":3798},[3383,8825,8826,8828,8830],{"class":3385,"line":3392},[3383,8827,3730],{"class":3657},[3383,8829,3795],{"class":3780},[3383,8831,6150],{"class":3798},[3383,8833,8834,8836,8838],{"class":3385,"line":3398},[3383,8835,8588],{"class":3657},[3383,8837,3795],{"class":3780},[3383,8839,8840],{"class":3798}," 143\n",[3383,8842,8843],{"class":3385,"line":3404},[3383,8844,3408],{"emptyLinePlaceholder":3407},[3383,8846,8847],{"class":3385,"line":3411},[3383,8848,5292],{"class":3637},[3383,8850,8851,8854,8856,8858],{"class":3385,"line":3417},[3383,8852,8853],{"class":6434},"  \"data\"",[3383,8855,7421],{"class":3637},[3383,8857,3851],{"class":7789},[3383,8859,7427],{"class":3637},[3383,8861,8862,8865,8868,8871,8873,8876,8878,8880,8882,8884,8886,8889,8891,8894],{"class":3385,"line":3423},[3383,8863,8864],{"class":6434},"  \"meta\"",[3383,8866,8867],{"class":3637},": {",[3383,8869,8870],{"class":6434},"\"total\"",[3383,8872,6438],{"class":3637},[3383,8874,8875],{"class":3786},"143",[3383,8877,3731],{"class":3637},[3383,8879,5371],{"class":6434},[3383,8881,6438],{"class":3637},[3383,8883,6474],{"class":3786},[3383,8885,3731],{"class":3637},[3383,8887,8888],{"class":6434},"\"per_page\"",[3383,8890,6438],{"class":3637},[3383,8892,8893],{"class":3786},"10",[3383,8895,4091],{"class":3637},[3383,8897,8898],{"class":3385,"line":3429},[3383,8899,4091],{"class":3637},[3317,8901,8902],{},[3321,8903,8904],{},"Коли використовувати:",[3719,8906,8907,8910,8913,8916],{},[3722,8908,8909],{},"Отримання одного або колекції ресурсів",[3722,8911,8912],{},"Пошук і фільтрація",[3722,8914,8915],{},"Пагінація",[3722,8917,8918],{},"Будь-яка read-only операція",[8496,8920,8923,8932,8937,9022,9106,9111,9178,9237,9242,9286,9314,9318],{"icon":8921,"label":8922},"i-lucide-plus","POST — створення або дія",[3317,8924,8925,8927,8928,8931],{},[3380,8926,3746],{}," надсилає дані для ",[3321,8929,8930],{},"обробки",". Найчастіше: створення нового ресурсу або виконання дії (login, upload, checkout).",[3317,8933,8934],{},[3321,8935,8936],{},"Приклад 1: Створення ресурсу",[3373,8938,8940],{"className":3625,"code":8939,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\nContent-Length: 62\n\n{\n  \"name\": \"Олена\",\n  \"email\": \"olena@example.com\",\n  \"role\": \"user\"\n}\n",[3380,8941,8942,8954,8962,8970,8979,8983,8987,8998,9009,9018],{"__ignoreMap":3378},[3383,8943,8944,8946,8948,8950,8952],{"class":3385,"line":3386},[3383,8945,3746],{"class":3634},[3383,8947,7056],{"class":3637},[3383,8949,3334],{"class":3780},[3383,8951,3783],{"class":3637},[3383,8953,3907],{"class":3786},[3383,8955,8956,8958,8960],{"class":3385,"line":3392},[3383,8957,3884],{"class":3657},[3383,8959,3795],{"class":3780},[3383,8961,6141],{"class":3798},[3383,8963,8964,8966,8968],{"class":3385,"line":3398},[3383,8965,3730],{"class":3657},[3383,8967,3795],{"class":3780},[3383,8969,6150],{"class":3798},[3383,8971,8972,8974,8976],{"class":3385,"line":3404},[3383,8973,3734],{"class":3657},[3383,8975,3795],{"class":3780},[3383,8977,8978],{"class":3798}," 62\n",[3383,8980,8981],{"class":3385,"line":3411},[3383,8982,3408],{"emptyLinePlaceholder":3407},[3383,8984,8985],{"class":3385,"line":3417},[3383,8986,5292],{"class":3637},[3383,8988,8989,8991,8993,8996],{"class":3385,"line":3423},[3383,8990,6910],{"class":6434},[3383,8992,6438],{"class":3637},[3383,8994,8995],{"class":3798},"\"Олена\"",[3383,8997,5305],{"class":3637},[3383,8999,9000,9002,9004,9007],{"class":3385,"line":3429},[3383,9001,6922],{"class":6434},[3383,9003,6438],{"class":3637},[3383,9005,9006],{"class":3798},"\"olena@example.com\"",[3383,9008,5305],{"class":3637},[3383,9010,9011,9013,9015],{"class":3385,"line":3435},[3383,9012,6934],{"class":6434},[3383,9014,6438],{"class":3637},[3383,9016,9017],{"class":3798},"\"user\"\n",[3383,9019,9020],{"class":3385,"line":3441},[3383,9021,4091],{"class":3637},[3373,9023,9025],{"className":3625,"code":9024,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 201 Created\nLocation: \u002Fapi\u002Fusers\u002F43\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 43,\n  \"name\": \"Олена\",\n  \"email\": \"olena@example.com\",\n  \"created_at\": \"2026-05-17T09:00:00Z\"\n}\n",[3380,9026,9027,9039,9047,9055,9059,9063,9073,9083,9093,9102],{"__ignoreMap":3378},[3383,9028,9029,9031,9033,9035,9037],{"class":3385,"line":3386},[3383,9030,3334],{"class":3780},[3383,9032,3783],{"class":3637},[3383,9034,3946],{"class":3786},[3383,9036,7166],{"class":3786},[3383,9038,7169],{"class":3798},[3383,9040,9041,9043,9045],{"class":3385,"line":3392},[3383,9042,7191],{"class":3657},[3383,9044,3795],{"class":3780},[3383,9046,7196],{"class":3798},[3383,9048,9049,9051,9053],{"class":3385,"line":3398},[3383,9050,3730],{"class":3657},[3383,9052,3795],{"class":3780},[3383,9054,6150],{"class":3798},[3383,9056,9057],{"class":3385,"line":3404},[3383,9058,3408],{"emptyLinePlaceholder":3407},[3383,9060,9061],{"class":3385,"line":3411},[3383,9062,5292],{"class":3637},[3383,9064,9065,9067,9069,9071],{"class":3385,"line":3417},[3383,9066,6898],{"class":6434},[3383,9068,6438],{"class":3637},[3383,9070,7222],{"class":3786},[3383,9072,5305],{"class":3637},[3383,9074,9075,9077,9079,9081],{"class":3385,"line":3423},[3383,9076,6910],{"class":6434},[3383,9078,6438],{"class":3637},[3383,9080,8995],{"class":3798},[3383,9082,5305],{"class":3637},[3383,9084,9085,9087,9089,9091],{"class":3385,"line":3429},[3383,9086,6922],{"class":6434},[3383,9088,6438],{"class":3637},[3383,9090,9006],{"class":3798},[3383,9092,5305],{"class":3637},[3383,9094,9095,9097,9099],{"class":3385,"line":3435},[3383,9096,7260],{"class":6434},[3383,9098,6438],{"class":3637},[3383,9100,9101],{"class":3798},"\"2026-05-17T09:00:00Z\"\n",[3383,9103,9104],{"class":3385,"line":3441},[3383,9105,4091],{"class":3637},[3317,9107,9108],{},[3321,9109,9110],{},"Приклад 2: Логін (дія, що не створює REST-ресурс)",[3373,9112,9114],{"className":3625,"code":9113,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fauth\u002Flogin HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\n  \"email\": \"ivan@example.com\",\n  \"password\": \"s3cr3t\"\n}\n",[3380,9115,9116,9129,9137,9145,9149,9153,9164,9174],{"__ignoreMap":3378},[3383,9117,9118,9120,9123,9125,9127],{"class":3385,"line":3386},[3383,9119,3746],{"class":3634},[3383,9121,9122],{"class":3637}," \u002Fapi\u002Fauth\u002Flogin ",[3383,9124,3334],{"class":3780},[3383,9126,3783],{"class":3637},[3383,9128,3907],{"class":3786},[3383,9130,9131,9133,9135],{"class":3385,"line":3392},[3383,9132,3884],{"class":3657},[3383,9134,3795],{"class":3780},[3383,9136,6141],{"class":3798},[3383,9138,9139,9141,9143],{"class":3385,"line":3398},[3383,9140,3730],{"class":3657},[3383,9142,3795],{"class":3780},[3383,9144,6150],{"class":3798},[3383,9146,9147],{"class":3385,"line":3404},[3383,9148,3408],{"emptyLinePlaceholder":3407},[3383,9150,9151],{"class":3385,"line":3411},[3383,9152,5292],{"class":3637},[3383,9154,9155,9157,9159,9162],{"class":3385,"line":3417},[3383,9156,6922],{"class":6434},[3383,9158,6438],{"class":3637},[3383,9160,9161],{"class":3798},"\"ivan@example.com\"",[3383,9163,5305],{"class":3637},[3383,9165,9166,9169,9171],{"class":3385,"line":3423},[3383,9167,9168],{"class":6434},"  \"password\"",[3383,9170,6438],{"class":3637},[3383,9172,9173],{"class":3798},"\"s3cr3t\"\n",[3383,9175,9176],{"class":3385,"line":3429},[3383,9177,4091],{"class":3637},[3373,9179,9181],{"className":3625,"code":9180,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"token\": \"eyJhbGci...\",\n  \"expires_in\": 3600\n}\n",[3380,9182,9183,9195,9203,9207,9211,9223,9233],{"__ignoreMap":3378},[3383,9184,9185,9187,9189,9191,9193],{"class":3385,"line":3386},[3383,9186,3334],{"class":3780},[3383,9188,3783],{"class":3637},[3383,9190,3946],{"class":3786},[3383,9192,3816],{"class":3786},[3383,9194,3819],{"class":3798},[3383,9196,9197,9199,9201],{"class":3385,"line":3392},[3383,9198,3730],{"class":3657},[3383,9200,3795],{"class":3780},[3383,9202,6150],{"class":3798},[3383,9204,9205],{"class":3385,"line":3398},[3383,9206,3408],{"emptyLinePlaceholder":3407},[3383,9208,9209],{"class":3385,"line":3404},[3383,9210,5292],{"class":3637},[3383,9212,9213,9216,9218,9221],{"class":3385,"line":3411},[3383,9214,9215],{"class":6434},"  \"token\"",[3383,9217,6438],{"class":3637},[3383,9219,9220],{"class":3798},"\"eyJhbGci...\"",[3383,9222,5305],{"class":3637},[3383,9224,9225,9228,9230],{"class":3385,"line":3417},[3383,9226,9227],{"class":6434},"  \"expires_in\"",[3383,9229,6438],{"class":3637},[3383,9231,9232],{"class":3786},"3600\n",[3383,9234,9235],{"class":3385,"line":3423},[3383,9236,4091],{"class":3637},[3317,9238,9239],{},[3321,9240,9241],{},"Приклад 3: Відправка форми (HTML form)",[3373,9243,9245],{"className":3625,"code":9244,"language":3627,"meta":3378,"style":3378},"POST \u002Fcontact HTTP\u002F1.1\nHost: example.com\nContent-Type: application\u002Fx-www-form-urlencoded\n\nname=Іван&email=ivan%40example.com&message=Привіт\n",[3380,9246,9247,9260,9268,9277,9281],{"__ignoreMap":3378},[3383,9248,9249,9251,9254,9256,9258],{"class":3385,"line":3386},[3383,9250,3746],{"class":3634},[3383,9252,9253],{"class":3637}," \u002Fcontact ",[3383,9255,3334],{"class":3780},[3383,9257,3783],{"class":3637},[3383,9259,3907],{"class":3786},[3383,9261,9262,9264,9266],{"class":3385,"line":3392},[3383,9263,3884],{"class":3657},[3383,9265,3795],{"class":3780},[3383,9267,7662],{"class":3798},[3383,9269,9270,9272,9274],{"class":3385,"line":3398},[3383,9271,3730],{"class":3657},[3383,9273,3795],{"class":3780},[3383,9275,9276],{"class":3798}," application\u002Fx-www-form-urlencoded\n",[3383,9278,9279],{"class":3385,"line":3404},[3383,9280,3408],{"emptyLinePlaceholder":3407},[3383,9282,9283],{"class":3385,"line":3411},[3383,9284,9285],{"class":3637},"name=Іван&email=ivan%40example.com&message=Привіт\n",[3373,9287,9289],{"className":3625,"code":9288,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 303 See Other\nLocation: \u002Fcontact\u002Fthanks\n",[3380,9290,9291,9305],{"__ignoreMap":3378},[3383,9292,9293,9295,9297,9299,9302],{"class":3385,"line":3386},[3383,9294,3334],{"class":3780},[3383,9296,3783],{"class":3637},[3383,9298,3946],{"class":3786},[3383,9300,9301],{"class":3786}," 303",[3383,9303,9304],{"class":3798}," See Other\n",[3383,9306,9307,9309,9311],{"class":3385,"line":3392},[3383,9308,7191],{"class":3657},[3383,9310,3795],{"class":3780},[3383,9312,9313],{"class":3798}," \u002Fcontact\u002Fthanks\n",[3317,9315,9316],{},[3321,9317,8904],{},[3719,9319,9320,9326,9335,9338],{},[3722,9321,9322,9323,4902],{},"Створення нового ресурсу (відповідь ",[3380,9324,9325],{},"201",[3722,9327,9328,9329,3731,9332,4902],{},"Виконання дії (",[3380,9330,9331],{},"\u002Forders\u002F42\u002Fpay",[3380,9333,9334],{},"\u002Femails\u002Fsend",[3722,9336,9337],{},"Відправка великих або чутливих даних",[3722,9339,9340],{},"Завантаження файлів",[8496,9342,9345,9357,9362,9448,9536,9541,9612,9638,9662,9666],{"icon":9343,"label":9344},"i-lucide-replace","PUT — повна заміна ресурсу",[3317,9346,9347,3743,9349,9352,9353,9356],{},[3380,9348,8412],{},[3321,9350,9351],{},"повністю замінює"," ресурс за вказаним URL. Тіло запиту — це нове ",[3321,9354,9355],{},"повне"," представлення. Поля, не вказані у тілі PUT, втрачаються.",[3317,9358,9359],{},[3321,9360,9361],{},"Приклад 1: Оновлення (повна заміна)",[3373,9363,9365],{"className":3625,"code":9364,"language":3627,"meta":3378,"style":3378},"PUT \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 1,\n  \"name\": \"Іван Петренко\",\n  \"email\": \"ivan.new@example.com\",\n  \"role\": \"admin\"\n}\n",[3380,9366,9367,9379,9387,9395,9399,9403,9413,9424,9435,9444],{"__ignoreMap":3378},[3383,9368,9369,9371,9373,9375,9377],{"class":3385,"line":3386},[3383,9370,8412],{"class":3634},[3383,9372,8678],{"class":3637},[3383,9374,3334],{"class":3780},[3383,9376,3783],{"class":3637},[3383,9378,3907],{"class":3786},[3383,9380,9381,9383,9385],{"class":3385,"line":3392},[3383,9382,3884],{"class":3657},[3383,9384,3795],{"class":3780},[3383,9386,6141],{"class":3798},[3383,9388,9389,9391,9393],{"class":3385,"line":3398},[3383,9390,3730],{"class":3657},[3383,9392,3795],{"class":3780},[3383,9394,6150],{"class":3798},[3383,9396,9397],{"class":3385,"line":3404},[3383,9398,3408],{"emptyLinePlaceholder":3407},[3383,9400,9401],{"class":3385,"line":3411},[3383,9402,5292],{"class":3637},[3383,9404,9405,9407,9409,9411],{"class":3385,"line":3417},[3383,9406,6898],{"class":6434},[3383,9408,6438],{"class":3637},[3383,9410,5316],{"class":3786},[3383,9412,5305],{"class":3637},[3383,9414,9415,9417,9419,9422],{"class":3385,"line":3423},[3383,9416,6910],{"class":6434},[3383,9418,6438],{"class":3637},[3383,9420,9421],{"class":3798},"\"Іван Петренко\"",[3383,9423,5305],{"class":3637},[3383,9425,9426,9428,9430,9433],{"class":3385,"line":3429},[3383,9427,6922],{"class":6434},[3383,9429,6438],{"class":3637},[3383,9431,9432],{"class":3798},"\"ivan.new@example.com\"",[3383,9434,5305],{"class":3637},[3383,9436,9437,9439,9441],{"class":3385,"line":3435},[3383,9438,6934],{"class":6434},[3383,9440,6438],{"class":3637},[3383,9442,9443],{"class":3798},"\"admin\"\n",[3383,9445,9446],{"class":3385,"line":3441},[3383,9447,4091],{"class":3637},[3373,9449,9451],{"className":3625,"code":9450,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 1,\n  \"name\": \"Іван Петренко\",\n  \"email\": \"ivan.new@example.com\",\n  \"role\": \"admin\",\n  \"updated_at\": \"2026-05-17T10:00:00Z\"\n}\n",[3380,9452,9453,9465,9473,9477,9481,9491,9501,9511,9522,9532],{"__ignoreMap":3378},[3383,9454,9455,9457,9459,9461,9463],{"class":3385,"line":3386},[3383,9456,3334],{"class":3780},[3383,9458,3783],{"class":3637},[3383,9460,3946],{"class":3786},[3383,9462,3816],{"class":3786},[3383,9464,3819],{"class":3798},[3383,9466,9467,9469,9471],{"class":3385,"line":3392},[3383,9468,3730],{"class":3657},[3383,9470,3795],{"class":3780},[3383,9472,6150],{"class":3798},[3383,9474,9475],{"class":3385,"line":3398},[3383,9476,3408],{"emptyLinePlaceholder":3407},[3383,9478,9479],{"class":3385,"line":3404},[3383,9480,5292],{"class":3637},[3383,9482,9483,9485,9487,9489],{"class":3385,"line":3411},[3383,9484,6898],{"class":6434},[3383,9486,6438],{"class":3637},[3383,9488,5316],{"class":3786},[3383,9490,5305],{"class":3637},[3383,9492,9493,9495,9497,9499],{"class":3385,"line":3417},[3383,9494,6910],{"class":6434},[3383,9496,6438],{"class":3637},[3383,9498,9421],{"class":3798},[3383,9500,5305],{"class":3637},[3383,9502,9503,9505,9507,9509],{"class":3385,"line":3423},[3383,9504,6922],{"class":6434},[3383,9506,6438],{"class":3637},[3383,9508,9432],{"class":3798},[3383,9510,5305],{"class":3637},[3383,9512,9513,9515,9517,9520],{"class":3385,"line":3429},[3383,9514,6934],{"class":6434},[3383,9516,6438],{"class":3637},[3383,9518,9519],{"class":3798},"\"admin\"",[3383,9521,5305],{"class":3637},[3383,9523,9524,9527,9529],{"class":3385,"line":3435},[3383,9525,9526],{"class":6434},"  \"updated_at\"",[3383,9528,6438],{"class":3637},[3383,9530,9531],{"class":3798},"\"2026-05-17T10:00:00Z\"\n",[3383,9533,9534],{"class":3385,"line":3441},[3383,9535,4091],{"class":3637},[3317,9537,9538],{},[3321,9539,9540],{},"Приклад 2: Upsert (create or replace) з відомим ID",[3373,9542,9544],{"className":3625,"code":9543,"language":3627,"meta":3378,"style":3378},"PUT \u002Fapi\u002Fsettings\u002Ftheme HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\"key\": \"theme\", \"value\": \"dark\", \"user_id\": 42}\n",[3380,9545,9546,9559,9567,9575,9579],{"__ignoreMap":3378},[3383,9547,9548,9550,9553,9555,9557],{"class":3385,"line":3386},[3383,9549,8412],{"class":3634},[3383,9551,9552],{"class":3637}," \u002Fapi\u002Fsettings\u002Ftheme ",[3383,9554,3334],{"class":3780},[3383,9556,3783],{"class":3637},[3383,9558,3907],{"class":3786},[3383,9560,9561,9563,9565],{"class":3385,"line":3392},[3383,9562,3884],{"class":3657},[3383,9564,3795],{"class":3780},[3383,9566,6141],{"class":3798},[3383,9568,9569,9571,9573],{"class":3385,"line":3398},[3383,9570,3730],{"class":3657},[3383,9572,3795],{"class":3780},[3383,9574,6150],{"class":3798},[3383,9576,9577],{"class":3385,"line":3404},[3383,9578,3408],{"emptyLinePlaceholder":3407},[3383,9580,9581,9583,9586,9588,9591,9593,9596,9598,9601,9603,9606,9608,9610],{"class":3385,"line":3411},[3383,9582,5466],{"class":3637},[3383,9584,9585],{"class":6434},"\"key\"",[3383,9587,6438],{"class":3637},[3383,9589,9590],{"class":3798},"\"theme\"",[3383,9592,3731],{"class":3637},[3383,9594,9595],{"class":6434},"\"value\"",[3383,9597,6438],{"class":3637},[3383,9599,9600],{"class":3798},"\"dark\"",[3383,9602,3731],{"class":3637},[3383,9604,9605],{"class":6434},"\"user_id\"",[3383,9607,6438],{"class":3637},[3383,9609,6903],{"class":3786},[3383,9611,4091],{"class":3637},[3373,9613,9615],{"className":3625,"code":9614,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 201 Created\nLocation: \u002Fapi\u002Fsettings\u002Ftheme\n",[3380,9616,9617,9629],{"__ignoreMap":3378},[3383,9618,9619,9621,9623,9625,9627],{"class":3385,"line":3386},[3383,9620,3334],{"class":3780},[3383,9622,3783],{"class":3637},[3383,9624,3946],{"class":3786},[3383,9626,7166],{"class":3786},[3383,9628,7169],{"class":3798},[3383,9630,9631,9633,9635],{"class":3385,"line":3392},[3383,9632,7191],{"class":3657},[3383,9634,3795],{"class":3780},[3383,9636,9637],{"class":3798}," \u002Fapi\u002Fsettings\u002Ftheme\n",[3317,9639,9640,9643,9644,9646,9647,9650,9651,9653,9654,9657,9658,9661],{},[3321,9641,9642],{},"PUT vs PATCH:"," якщо надіслати ",[3380,9645,8412],{}," без поля ",[3380,9648,9649],{},"role",", то ",[3380,9652,9649],{}," буде ",[3321,9655,9656],{},"видалено"," або скинуто до значення за замовчуванням. Завжди передавайте у PUT ",[3321,9659,9660],{},"всі поля"," ресурсу, навіть ті, що не змінюються.",[3317,9663,9664],{},[3321,9665,8904],{},[3719,9667,9668,9671,9674],{},[3722,9669,9670],{},"Повна заміна ресурсу відомою структурою",[3722,9672,9673],{},"Upsert операції",[3722,9675,9676],{},"Коли ідемпотентність критична",[8496,9678,9681,9690,9695,9750,9826,9831,9965,10048,10052],{"icon":9679,"label":9680},"i-lucide-pencil","PATCH — часткове оновлення",[3317,9682,9683,9685,9686,9689],{},[3380,9684,8428],{}," оновлює ",[3321,9687,9688],{},"лише вказані поля"," ресурсу (RFC 5789). Решта полів залишаються незмінними.",[3317,9691,9692],{},[3321,9693,9694],{},"Приклад 1: JSON Merge Patch — простий підхід",[3373,9696,9698],{"className":3625,"code":9697,"language":3627,"meta":3378,"style":3378},"PATCH \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fmerge-patch+json\n\n{\n  \"email\": \"ivan.updated@example.com\"\n}\n",[3380,9699,9700,9712,9720,9729,9733,9737,9746],{"__ignoreMap":3378},[3383,9701,9702,9704,9706,9708,9710],{"class":3385,"line":3386},[3383,9703,8428],{"class":3634},[3383,9705,8678],{"class":3637},[3383,9707,3334],{"class":3780},[3383,9709,3783],{"class":3637},[3383,9711,3907],{"class":3786},[3383,9713,9714,9716,9718],{"class":3385,"line":3392},[3383,9715,3884],{"class":3657},[3383,9717,3795],{"class":3780},[3383,9719,6141],{"class":3798},[3383,9721,9722,9724,9726],{"class":3385,"line":3398},[3383,9723,3730],{"class":3657},[3383,9725,3795],{"class":3780},[3383,9727,9728],{"class":3798}," application\u002Fmerge-patch+json\n",[3383,9730,9731],{"class":3385,"line":3404},[3383,9732,3408],{"emptyLinePlaceholder":3407},[3383,9734,9735],{"class":3385,"line":3411},[3383,9736,5292],{"class":3637},[3383,9738,9739,9741,9743],{"class":3385,"line":3417},[3383,9740,6922],{"class":6434},[3383,9742,6438],{"class":3637},[3383,9744,9745],{"class":3798},"\"ivan.updated@example.com\"\n",[3383,9747,9748],{"class":3385,"line":3423},[3383,9749,4091],{"class":3637},[3373,9751,9753],{"className":3625,"code":9752,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 1,\n  \"name\": \"Іван\",\n  \"email\": \"ivan.updated@example.com\",\n  \"role\": \"user\"\n}\n",[3380,9754,9755,9767,9775,9779,9783,9793,9803,9814,9822],{"__ignoreMap":3378},[3383,9756,9757,9759,9761,9763,9765],{"class":3385,"line":3386},[3383,9758,3334],{"class":3780},[3383,9760,3783],{"class":3637},[3383,9762,3946],{"class":3786},[3383,9764,3816],{"class":3786},[3383,9766,3819],{"class":3798},[3383,9768,9769,9771,9773],{"class":3385,"line":3392},[3383,9770,3730],{"class":3657},[3383,9772,3795],{"class":3780},[3383,9774,6150],{"class":3798},[3383,9776,9777],{"class":3385,"line":3398},[3383,9778,3408],{"emptyLinePlaceholder":3407},[3383,9780,9781],{"class":3385,"line":3404},[3383,9782,5292],{"class":3637},[3383,9784,9785,9787,9789,9791],{"class":3385,"line":3411},[3383,9786,6898],{"class":6434},[3383,9788,6438],{"class":3637},[3383,9790,5316],{"class":3786},[3383,9792,5305],{"class":3637},[3383,9794,9795,9797,9799,9801],{"class":3385,"line":3417},[3383,9796,6910],{"class":6434},[3383,9798,6438],{"class":3637},[3383,9800,8629],{"class":3798},[3383,9802,5305],{"class":3637},[3383,9804,9805,9807,9809,9812],{"class":3385,"line":3423},[3383,9806,6922],{"class":6434},[3383,9808,6438],{"class":3637},[3383,9810,9811],{"class":3798},"\"ivan.updated@example.com\"",[3383,9813,5305],{"class":3637},[3383,9815,9816,9818,9820],{"class":3385,"line":3429},[3383,9817,6934],{"class":6434},[3383,9819,6438],{"class":3637},[3383,9821,9017],{"class":3798},[3383,9823,9824],{"class":3385,"line":3435},[3383,9825,4091],{"class":3637},[3317,9827,9828],{},[3321,9829,9830],{},"Приклад 2: JSON Patch RFC 6902 — операції над документом",[3373,9832,9834],{"className":3625,"code":9833,"language":3627,"meta":3378,"style":3378},"PATCH \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson-patch+json\n\n[\n  {\"op\": \"replace\", \"path\": \"\u002Femail\", \"value\": \"new@example.com\"},\n  {\"op\": \"add\",     \"path\": \"\u002Ftags\u002F-\", \"value\": \"vip\"},\n  {\"op\": \"remove\",  \"path\": \"\u002Ftemp_flag\"}\n]\n",[3380,9835,9836,9848,9856,9865,9869,9873,9906,9938,9961],{"__ignoreMap":3378},[3383,9837,9838,9840,9842,9844,9846],{"class":3385,"line":3386},[3383,9839,8428],{"class":3634},[3383,9841,8678],{"class":3637},[3383,9843,3334],{"class":3780},[3383,9845,3783],{"class":3637},[3383,9847,3907],{"class":3786},[3383,9849,9850,9852,9854],{"class":3385,"line":3392},[3383,9851,3884],{"class":3657},[3383,9853,3795],{"class":3780},[3383,9855,6141],{"class":3798},[3383,9857,9858,9860,9862],{"class":3385,"line":3398},[3383,9859,3730],{"class":3657},[3383,9861,3795],{"class":3780},[3383,9863,9864],{"class":3798}," application\u002Fjson-patch+json\n",[3383,9866,9867],{"class":3385,"line":3404},[3383,9868,3408],{"emptyLinePlaceholder":3407},[3383,9870,9871],{"class":3385,"line":3411},[3383,9872,6426],{"class":3637},[3383,9874,9875,9877,9880,9882,9885,9887,9890,9892,9895,9897,9899,9901,9904],{"class":3385,"line":3417},[3383,9876,6431],{"class":3637},[3383,9878,9879],{"class":6434},"\"op\"",[3383,9881,6438],{"class":3637},[3383,9883,9884],{"class":3798},"\"replace\"",[3383,9886,3731],{"class":3637},[3383,9888,9889],{"class":6434},"\"path\"",[3383,9891,6438],{"class":3637},[3383,9893,9894],{"class":3798},"\"\u002Femail\"",[3383,9896,3731],{"class":3637},[3383,9898,9595],{"class":6434},[3383,9900,6438],{"class":3637},[3383,9902,9903],{"class":3798},"\"new@example.com\"",[3383,9905,6463],{"class":3637},[3383,9907,9908,9910,9912,9914,9917,9920,9922,9924,9927,9929,9931,9933,9936],{"class":3385,"line":3423},[3383,9909,6431],{"class":3637},[3383,9911,9879],{"class":6434},[3383,9913,6438],{"class":3637},[3383,9915,9916],{"class":3798},"\"add\"",[3383,9918,9919],{"class":3637},",     ",[3383,9921,9889],{"class":6434},[3383,9923,6438],{"class":3637},[3383,9925,9926],{"class":3798},"\"\u002Ftags\u002F-\"",[3383,9928,3731],{"class":3637},[3383,9930,9595],{"class":6434},[3383,9932,6438],{"class":3637},[3383,9934,9935],{"class":3798},"\"vip\"",[3383,9937,6463],{"class":3637},[3383,9939,9940,9942,9944,9946,9949,9952,9954,9956,9959],{"class":3385,"line":3429},[3383,9941,6431],{"class":3637},[3383,9943,9879],{"class":6434},[3383,9945,6438],{"class":3637},[3383,9947,9948],{"class":3798},"\"remove\"",[3383,9950,9951],{"class":3637},",  ",[3383,9953,9889],{"class":6434},[3383,9955,6438],{"class":3637},[3383,9957,9958],{"class":3798},"\"\u002Ftemp_flag\"",[3383,9960,4091],{"class":3637},[3383,9962,9963],{"class":3385,"line":3435},[3383,9964,6499],{"class":3637},[3373,9966,9968],{"className":3625,"code":9967,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 1,\n  \"name\": \"Іван\",\n  \"email\": \"new@example.com\",\n  \"tags\": [\"user\", \"vip\"]\n}\n",[3380,9969,9970,9982,9990,9994,9998,10008,10018,10028,10044],{"__ignoreMap":3378},[3383,9971,9972,9974,9976,9978,9980],{"class":3385,"line":3386},[3383,9973,3334],{"class":3780},[3383,9975,3783],{"class":3637},[3383,9977,3946],{"class":3786},[3383,9979,3816],{"class":3786},[3383,9981,3819],{"class":3798},[3383,9983,9984,9986,9988],{"class":3385,"line":3392},[3383,9985,3730],{"class":3657},[3383,9987,3795],{"class":3780},[3383,9989,6150],{"class":3798},[3383,9991,9992],{"class":3385,"line":3398},[3383,9993,3408],{"emptyLinePlaceholder":3407},[3383,9995,9996],{"class":3385,"line":3404},[3383,9997,5292],{"class":3637},[3383,9999,10000,10002,10004,10006],{"class":3385,"line":3411},[3383,10001,6898],{"class":6434},[3383,10003,6438],{"class":3637},[3383,10005,5316],{"class":3786},[3383,10007,5305],{"class":3637},[3383,10009,10010,10012,10014,10016],{"class":3385,"line":3417},[3383,10011,6910],{"class":6434},[3383,10013,6438],{"class":3637},[3383,10015,8629],{"class":3798},[3383,10017,5305],{"class":3637},[3383,10019,10020,10022,10024,10026],{"class":3385,"line":3423},[3383,10021,6922],{"class":6434},[3383,10023,6438],{"class":3637},[3383,10025,9903],{"class":3798},[3383,10027,5305],{"class":3637},[3383,10029,10030,10033,10035,10038,10040,10042],{"class":3385,"line":3429},[3383,10031,10032],{"class":6434},"  \"tags\"",[3383,10034,7421],{"class":3637},[3383,10036,10037],{"class":3798},"\"user\"",[3383,10039,3731],{"class":3637},[3383,10041,9935],{"class":3798},[3383,10043,6499],{"class":3637},[3383,10045,10046],{"class":3385,"line":3435},[3383,10047,4091],{"class":3637},[3317,10049,10050],{},[3321,10051,8904],{},[3719,10053,10054,10057,10060],{},[3722,10055,10056],{},"Зміна одного-двох полів великого об'єкту",[3722,10058,10059],{},"Мобільні клієнти з обмеженим трафіком",[3722,10061,10062],{},"Часткові оновлення без завантаження всього об'єкту",[8496,10064,10067,10074,10079,10112,10129,10134,10159,10217,10222,10248,10318,10322],{"icon":10065,"label":10066},"i-lucide-trash-2","DELETE — видалення ресурсу",[3317,10068,10069,10071,10072,4760],{},[3380,10070,7467],{}," видаляє ресурс. Ідемпотентний: перший виклик видаляє, наступні — повертають ",[3380,10073,7589],{},[3317,10075,10076],{},[3321,10077,10078],{},"Приклад 1: Успішне видалення",[3373,10080,10082],{"className":3625,"code":10081,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fusers\u002F42 HTTP\u002F1.1\nHost: api.example.com\nAuthorization: Bearer eyJhbGci...\n",[3380,10083,10084,10096,10104],{"__ignoreMap":3378},[3383,10085,10086,10088,10090,10092,10094],{"class":3385,"line":3386},[3383,10087,7467],{"class":3634},[3383,10089,6764],{"class":3637},[3383,10091,3334],{"class":3780},[3383,10093,3783],{"class":3637},[3383,10095,3907],{"class":3786},[3383,10097,10098,10100,10102],{"class":3385,"line":3392},[3383,10099,3884],{"class":3657},[3383,10101,3795],{"class":3780},[3383,10103,6141],{"class":3798},[3383,10105,10106,10108,10110],{"class":3385,"line":3398},[3383,10107,6165],{"class":3657},[3383,10109,3795],{"class":3780},[3383,10111,8558],{"class":3798},[3373,10113,10115],{"className":3625,"code":10114,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 204 No Content\n",[3380,10116,10117],{"__ignoreMap":3378},[3383,10118,10119,10121,10123,10125,10127],{"class":3385,"line":3386},[3383,10120,3334],{"class":3780},[3383,10122,3783],{"class":3637},[3383,10124,3946],{"class":3786},[3383,10126,7500],{"class":3786},[3383,10128,7503],{"class":3798},[3317,10130,10131],{},[3321,10132,10133],{},"Приклад 2: Повторний DELETE (ідемпотентна поведінка)",[3373,10135,10137],{"className":3625,"code":10136,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fusers\u002F42 HTTP\u002F1.1\nHost: api.example.com\n",[3380,10138,10139,10151],{"__ignoreMap":3378},[3383,10140,10141,10143,10145,10147,10149],{"class":3385,"line":3386},[3383,10142,7467],{"class":3634},[3383,10144,6764],{"class":3637},[3383,10146,3334],{"class":3780},[3383,10148,3783],{"class":3637},[3383,10150,3907],{"class":3786},[3383,10152,10153,10155,10157],{"class":3385,"line":3392},[3383,10154,3884],{"class":3657},[3383,10156,3795],{"class":3780},[3383,10158,6141],{"class":3798},[3373,10160,10162],{"className":3625,"code":10161,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 404 Not Found\nContent-Type: application\u002Fjson\n\n{\n  \"error\": \"Not Found\",\n  \"message\": \"Користувача з ID 42 не існує\"\n}\n",[3380,10163,10164,10176,10184,10188,10192,10203,10213],{"__ignoreMap":3378},[3383,10165,10166,10168,10170,10172,10174],{"class":3385,"line":3386},[3383,10167,3334],{"class":3780},[3383,10169,3783],{"class":3637},[3383,10171,3946],{"class":3786},[3383,10173,7561],{"class":3786},[3383,10175,7564],{"class":3798},[3383,10177,10178,10180,10182],{"class":3385,"line":3392},[3383,10179,3730],{"class":3657},[3383,10181,3795],{"class":3780},[3383,10183,6150],{"class":3798},[3383,10185,10186],{"class":3385,"line":3398},[3383,10187,3408],{"emptyLinePlaceholder":3407},[3383,10189,10190],{"class":3385,"line":3404},[3383,10191,5292],{"class":3637},[3383,10193,10194,10197,10199,10201],{"class":3385,"line":3411},[3383,10195,10196],{"class":6434},"  \"error\"",[3383,10198,6438],{"class":3637},[3383,10200,7600],{"class":3798},[3383,10202,5305],{"class":3637},[3383,10204,10205,10208,10210],{"class":3385,"line":3417},[3383,10206,10207],{"class":6434},"  \"message\"",[3383,10209,6438],{"class":3637},[3383,10211,10212],{"class":3798},"\"Користувача з ID 42 не існує\"\n",[3383,10214,10215],{"class":3385,"line":3423},[3383,10216,4091],{"class":3637},[3317,10218,10219],{},[3321,10220,10221],{},"Приклад 3: М'яке видалення (soft delete)",[3373,10223,10225],{"className":3625,"code":10224,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fposts\u002F15 HTTP\u002F1.1\nHost: api.example.com\n",[3380,10226,10227,10240],{"__ignoreMap":3378},[3383,10228,10229,10231,10234,10236,10238],{"class":3385,"line":3386},[3383,10230,7467],{"class":3634},[3383,10232,10233],{"class":3637}," \u002Fapi\u002Fposts\u002F15 ",[3383,10235,3334],{"class":3780},[3383,10237,3783],{"class":3637},[3383,10239,3907],{"class":3786},[3383,10241,10242,10244,10246],{"class":3385,"line":3392},[3383,10243,3884],{"class":3657},[3383,10245,3795],{"class":3780},[3383,10247,6141],{"class":3798},[3373,10249,10251],{"className":3625,"code":10250,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\n  \"id\": 15,\n  \"deleted\": true,\n  \"deleted_at\": \"2026-05-17T10:15:00Z\"\n}\n",[3380,10252,10253,10265,10273,10277,10281,10292,10304,10314],{"__ignoreMap":3378},[3383,10254,10255,10257,10259,10261,10263],{"class":3385,"line":3386},[3383,10256,3334],{"class":3780},[3383,10258,3783],{"class":3637},[3383,10260,3946],{"class":3786},[3383,10262,3816],{"class":3786},[3383,10264,3819],{"class":3798},[3383,10266,10267,10269,10271],{"class":3385,"line":3392},[3383,10268,3730],{"class":3657},[3383,10270,3795],{"class":3780},[3383,10272,6150],{"class":3798},[3383,10274,10275],{"class":3385,"line":3398},[3383,10276,3408],{"emptyLinePlaceholder":3407},[3383,10278,10279],{"class":3385,"line":3404},[3383,10280,5292],{"class":3637},[3383,10282,10283,10285,10287,10290],{"class":3385,"line":3411},[3383,10284,6898],{"class":6434},[3383,10286,6438],{"class":3637},[3383,10288,10289],{"class":3786},"15",[3383,10291,5305],{"class":3637},[3383,10293,10294,10297,10299,10302],{"class":3385,"line":3417},[3383,10295,10296],{"class":6434},"  \"deleted\"",[3383,10298,6438],{"class":3637},[3383,10300,10301],{"class":3780},"true",[3383,10303,5305],{"class":3637},[3383,10305,10306,10309,10311],{"class":3385,"line":3423},[3383,10307,10308],{"class":6434},"  \"deleted_at\"",[3383,10310,6438],{"class":3637},[3383,10312,10313],{"class":3798},"\"2026-05-17T10:15:00Z\"\n",[3383,10315,10316],{"class":3385,"line":3429},[3383,10317,4091],{"class":3637},[3317,10319,10320],{},[3321,10321,8904],{},[3719,10323,10324,10327,10330],{},[3722,10325,10326],{},"Видалення ресурсу",[3722,10328,10329],{},"Скасування підписки, відкликання токену",[3722,10331,10332],{},"Очищення сесії (logout)",[8496,10334,10337,10349,10354,10379,10431,10436,10441,10468,10513,10520,10524],{"icon":10335,"label":10336},"i-lucide-list","HEAD — заголовки без тіла",[3317,10338,10339,10341,10342,10344,10345,10348],{},[3380,10340,3750],{}," ідентичний ",[3380,10343,3621],{},", але сервер ",[3321,10346,10347],{},"не надсилає тіло відповіді",". Всі заголовки — ті самі.",[3317,10350,10351],{},[3321,10352,10353],{},"Приклад 1: Перевірка існування ресурсу",[3373,10355,10357],{"className":3625,"code":10356,"language":3627,"meta":3378,"style":3378},"HEAD \u002Fapi\u002Fusers\u002F42 HTTP\u002F1.1\nHost: api.example.com\n",[3380,10358,10359,10371],{"__ignoreMap":3378},[3383,10360,10361,10363,10365,10367,10369],{"class":3385,"line":3386},[3383,10362,3750],{"class":3634},[3383,10364,6764],{"class":3637},[3383,10366,3334],{"class":3780},[3383,10368,3783],{"class":3637},[3383,10370,3907],{"class":3786},[3383,10372,10373,10375,10377],{"class":3385,"line":3392},[3383,10374,3884],{"class":3657},[3383,10376,3795],{"class":3780},[3383,10378,6141],{"class":3798},[3373,10380,10382],{"className":3625,"code":10381,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\nContent-Length: 284\nLast-Modified: Mon, 12 May 2026 08:00:00 GMT\nETag: \"a3f8b2c1\"\n",[3380,10383,10384,10396,10404,10413,10423],{"__ignoreMap":3378},[3383,10385,10386,10388,10390,10392,10394],{"class":3385,"line":3386},[3383,10387,3334],{"class":3780},[3383,10389,3783],{"class":3637},[3383,10391,3946],{"class":3786},[3383,10393,3816],{"class":3786},[3383,10395,3819],{"class":3798},[3383,10397,10398,10400,10402],{"class":3385,"line":3392},[3383,10399,3730],{"class":3657},[3383,10401,3795],{"class":3780},[3383,10403,6150],{"class":3798},[3383,10405,10406,10408,10410],{"class":3385,"line":3398},[3383,10407,3734],{"class":3657},[3383,10409,3795],{"class":3780},[3383,10411,10412],{"class":3798}," 284\n",[3383,10414,10415,10418,10420],{"class":3385,"line":3404},[3383,10416,10417],{"class":3657},"Last-Modified",[3383,10419,3795],{"class":3780},[3383,10421,10422],{"class":3798}," Mon, 12 May 2026 08:00:00 GMT\n",[3383,10424,10425,10427,10429],{"class":3385,"line":3411},[3383,10426,6871],{"class":3657},[3383,10428,3795],{"class":3780},[3383,10430,6876],{"class":3798},[3317,10432,10433],{},[3337,10434,10435],{},"(тіло відсутнє)",[3317,10437,10438],{},[3321,10439,10440],{},"Приклад 2: Розмір файлу перед завантаженням",[3373,10442,10444],{"className":3625,"code":10443,"language":3627,"meta":3378,"style":3378},"HEAD \u002Ffiles\u002Freport-2026.pdf HTTP\u002F1.1\nHost: files.example.com\n",[3380,10445,10446,10459],{"__ignoreMap":3378},[3383,10447,10448,10450,10453,10455,10457],{"class":3385,"line":3386},[3383,10449,3750],{"class":3634},[3383,10451,10452],{"class":3637}," \u002Ffiles\u002Freport-2026.pdf ",[3383,10454,3334],{"class":3780},[3383,10456,3783],{"class":3637},[3383,10458,3907],{"class":3786},[3383,10460,10461,10463,10465],{"class":3385,"line":3392},[3383,10462,3884],{"class":3657},[3383,10464,3795],{"class":3780},[3383,10466,10467],{"class":3798}," files.example.com\n",[3373,10469,10471],{"className":3625,"code":10470,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fpdf\nContent-Length: 5242880\nAccept-Ranges: bytes\n",[3380,10472,10473,10485,10494,10503],{"__ignoreMap":3378},[3383,10474,10475,10477,10479,10481,10483],{"class":3385,"line":3386},[3383,10476,3334],{"class":3780},[3383,10478,3783],{"class":3637},[3383,10480,3946],{"class":3786},[3383,10482,3816],{"class":3786},[3383,10484,3819],{"class":3798},[3383,10486,10487,10489,10491],{"class":3385,"line":3392},[3383,10488,3730],{"class":3657},[3383,10490,3795],{"class":3780},[3383,10492,10493],{"class":3798}," application\u002Fpdf\n",[3383,10495,10496,10498,10500],{"class":3385,"line":3398},[3383,10497,3734],{"class":3657},[3383,10499,3795],{"class":3780},[3383,10501,10502],{"class":3798}," 5242880\n",[3383,10504,10505,10508,10510],{"class":3385,"line":3404},[3383,10506,10507],{"class":3657},"Accept-Ranges",[3383,10509,3795],{"class":3780},[3383,10511,10512],{"class":3798}," bytes\n",[3317,10514,10515,10516,10519],{},"Клієнт бачить: файл 5MB, підтримує ",[3380,10517,10518],{},"Range"," — можна завантажувати по частинах.",[3317,10521,10522],{},[3321,10523,8904],{},[3719,10525,10526,10529,10535,10542],{},[3722,10527,10528],{},"Перевірка існування ресурсу без завантаження",[3722,10530,10531,10532,10534],{},"Отримання ",[3380,10533,3734],{}," перед завантаженням",[3722,10536,10537,10538,3731,10540,4902],{},"Перевірка актуальності кешу (",[3380,10539,6871],{},[3380,10541,10417],{},[3722,10543,10544],{},"Легкий health check",[8496,10546,10549,10554,10559,10584,10611,10616,10672,10738,10742],{"icon":10547,"label":10548},"i-lucide-settings","OPTIONS — можливості та CORS preflight",[3317,10550,10551,10553],{},[3380,10552,8381],{}," повертає список підтримуваних методів для ресурсу.",[3317,10555,10556],{},[3321,10557,10558],{},"Приклад 1: Запит можливостей ресурсу",[3373,10560,10562],{"className":3625,"code":10561,"language":3627,"meta":3378,"style":3378},"OPTIONS \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\n",[3380,10563,10564,10576],{"__ignoreMap":3378},[3383,10565,10566,10568,10570,10572,10574],{"class":3385,"line":3386},[3383,10567,8381],{"class":3634},[3383,10569,7056],{"class":3637},[3383,10571,3334],{"class":3780},[3383,10573,3783],{"class":3637},[3383,10575,3907],{"class":3786},[3383,10577,10578,10580,10582],{"class":3385,"line":3392},[3383,10579,3884],{"class":3657},[3383,10581,3795],{"class":3780},[3383,10583,6141],{"class":3798},[3373,10585,10587],{"className":3625,"code":10586,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 204 No Content\nAllow: GET, POST, HEAD, OPTIONS\n",[3380,10588,10589,10601],{"__ignoreMap":3378},[3383,10590,10591,10593,10595,10597,10599],{"class":3385,"line":3386},[3383,10592,3334],{"class":3780},[3383,10594,3783],{"class":3637},[3383,10596,3946],{"class":3786},[3383,10598,7500],{"class":3786},[3383,10600,7503],{"class":3798},[3383,10602,10603,10606,10608],{"class":3385,"line":3392},[3383,10604,10605],{"class":3657},"Allow",[3383,10607,3795],{"class":3780},[3383,10609,10610],{"class":3798}," GET, POST, HEAD, OPTIONS\n",[3317,10612,10613],{},[3321,10614,10615],{},"Приклад 2: CORS Preflight",[3373,10617,10619],{"className":3625,"code":10618,"language":3627,"meta":3378,"style":3378},"OPTIONS \u002Fapi\u002Forders HTTP\u002F1.1\nHost: api.example.com\nOrigin: https:\u002F\u002Fapp.example.com\nAccess-Control-Request-Method: POST\nAccess-Control-Request-Headers: Authorization, Content-Type\n",[3380,10620,10621,10634,10642,10652,10662],{"__ignoreMap":3378},[3383,10622,10623,10625,10628,10630,10632],{"class":3385,"line":3386},[3383,10624,8381],{"class":3634},[3383,10626,10627],{"class":3637}," \u002Fapi\u002Forders ",[3383,10629,3334],{"class":3780},[3383,10631,3783],{"class":3637},[3383,10633,3907],{"class":3786},[3383,10635,10636,10638,10640],{"class":3385,"line":3392},[3383,10637,3884],{"class":3657},[3383,10639,3795],{"class":3780},[3383,10641,6141],{"class":3798},[3383,10643,10644,10647,10649],{"class":3385,"line":3398},[3383,10645,10646],{"class":3657},"Origin",[3383,10648,3795],{"class":3780},[3383,10650,10651],{"class":3798}," https:\u002F\u002Fapp.example.com\n",[3383,10653,10654,10657,10659],{"class":3385,"line":3404},[3383,10655,10656],{"class":3657},"Access-Control-Request-Method",[3383,10658,3795],{"class":3780},[3383,10660,10661],{"class":3798}," POST\n",[3383,10663,10664,10667,10669],{"class":3385,"line":3411},[3383,10665,10666],{"class":3657},"Access-Control-Request-Headers",[3383,10668,3795],{"class":3780},[3383,10670,10671],{"class":3798}," Authorization, Content-Type\n",[3373,10673,10675],{"className":3625,"code":10674,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 204 No Content\nAccess-Control-Allow-Origin: https:\u002F\u002Fapp.example.com\nAccess-Control-Allow-Methods: GET, POST, PUT, DELETE, PATCH\nAccess-Control-Allow-Headers: Authorization, Content-Type, X-Request-Id\nAccess-Control-Max-Age: 86400\nVary: Origin\n",[3380,10676,10677,10689,10698,10708,10718,10728],{"__ignoreMap":3378},[3383,10678,10679,10681,10683,10685,10687],{"class":3385,"line":3386},[3383,10680,3334],{"class":3780},[3383,10682,3783],{"class":3637},[3383,10684,3946],{"class":3786},[3383,10686,7500],{"class":3786},[3383,10688,7503],{"class":3798},[3383,10690,10691,10694,10696],{"class":3385,"line":3392},[3383,10692,10693],{"class":3657},"Access-Control-Allow-Origin",[3383,10695,3795],{"class":3780},[3383,10697,10651],{"class":3798},[3383,10699,10700,10703,10705],{"class":3385,"line":3398},[3383,10701,10702],{"class":3657},"Access-Control-Allow-Methods",[3383,10704,3795],{"class":3780},[3383,10706,10707],{"class":3798}," GET, POST, PUT, DELETE, PATCH\n",[3383,10709,10710,10713,10715],{"class":3385,"line":3404},[3383,10711,10712],{"class":3657},"Access-Control-Allow-Headers",[3383,10714,3795],{"class":3780},[3383,10716,10717],{"class":3798}," Authorization, Content-Type, X-Request-Id\n",[3383,10719,10720,10723,10725],{"class":3385,"line":3411},[3383,10721,10722],{"class":3657},"Access-Control-Max-Age",[3383,10724,3795],{"class":3780},[3383,10726,10727],{"class":3798}," 86400\n",[3383,10729,10730,10733,10735],{"class":3385,"line":3417},[3383,10731,10732],{"class":3657},"Vary",[3383,10734,3795],{"class":3780},[3383,10736,10737],{"class":3798}," Origin\n",[3317,10739,10740],{},[3321,10741,8904],{},[3719,10743,10744,10747,10750],{},[3722,10745,10746],{},"Автоматично браузером (CORS preflight) — без вашої участі",[3722,10748,10749],{},"Документування API",[3722,10751,10752],{},"Реалізація CORS-middleware на сервері",[3360,10754],{},[3312,10756,10758],{"id":10757},"http-status-codes-всі-пять-класів","HTTP Status Codes: всі п'ять класів",[3317,10760,10761,10762,10765],{},"Статус-код — це числова відповідь сервера, що однозначно вказує на результат обробки запиту. Перша цифра визначає ",[3321,10763,10764],{},"клас"," відповіді, наступні дві — конкретний код.",[3370,10767,10768],{},[3373,10769,10771],{"className":3375,"code":10770,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nstate \"HTTP Response\" as root {\n    state \"1xx\\nInformational\" as s1xx #e3f2fd\n    state \"2xx\\nSuccess\" as s2xx #e8f5e9\n    state \"3xx\\nRedirection\" as s3xx #fff9c4\n    state \"4xx\\nClient Error\" as s4xx #fce4ec\n    state \"5xx\\nServer Error\" as s5xx #f3e5f5\n\n    [*] --> s1xx : Запит отримано,\\nпродовжуємо\n    [*] --> s2xx : Успіх\n    [*] --> s3xx : Потрібне\\nперенаправлення\n    [*] --> s4xx : Помилка\\nклієнта\n    [*] --> s5xx : Помилка\\nсервера\n}\n\nnote right of s1xx\n  100 Continue\n  101 Switching Protocols\n  103 Early Hints\nend note\n\nnote right of s2xx\n  200 OK\n  201 Created\n  204 No Content\n  206 Partial Content\nend note\n\nnote right of s3xx\n  301 Moved Permanently\n  302 Found\n  304 Not Modified\n  307 Temporary Redirect\n  308 Permanent Redirect\nend note\n\nnote right of s4xx\n  400 Bad Request\n  401 Unauthorized\n  403 Forbidden\n  404 Not Found\n  409 Conflict\n  422 Unprocessable Entity\n  429 Too Many Requests\nend note\n\nnote right of s5xx\n  500 Internal Server Error\n  502 Bad Gateway\n  503 Service Unavailable\n  504 Gateway Timeout\nend note\n\n@enduml\n",[3380,10772,10773,10777,10781,10785,10789,10794,10799,10804,10809,10814,10819,10823,10828,10833,10838,10843,10848,10852,10856,10861,10866,10871,10876,10880,10884,10889,10894,10899,10904,10909,10913,10917,10922,10927,10932,10937,10942,10947,10951,10955,10960,10965,10970,10975,10980,10985,10990,10995,10999,11003,11008,11013,11018,11023,11028,11032,11036],{"__ignoreMap":3378},[3383,10774,10775],{"class":3385,"line":3386},[3383,10776,4064],{},[3383,10778,10779],{"class":3385,"line":3392},[3383,10780,3395],{},[3383,10782,10783],{"class":3385,"line":3398},[3383,10784,3401],{},[3383,10786,10787],{"class":3385,"line":3404},[3383,10788,3408],{"emptyLinePlaceholder":3407},[3383,10790,10791],{"class":3385,"line":3411},[3383,10792,10793],{},"state \"HTTP Response\" as root {\n",[3383,10795,10796],{"class":3385,"line":3417},[3383,10797,10798],{},"    state \"1xx\\nInformational\" as s1xx #e3f2fd\n",[3383,10800,10801],{"class":3385,"line":3423},[3383,10802,10803],{},"    state \"2xx\\nSuccess\" as s2xx #e8f5e9\n",[3383,10805,10806],{"class":3385,"line":3429},[3383,10807,10808],{},"    state \"3xx\\nRedirection\" as s3xx #fff9c4\n",[3383,10810,10811],{"class":3385,"line":3435},[3383,10812,10813],{},"    state \"4xx\\nClient Error\" as s4xx #fce4ec\n",[3383,10815,10816],{"class":3385,"line":3441},[3383,10817,10818],{},"    state \"5xx\\nServer Error\" as s5xx #f3e5f5\n",[3383,10820,10821],{"class":3385,"line":3447},[3383,10822,3408],{"emptyLinePlaceholder":3407},[3383,10824,10825],{"class":3385,"line":3453},[3383,10826,10827],{},"    [*] --> s1xx : Запит отримано,\\nпродовжуємо\n",[3383,10829,10830],{"class":3385,"line":3459},[3383,10831,10832],{},"    [*] --> s2xx : Успіх\n",[3383,10834,10835],{"class":3385,"line":3465},[3383,10836,10837],{},"    [*] --> s3xx : Потрібне\\nперенаправлення\n",[3383,10839,10840],{"class":3385,"line":3471},[3383,10841,10842],{},"    [*] --> s4xx : Помилка\\nклієнта\n",[3383,10844,10845],{"class":3385,"line":3477},[3383,10846,10847],{},"    [*] --> s5xx : Помилка\\nсервера\n",[3383,10849,10850],{"class":3385,"line":3483},[3383,10851,4091],{},[3383,10853,10854],{"class":3385,"line":3489},[3383,10855,3408],{"emptyLinePlaceholder":3407},[3383,10857,10858],{"class":3385,"line":3495},[3383,10859,10860],{},"note right of s1xx\n",[3383,10862,10863],{"class":3385,"line":3501},[3383,10864,10865],{},"  100 Continue\n",[3383,10867,10868],{"class":3385,"line":3507},[3383,10869,10870],{},"  101 Switching Protocols\n",[3383,10872,10873],{"class":3385,"line":3513},[3383,10874,10875],{},"  103 Early Hints\n",[3383,10877,10878],{"class":3385,"line":3519},[3383,10879,4193],{},[3383,10881,10882],{"class":3385,"line":3525},[3383,10883,3408],{"emptyLinePlaceholder":3407},[3383,10885,10886],{"class":3385,"line":3531},[3383,10887,10888],{},"note right of s2xx\n",[3383,10890,10891],{"class":3385,"line":3537},[3383,10892,10893],{},"  200 OK\n",[3383,10895,10896],{"class":3385,"line":3543},[3383,10897,10898],{},"  201 Created\n",[3383,10900,10901],{"class":3385,"line":3549},[3383,10902,10903],{},"  204 No Content\n",[3383,10905,10906],{"class":3385,"line":3555},[3383,10907,10908],{},"  206 Partial Content\n",[3383,10910,10911],{"class":3385,"line":3561},[3383,10912,4193],{},[3383,10914,10915],{"class":3385,"line":3567},[3383,10916,3408],{"emptyLinePlaceholder":3407},[3383,10918,10919],{"class":3385,"line":3573},[3383,10920,10921],{},"note right of s3xx\n",[3383,10923,10924],{"class":3385,"line":3579},[3383,10925,10926],{},"  301 Moved Permanently\n",[3383,10928,10929],{"class":3385,"line":4215},[3383,10930,10931],{},"  302 Found\n",[3383,10933,10934],{"class":3385,"line":4220},[3383,10935,10936],{},"  304 Not Modified\n",[3383,10938,10939],{"class":3385,"line":4225},[3383,10940,10941],{},"  307 Temporary Redirect\n",[3383,10943,10944],{"class":3385,"line":4231},[3383,10945,10946],{},"  308 Permanent Redirect\n",[3383,10948,10949],{"class":3385,"line":4237},[3383,10950,4193],{},[3383,10952,10953],{"class":3385,"line":4243},[3383,10954,3408],{"emptyLinePlaceholder":3407},[3383,10956,10957],{"class":3385,"line":4248},[3383,10958,10959],{},"note right of s4xx\n",[3383,10961,10962],{"class":3385,"line":4253},[3383,10963,10964],{},"  400 Bad Request\n",[3383,10966,10967],{"class":3385,"line":4259},[3383,10968,10969],{},"  401 Unauthorized\n",[3383,10971,10972],{"class":3385,"line":4265},[3383,10973,10974],{},"  403 Forbidden\n",[3383,10976,10977],{"class":3385,"line":4271},[3383,10978,10979],{},"  404 Not Found\n",[3383,10981,10982],{"class":3385,"line":4276},[3383,10983,10984],{},"  409 Conflict\n",[3383,10986,10987],{"class":3385,"line":4281},[3383,10988,10989],{},"  422 Unprocessable Entity\n",[3383,10991,10992],{"class":3385,"line":4540},[3383,10993,10994],{},"  429 Too Many Requests\n",[3383,10996,10997],{"class":3385,"line":4545},[3383,10998,4193],{},[3383,11000,11001],{"class":3385,"line":4551},[3383,11002,3408],{"emptyLinePlaceholder":3407},[3383,11004,11005],{"class":3385,"line":4557},[3383,11006,11007],{},"note right of s5xx\n",[3383,11009,11010],{"class":3385,"line":4563},[3383,11011,11012],{},"  500 Internal Server Error\n",[3383,11014,11015],{"class":3385,"line":4569},[3383,11016,11017],{},"  502 Bad Gateway\n",[3383,11019,11020],{"class":3385,"line":4574},[3383,11021,11022],{},"  503 Service Unavailable\n",[3383,11024,11025],{"class":3385,"line":4579},[3383,11026,11027],{},"  504 Gateway Timeout\n",[3383,11029,11030],{"class":3385,"line":4585},[3383,11031,4193],{},[3383,11033,11034],{"class":3385,"line":4591},[3383,11035,3408],{"emptyLinePlaceholder":3407},[3383,11037,11038],{"class":3385,"line":4597},[3383,11039,4284],{},[3599,11041,11043],{"id":11042},"_1xx-інформаційні","1xx — Інформаційні",[7824,11045,11046,11126],{},[7827,11047,11050,11057,11102,11121],{"icon":11048,"title":11049},"i-lucide-arrow-right","100 Continue",[3317,11051,11052,11053,11056],{},"Сервер отримав заголовки запиту і клієнт може надіслати тіло. Використовується з заголовком ",[3380,11054,11055],{},"Expect: 100-continue"," для великих запитів — клієнт «запитує дозвіл» перед відправкою великого тіла.",[3373,11058,11060],{"className":3625,"code":11059,"language":3627,"meta":3378,"style":3378},"POST \u002Fupload HTTP\u002F1.1\nHost: api.example.com\nContent-Length: 10485760\nExpect: 100-continue\n",[3380,11061,11062,11075,11083,11092],{"__ignoreMap":3378},[3383,11063,11064,11066,11069,11071,11073],{"class":3385,"line":3386},[3383,11065,3746],{"class":3634},[3383,11067,11068],{"class":3637}," \u002Fupload ",[3383,11070,3334],{"class":3780},[3383,11072,3783],{"class":3637},[3383,11074,3907],{"class":3786},[3383,11076,11077,11079,11081],{"class":3385,"line":3392},[3383,11078,3884],{"class":3657},[3383,11080,3795],{"class":3780},[3383,11082,6141],{"class":3798},[3383,11084,11085,11087,11089],{"class":3385,"line":3398},[3383,11086,3734],{"class":3657},[3383,11088,3795],{"class":3780},[3383,11090,11091],{"class":3798}," 10485760\n",[3383,11093,11094,11097,11099],{"class":3385,"line":3404},[3383,11095,11096],{"class":3657},"Expect",[3383,11098,3795],{"class":3780},[3383,11100,11101],{"class":3798}," 100-continue\n",[3373,11103,11105],{"className":3625,"code":11104,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 100 Continue\n",[3380,11106,11107],{"__ignoreMap":3378},[3383,11108,11109,11111,11113,11115,11118],{"class":3385,"line":3386},[3383,11110,3334],{"class":3780},[3383,11112,3783],{"class":3637},[3383,11114,3946],{"class":3786},[3383,11116,11117],{"class":3786}," 100",[3383,11119,11120],{"class":3798}," Continue\n",[3317,11122,11123],{},[3337,11124,11125],{},"(після цього клієнт надсилає 10MB тіла)",[7827,11127,11130,11140,11195],{"icon":11128,"title":11129},"i-lucide-refresh-cw","101 Switching Protocols",[3317,11131,11132,11133,11136,11137,4760],{},"Сервер погоджується змінити протокол відповідно до запиту ",[3380,11134,11135],{},"Upgrade",". Саме ця відповідь завершує HTTP-рукостискання при переході на ",[3321,11138,11139],{},"WebSocket",[3373,11141,11143],{"className":3625,"code":11142,"language":3627,"meta":3378,"style":3378},"GET \u002Fchat HTTP\u002F1.1\nHost: ws.example.com\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\n",[3380,11144,11145,11158,11167,11176,11185],{"__ignoreMap":3378},[3383,11146,11147,11149,11152,11154,11156],{"class":3385,"line":3386},[3383,11148,3621],{"class":3634},[3383,11150,11151],{"class":3637}," \u002Fchat ",[3383,11153,3334],{"class":3780},[3383,11155,3783],{"class":3637},[3383,11157,3907],{"class":3786},[3383,11159,11160,11162,11164],{"class":3385,"line":3392},[3383,11161,3884],{"class":3657},[3383,11163,3795],{"class":3780},[3383,11165,11166],{"class":3798}," ws.example.com\n",[3383,11168,11169,11171,11173],{"class":3385,"line":3398},[3383,11170,11135],{"class":3657},[3383,11172,3795],{"class":3780},[3383,11174,11175],{"class":3798}," websocket\n",[3383,11177,11178,11180,11182],{"class":3385,"line":3404},[3383,11179,3921],{"class":3657},[3383,11181,3795],{"class":3780},[3383,11183,11184],{"class":3798}," Upgrade\n",[3383,11186,11187,11190,11192],{"class":3385,"line":3411},[3383,11188,11189],{"class":3657},"Sec-WebSocket-Key",[3383,11191,3795],{"class":3780},[3383,11193,11194],{"class":3798}," dGhlIHNhbXBsZSBub25jZQ==\n",[3373,11196,11198],{"className":3625,"code":11197,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 101 Switching Protocols\nUpgrade: websocket\nConnection: Upgrade\nSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\n",[3380,11199,11200,11214,11222,11230],{"__ignoreMap":3378},[3383,11201,11202,11204,11206,11208,11211],{"class":3385,"line":3386},[3383,11203,3334],{"class":3780},[3383,11205,3783],{"class":3637},[3383,11207,3946],{"class":3786},[3383,11209,11210],{"class":3786}," 101",[3383,11212,11213],{"class":3798}," Switching Protocols\n",[3383,11215,11216,11218,11220],{"class":3385,"line":3392},[3383,11217,11135],{"class":3657},[3383,11219,3795],{"class":3780},[3383,11221,11175],{"class":3798},[3383,11223,11224,11226,11228],{"class":3385,"line":3398},[3383,11225,3921],{"class":3657},[3383,11227,3795],{"class":3780},[3383,11229,11184],{"class":3798},[3383,11231,11232,11235,11237],{"class":3385,"line":3404},[3383,11233,11234],{"class":3657},"Sec-WebSocket-Accept",[3383,11236,3795],{"class":3780},[3383,11238,11239],{"class":3798}," s3pPLMBiTxaQ9kYGzzhZRbK+xOo=\n",[3599,11241,11243],{"id":11242},"_2xx-успішні","2xx — Успішні",[7824,11245,11246,11340,11477,11535],{},[7827,11247,11249,11258,11283],{"icon":11248,"title":6823},"i-lucide-check",[3317,11250,11251,11252,11254,11255,11257],{},"Стандартна успішна відповідь. Тіло залежить від методу: для ",[3380,11253,3621],{}," — запитаний ресурс, для ",[3380,11256,3746],{}," — результат дії.",[3373,11259,11261],{"className":3625,"code":11260,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\n",[3380,11262,11263,11275],{"__ignoreMap":3378},[3383,11264,11265,11267,11269,11271,11273],{"class":3385,"line":3386},[3383,11266,3621],{"class":3634},[3383,11268,8678],{"class":3637},[3383,11270,3334],{"class":3780},[3383,11272,3783],{"class":3637},[3383,11274,3907],{"class":3786},[3383,11276,11277,11279,11281],{"class":3385,"line":3392},[3383,11278,3884],{"class":3657},[3383,11280,3795],{"class":3780},[3383,11282,6141],{"class":3798},[3373,11284,11286],{"className":3625,"code":11285,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 200 OK\nContent-Type: application\u002Fjson\n\n{\"id\": 1, \"name\": \"Іван\", \"email\": \"ivan@example.com\"}\n",[3380,11287,11288,11300,11308,11312],{"__ignoreMap":3378},[3383,11289,11290,11292,11294,11296,11298],{"class":3385,"line":3386},[3383,11291,3334],{"class":3780},[3383,11293,3783],{"class":3637},[3383,11295,3946],{"class":3786},[3383,11297,3816],{"class":3786},[3383,11299,3819],{"class":3798},[3383,11301,11302,11304,11306],{"class":3385,"line":3392},[3383,11303,3730],{"class":3657},[3383,11305,3795],{"class":3780},[3383,11307,6150],{"class":3798},[3383,11309,11310],{"class":3385,"line":3398},[3383,11311,3408],{"emptyLinePlaceholder":3407},[3383,11313,11314,11316,11318,11320,11322,11324,11326,11328,11330,11332,11334,11336,11338],{"class":3385,"line":3404},[3383,11315,5466],{"class":3637},[3383,11317,6435],{"class":6434},[3383,11319,6438],{"class":3637},[3383,11321,5316],{"class":3786},[3383,11323,3731],{"class":3637},[3383,11325,6445],{"class":6434},[3383,11327,6438],{"class":3637},[3383,11329,8629],{"class":3798},[3383,11331,3731],{"class":3637},[3383,11333,6455],{"class":6434},[3383,11335,6438],{"class":3637},[3383,11337,9161],{"class":3798},[3383,11339,4091],{"class":3637},[7827,11341,11343,11353,11410],{"icon":11342,"title":7150},"i-lucide-plus-circle",[3317,11344,11345,11346,11349,11350,11352],{},"Ресурс успішно ",[3321,11347,11348],{},"створено",". Обов'язково містить заголовок ",[3380,11351,7191],{}," з URL нового ресурсу.",[3373,11354,11356],{"className":3625,"code":11355,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\"name\": \"Марія\", \"email\": \"maria@example.com\"}\n",[3380,11357,11358,11370,11378,11386,11390],{"__ignoreMap":3378},[3383,11359,11360,11362,11364,11366,11368],{"class":3385,"line":3386},[3383,11361,3746],{"class":3634},[3383,11363,7056],{"class":3637},[3383,11365,3334],{"class":3780},[3383,11367,3783],{"class":3637},[3383,11369,3907],{"class":3786},[3383,11371,11372,11374,11376],{"class":3385,"line":3392},[3383,11373,3884],{"class":3657},[3383,11375,3795],{"class":3780},[3383,11377,6141],{"class":3798},[3383,11379,11380,11382,11384],{"class":3385,"line":3398},[3383,11381,3730],{"class":3657},[3383,11383,3795],{"class":3780},[3383,11385,6150],{"class":3798},[3383,11387,11388],{"class":3385,"line":3404},[3383,11389,3408],{"emptyLinePlaceholder":3407},[3383,11391,11392,11394,11396,11398,11400,11402,11404,11406,11408],{"class":3385,"line":3411},[3383,11393,5466],{"class":3637},[3383,11395,6445],{"class":6434},[3383,11397,6438],{"class":3637},[3383,11399,8650],{"class":3798},[3383,11401,3731],{"class":3637},[3383,11403,6455],{"class":6434},[3383,11405,6438],{"class":3637},[3383,11407,7123],{"class":3798},[3383,11409,4091],{"class":3637},[3373,11411,11413],{"className":3625,"code":11412,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 201 Created\nLocation: \u002Fapi\u002Fusers\u002F44\nContent-Type: application\u002Fjson\n\n{\"id\": 44, \"name\": \"Марія\", \"email\": \"maria@example.com\"}\n",[3380,11414,11415,11427,11436,11444,11448],{"__ignoreMap":3378},[3383,11416,11417,11419,11421,11423,11425],{"class":3385,"line":3386},[3383,11418,3334],{"class":3780},[3383,11420,3783],{"class":3637},[3383,11422,3946],{"class":3786},[3383,11424,7166],{"class":3786},[3383,11426,7169],{"class":3798},[3383,11428,11429,11431,11433],{"class":3385,"line":3392},[3383,11430,7191],{"class":3657},[3383,11432,3795],{"class":3780},[3383,11434,11435],{"class":3798}," \u002Fapi\u002Fusers\u002F44\n",[3383,11437,11438,11440,11442],{"class":3385,"line":3398},[3383,11439,3730],{"class":3657},[3383,11441,3795],{"class":3780},[3383,11443,6150],{"class":3798},[3383,11445,11446],{"class":3385,"line":3404},[3383,11447,3408],{"emptyLinePlaceholder":3407},[3383,11449,11450,11452,11454,11456,11459,11461,11463,11465,11467,11469,11471,11473,11475],{"class":3385,"line":3411},[3383,11451,5466],{"class":3637},[3383,11453,6435],{"class":6434},[3383,11455,6438],{"class":3637},[3383,11457,11458],{"class":3786},"44",[3383,11460,3731],{"class":3637},[3383,11462,6445],{"class":6434},[3383,11464,6438],{"class":3637},[3383,11466,8650],{"class":3798},[3383,11468,3731],{"class":3637},[3383,11470,6455],{"class":6434},[3383,11472,6438],{"class":3637},[3383,11474,7123],{"class":3798},[3383,11476,4091],{"class":3637},[7827,11478,11480,11493,11519],{"icon":11479,"title":7517},"i-lucide-minus-circle",[3317,11481,11482,11483,11485,11486,4775,11488,3783,11490,11492],{},"Успіх, але ",[3321,11484,6956],{}," відповіді. Типово для ",[3380,11487,7467],{},[3380,11489,8412],{},[3380,11491,8428],{}," без поверненого ресурсу.",[3373,11494,11496],{"className":3625,"code":11495,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fusers\u002F44 HTTP\u002F1.1\nHost: api.example.com\n",[3380,11497,11498,11511],{"__ignoreMap":3378},[3383,11499,11500,11502,11505,11507,11509],{"class":3385,"line":3386},[3383,11501,7467],{"class":3634},[3383,11503,11504],{"class":3637}," \u002Fapi\u002Fusers\u002F44 ",[3383,11506,3334],{"class":3780},[3383,11508,3783],{"class":3637},[3383,11510,3907],{"class":3786},[3383,11512,11513,11515,11517],{"class":3385,"line":3392},[3383,11514,3884],{"class":3657},[3383,11516,3795],{"class":3780},[3383,11518,6141],{"class":3798},[3373,11520,11521],{"className":3625,"code":10114,"language":3627,"meta":3378,"style":3378},[3380,11522,11523],{"__ignoreMap":3378},[3383,11524,11525,11527,11529,11531,11533],{"class":3385,"line":3386},[3383,11526,3334],{"class":3780},[3383,11528,3783],{"class":3637},[3383,11530,3946],{"class":3786},[3383,11532,7500],{"class":3786},[3383,11534,7503],{"class":3798},[7827,11536,11538,11548,11584],{"icon":8498,"title":11537},"206 Partial Content",[3317,11539,11540,11541,11543,11544,11547],{},"Відповідь на запит з ",[3380,11542,10518],{}," header. Основа для ",[3321,11545,11546],{},"відновлюваних завантажень"," та відео-стрімінгу.",[3373,11549,11551],{"className":3625,"code":11550,"language":3627,"meta":3378,"style":3378},"GET \u002Ffiles\u002Fvideo.mp4 HTTP\u002F1.1\nHost: cdn.example.com\nRange: bytes=0-1048575\n",[3380,11552,11553,11566,11575],{"__ignoreMap":3378},[3383,11554,11555,11557,11560,11562,11564],{"class":3385,"line":3386},[3383,11556,3621],{"class":3634},[3383,11558,11559],{"class":3637}," \u002Ffiles\u002Fvideo.mp4 ",[3383,11561,3334],{"class":3780},[3383,11563,3783],{"class":3637},[3383,11565,3907],{"class":3786},[3383,11567,11568,11570,11572],{"class":3385,"line":3392},[3383,11569,3884],{"class":3657},[3383,11571,3795],{"class":3780},[3383,11573,11574],{"class":3798}," cdn.example.com\n",[3383,11576,11577,11579,11581],{"class":3385,"line":3398},[3383,11578,10518],{"class":3657},[3383,11580,3795],{"class":3780},[3383,11582,11583],{"class":3798}," bytes=0-1048575\n",[3373,11585,11587],{"className":3625,"code":11586,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 206 Partial Content\nContent-Range: bytes 0-1048575\u002F52428800\nContent-Length: 1048576\nContent-Type: video\u002Fmp4\n\n(перший 1MB відео...)\n",[3380,11588,11589,11603,11613,11622,11631,11635],{"__ignoreMap":3378},[3383,11590,11591,11593,11595,11597,11600],{"class":3385,"line":3386},[3383,11592,3334],{"class":3780},[3383,11594,3783],{"class":3637},[3383,11596,3946],{"class":3786},[3383,11598,11599],{"class":3786}," 206",[3383,11601,11602],{"class":3798}," Partial Content\n",[3383,11604,11605,11608,11610],{"class":3385,"line":3392},[3383,11606,11607],{"class":3657},"Content-Range",[3383,11609,3795],{"class":3780},[3383,11611,11612],{"class":3798}," bytes 0-1048575\u002F52428800\n",[3383,11614,11615,11617,11619],{"class":3385,"line":3398},[3383,11616,3734],{"class":3657},[3383,11618,3795],{"class":3780},[3383,11620,11621],{"class":3798}," 1048576\n",[3383,11623,11624,11626,11628],{"class":3385,"line":3404},[3383,11625,3730],{"class":3657},[3383,11627,3795],{"class":3780},[3383,11629,11630],{"class":3798}," video\u002Fmp4\n",[3383,11632,11633],{"class":3385,"line":3411},[3383,11634,3408],{"emptyLinePlaceholder":3407},[3383,11636,11637],{"class":3385,"line":3417},[3383,11638,11639],{"class":3637},"(перший 1MB відео...)\n",[3599,11641,11643],{"id":11642},"_3xx-перенаправлення","3xx — Перенаправлення",[7824,11645,11646,11709,11788,11896],{},[7827,11647,11650,11657,11683],{"icon":11648,"title":11649},"i-lucide-arrow-right-from-line","301 Moved Permanently",[3317,11651,11652,11653,11656],{},"Ресурс ",[3321,11654,11655],{},"назавжди"," переїхав. Браузери та пошукові роботи кешують назавжди.",[3373,11658,11660],{"className":3625,"code":11659,"language":3627,"meta":3378,"style":3378},"GET \u002Fold-path HTTP\u002F1.1\nHost: example.com\n",[3380,11661,11662,11675],{"__ignoreMap":3378},[3383,11663,11664,11666,11669,11671,11673],{"class":3385,"line":3386},[3383,11665,3621],{"class":3634},[3383,11667,11668],{"class":3637}," \u002Fold-path ",[3383,11670,3334],{"class":3780},[3383,11672,3783],{"class":3637},[3383,11674,3907],{"class":3786},[3383,11676,11677,11679,11681],{"class":3385,"line":3392},[3383,11678,3884],{"class":3657},[3383,11680,3795],{"class":3780},[3383,11682,7662],{"class":3798},[3373,11684,11686],{"className":3625,"code":11685,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 301 Moved Permanently\nLocation: https:\u002F\u002Fexample.com\u002Fnew-path\n",[3380,11687,11688,11700],{"__ignoreMap":3378},[3383,11689,11690,11692,11694,11696,11698],{"class":3385,"line":3386},[3383,11691,3334],{"class":3780},[3383,11693,3783],{"class":3637},[3383,11695,3946],{"class":3786},[3383,11697,7678],{"class":3786},[3383,11699,7681],{"class":3798},[3383,11701,11702,11704,11706],{"class":3385,"line":3392},[3383,11703,7191],{"class":3657},[3383,11705,3795],{"class":3780},[3383,11707,11708],{"class":3798}," https:\u002F\u002Fexample.com\u002Fnew-path\n",[7827,11710,11713,11719,11754],{"icon":11711,"title":11712},"i-lucide-save","304 Not Modified",[3317,11714,11652,11715,11718],{},[3321,11716,11717],{},"не змінився"," — клієнт використовує кешовану версію (тіло відсутнє).",[3373,11720,11722],{"className":3625,"code":11721,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fproducts HTTP\u002F1.1\nHost: api.example.com\nIf-None-Match: \"v5-abc123\"\n",[3380,11723,11724,11737,11745],{"__ignoreMap":3378},[3383,11725,11726,11728,11731,11733,11735],{"class":3385,"line":3386},[3383,11727,3621],{"class":3634},[3383,11729,11730],{"class":3637}," \u002Fapi\u002Fproducts ",[3383,11732,3334],{"class":3780},[3383,11734,3783],{"class":3637},[3383,11736,3907],{"class":3786},[3383,11738,11739,11741,11743],{"class":3385,"line":3392},[3383,11740,3884],{"class":3657},[3383,11742,3795],{"class":3780},[3383,11744,6141],{"class":3798},[3383,11746,11747,11749,11751],{"class":3385,"line":3398},[3383,11748,6952],{"class":3657},[3383,11750,3795],{"class":3780},[3383,11752,11753],{"class":3798}," \"v5-abc123\"\n",[3373,11755,11757],{"className":3625,"code":11756,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 304 Not Modified\nETag: \"v5-abc123\"\nCache-Control: max-age=60\n",[3380,11758,11759,11771,11779],{"__ignoreMap":3378},[3383,11760,11761,11763,11765,11767,11769],{"class":3385,"line":3386},[3383,11762,3334],{"class":3780},[3383,11764,3783],{"class":3637},[3383,11766,3946],{"class":3786},[3383,11768,7005],{"class":3786},[3383,11770,7008],{"class":3798},[3383,11772,11773,11775,11777],{"class":3385,"line":3392},[3383,11774,6871],{"class":3657},[3383,11776,3795],{"class":3780},[3383,11778,11753],{"class":3798},[3383,11780,11781,11783,11785],{"class":3385,"line":3398},[3383,11782,6393],{"class":3657},[3383,11784,3795],{"class":3780},[3383,11786,11787],{"class":3798}," max-age=60\n",[7827,11789,11792,11812,11863,11891],{"icon":11790,"title":11791},"i-lucide-corner-right-down","307 Temporary Redirect",[3317,11793,11794,11797,11798,11801,11802,11804,11805,11807,11808,11811],{},[3321,11795,11796],{},"Тимчасовий"," редирект. Метод і тіло ",[3321,11799,11800],{},"не змінюються"," — ",[3380,11803,3746],{}," залишається ",[3380,11806,3746],{}," (на відміну від ",[3380,11809,11810],{},"302",", який часто конвертує POST → GET). Не кешується.",[3373,11813,11815],{"className":3625,"code":11814,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fv1\u002Fupload HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\"name\": \"Андрій\"}\n",[3380,11816,11817,11830,11838,11846,11850],{"__ignoreMap":3378},[3383,11818,11819,11821,11824,11826,11828],{"class":3385,"line":3386},[3383,11820,3746],{"class":3634},[3383,11822,11823],{"class":3637}," \u002Fapi\u002Fv1\u002Fupload ",[3383,11825,3334],{"class":3780},[3383,11827,3783],{"class":3637},[3383,11829,3907],{"class":3786},[3383,11831,11832,11834,11836],{"class":3385,"line":3392},[3383,11833,3884],{"class":3657},[3383,11835,3795],{"class":3780},[3383,11837,6141],{"class":3798},[3383,11839,11840,11842,11844],{"class":3385,"line":3398},[3383,11841,3730],{"class":3657},[3383,11843,3795],{"class":3780},[3383,11845,6150],{"class":3798},[3383,11847,11848],{"class":3385,"line":3404},[3383,11849,3408],{"emptyLinePlaceholder":3407},[3383,11851,11852,11854,11856,11858,11861],{"class":3385,"line":3411},[3383,11853,5466],{"class":3637},[3383,11855,6445],{"class":6434},[3383,11857,6438],{"class":3637},[3383,11859,11860],{"class":3798},"\"Андрій\"",[3383,11862,4091],{"class":3637},[3373,11864,11866],{"className":3625,"code":11865,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 307 Temporary Redirect\nLocation: https:\u002F\u002Fapi.example.com\u002Fupload-v2\n",[3380,11867,11868,11882],{"__ignoreMap":3378},[3383,11869,11870,11872,11874,11876,11879],{"class":3385,"line":3386},[3383,11871,3334],{"class":3780},[3383,11873,3783],{"class":3637},[3383,11875,3946],{"class":3786},[3383,11877,11878],{"class":3786}," 307",[3383,11880,11881],{"class":3798}," Temporary Redirect\n",[3383,11883,11884,11886,11888],{"class":3385,"line":3392},[3383,11885,7191],{"class":3657},[3383,11887,3795],{"class":3780},[3383,11889,11890],{"class":3798}," https:\u002F\u002Fapi.example.com\u002Fupload-v2\n",[3317,11892,11893],{},[3337,11894,11895],{},"(Клієнт повторить POST на \u002Fupload-v2 — метод зберігається)",[7827,11897,11899,11913,11963,11991],{"icon":11648,"title":11898},"308 Permanent Redirect",[3317,11900,11901,11904,11905,11908,11909,11912],{},[3321,11902,11903],{},"Постійний"," редирект. Аналог ",[3380,11906,11907],{},"301",", але метод ",[3321,11910,11911],{},"не змінюється",". Кешується назавжди.",[3373,11914,11916],{"className":3625,"code":11915,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fv1\u002Fusers HTTP\u002F1.1\nHost: api.example.com\nContent-Type: application\u002Fjson\n\n{\"name\": \"Андрій\"}\n",[3380,11917,11918,11931,11939,11947,11951],{"__ignoreMap":3378},[3383,11919,11920,11922,11925,11927,11929],{"class":3385,"line":3386},[3383,11921,3746],{"class":3634},[3383,11923,11924],{"class":3637}," \u002Fapi\u002Fv1\u002Fusers ",[3383,11926,3334],{"class":3780},[3383,11928,3783],{"class":3637},[3383,11930,3907],{"class":3786},[3383,11932,11933,11935,11937],{"class":3385,"line":3392},[3383,11934,3884],{"class":3657},[3383,11936,3795],{"class":3780},[3383,11938,6141],{"class":3798},[3383,11940,11941,11943,11945],{"class":3385,"line":3398},[3383,11942,3730],{"class":3657},[3383,11944,3795],{"class":3780},[3383,11946,6150],{"class":3798},[3383,11948,11949],{"class":3385,"line":3404},[3383,11950,3408],{"emptyLinePlaceholder":3407},[3383,11952,11953,11955,11957,11959,11961],{"class":3385,"line":3411},[3383,11954,5466],{"class":3637},[3383,11956,6445],{"class":6434},[3383,11958,6438],{"class":3637},[3383,11960,11860],{"class":3798},[3383,11962,4091],{"class":3637},[3373,11964,11966],{"className":3625,"code":11965,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 308 Permanent Redirect\nLocation: https:\u002F\u002Fapi.example.com\u002Fapi\u002Fv2\u002Fusers\n",[3380,11967,11968,11982],{"__ignoreMap":3378},[3383,11969,11970,11972,11974,11976,11979],{"class":3385,"line":3386},[3383,11971,3334],{"class":3780},[3383,11973,3783],{"class":3637},[3383,11975,3946],{"class":3786},[3383,11977,11978],{"class":3786}," 308",[3383,11980,11981],{"class":3798}," Permanent Redirect\n",[3383,11983,11984,11986,11988],{"class":3385,"line":3392},[3383,11985,7191],{"class":3657},[3383,11987,3795],{"class":3780},[3383,11989,11990],{"class":3798}," https:\u002F\u002Fapi.example.com\u002Fapi\u002Fv2\u002Fusers\n",[3317,11992,11993],{},[3337,11994,11995],{},"(Клієнт повторить POST на \u002Fapi\u002Fv2\u002Fusers — редирект запам'ятовується браузером)",[3599,11997,11999],{"id":11998},"_4xx-помилки-клієнта","4xx — Помилки клієнта",[8493,12001,12002,12180,12327,12461,12582,12783,12961],{},[8496,12003,12006,12009,12069,12174],{"icon":12004,"label":12005},"i-lucide-alert-triangle","400 Bad Request",[3317,12007,12008],{},"Сервер не може обробити запит через синтаксичну помилку: некоректний JSON, відсутнє обов'язкове поле, невалідне значення.",[3373,12010,12012],{"className":3625,"code":12011,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{\"name\": \"Іван\", \"email\": \"not-an-email\", \"age\": \"twenty\"}\n",[3380,12013,12014,12026,12034,12038],{"__ignoreMap":3378},[3383,12015,12016,12018,12020,12022,12024],{"class":3385,"line":3386},[3383,12017,3746],{"class":3634},[3383,12019,7056],{"class":3637},[3383,12021,3334],{"class":3780},[3383,12023,3783],{"class":3637},[3383,12025,3907],{"class":3786},[3383,12027,12028,12030,12032],{"class":3385,"line":3392},[3383,12029,3730],{"class":3657},[3383,12031,3795],{"class":3780},[3383,12033,6150],{"class":3798},[3383,12035,12036],{"class":3385,"line":3398},[3383,12037,3408],{"emptyLinePlaceholder":3407},[3383,12039,12040,12042,12044,12046,12048,12050,12052,12054,12057,12059,12062,12064,12067],{"class":3385,"line":3404},[3383,12041,5466],{"class":3637},[3383,12043,6445],{"class":6434},[3383,12045,6438],{"class":3637},[3383,12047,8629],{"class":3798},[3383,12049,3731],{"class":3637},[3383,12051,6455],{"class":6434},[3383,12053,6438],{"class":3637},[3383,12055,12056],{"class":3798},"\"not-an-email\"",[3383,12058,3731],{"class":3637},[3383,12060,12061],{"class":6434},"\"age\"",[3383,12063,6438],{"class":3637},[3383,12065,12066],{"class":3798},"\"twenty\"",[3383,12068,4091],{"class":3637},[3373,12070,12072],{"className":3625,"code":12071,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 400 Bad Request\nContent-Type: application\u002Fproblem+json\n\n{\n  \"type\": \"https:\u002F\u002Fexample.com\u002Fproblems\u002Fvalidation\",\n  \"title\": \"Bad Request\",\n  \"status\": 400,\n  \"errors\": {\n    \"email\": [\"Невалідний формат email\"],\n    \"age\": [\"Очікується число, отримано рядок\"]\n  }\n}\n",[3380,12073,12074,12088,12096,12100,12104,12116,12127,12138,12144,12154,12166,12170],{"__ignoreMap":3378},[3383,12075,12076,12078,12080,12082,12085],{"class":3385,"line":3386},[3383,12077,3334],{"class":3780},[3383,12079,3783],{"class":3637},[3383,12081,3946],{"class":3786},[3383,12083,12084],{"class":3786}," 400",[3383,12086,12087],{"class":3798}," Bad Request\n",[3383,12089,12090,12092,12094],{"class":3385,"line":3392},[3383,12091,3730],{"class":3657},[3383,12093,3795],{"class":3780},[3383,12095,7373],{"class":3798},[3383,12097,12098],{"class":3385,"line":3398},[3383,12099,3408],{"emptyLinePlaceholder":3407},[3383,12101,12102],{"class":3385,"line":3404},[3383,12103,5292],{"class":3637},[3383,12105,12106,12109,12111,12114],{"class":3385,"line":3411},[3383,12107,12108],{"class":6434},"  \"type\"",[3383,12110,6438],{"class":3637},[3383,12112,12113],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fproblems\u002Fvalidation\"",[3383,12115,5305],{"class":3637},[3383,12117,12118,12120,12122,12125],{"class":3385,"line":3417},[3383,12119,7398],{"class":6434},[3383,12121,6438],{"class":3637},[3383,12123,12124],{"class":3798},"\"Bad Request\"",[3383,12126,5305],{"class":3637},[3383,12128,12129,12131,12133,12136],{"class":3385,"line":3423},[3383,12130,7386],{"class":6434},[3383,12132,6438],{"class":3637},[3383,12134,12135],{"class":3786},"400",[3383,12137,5305],{"class":3637},[3383,12139,12140,12142],{"class":3385,"line":3429},[3383,12141,7410],{"class":6434},[3383,12143,7413],{"class":3637},[3383,12145,12146,12148,12150,12152],{"class":3385,"line":3435},[3383,12147,7432],{"class":6434},[3383,12149,7421],{"class":3637},[3383,12151,7437],{"class":3798},[3383,12153,7427],{"class":3637},[3383,12155,12156,12159,12161,12164],{"class":3385,"line":3441},[3383,12157,12158],{"class":6434},"    \"age\"",[3383,12160,7421],{"class":3637},[3383,12162,12163],{"class":3798},"\"Очікується число, отримано рядок\"",[3383,12165,6499],{"class":3637},[3383,12167,12168],{"class":3385,"line":3447},[3383,12169,7444],{"class":3637},[3383,12171,12172],{"class":3385,"line":3453},[3383,12173,4091],{"class":3637},[3317,12175,12176,12179],{},[3321,12177,12178],{},"Коли:"," некоректний JSON, відсутні обов'язкові поля, невалідні типи даних.",[8496,12181,12184,12191,12216,12221,12322],{"icon":12182,"label":12183},"i-lucide-lock","401 Unauthorized",[3317,12185,12186,12187,12190],{},"Клієнт ",[3321,12188,12189],{},"не аутентифікований",". Потрібно надати або оновити облікові дані.",[3373,12192,12194],{"className":3625,"code":12193,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Forders HTTP\u002F1.1\nHost: api.example.com\n",[3380,12195,12196,12208],{"__ignoreMap":3378},[3383,12197,12198,12200,12202,12204,12206],{"class":3385,"line":3386},[3383,12199,3621],{"class":3634},[3383,12201,10627],{"class":3637},[3383,12203,3334],{"class":3780},[3383,12205,3783],{"class":3637},[3383,12207,3907],{"class":3786},[3383,12209,12210,12212,12214],{"class":3385,"line":3392},[3383,12211,3884],{"class":3657},[3383,12213,3795],{"class":3780},[3383,12215,6141],{"class":3798},[3317,12217,12218],{},[3337,12219,12220],{},"(без Authorization header)",[3373,12222,12224],{"className":3625,"code":12223,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 401 Unauthorized\nWWW-Authenticate: Bearer realm=\"api.example.com\",\n                  error=\"missing_token\",\n                  error_description=\"Authorization header required\"\nContent-Type: application\u002Fproblem+json\n\n{\n  \"type\": \"https:\u002F\u002Fexample.com\u002Fproblems\u002Funauthorized\",\n  \"title\": \"Unauthorized\",\n  \"status\": 401,\n  \"detail\": \"Відсутній або прострочений токен авторизації\"\n}\n",[3380,12225,12226,12240,12250,12255,12260,12268,12272,12276,12287,12298,12309,12318],{"__ignoreMap":3378},[3383,12227,12228,12230,12232,12234,12237],{"class":3385,"line":3386},[3383,12229,3334],{"class":3780},[3383,12231,3783],{"class":3637},[3383,12233,3946],{"class":3786},[3383,12235,12236],{"class":3786}," 401",[3383,12238,12239],{"class":3798}," Unauthorized\n",[3383,12241,12242,12245,12247],{"class":3385,"line":3392},[3383,12243,12244],{"class":3657},"WWW-Authenticate",[3383,12246,3795],{"class":3780},[3383,12248,12249],{"class":3798}," Bearer realm=\"api.example.com\",\n",[3383,12251,12252],{"class":3385,"line":3398},[3383,12253,12254],{"class":3637},"                  error=\"missing_token\",\n",[3383,12256,12257],{"class":3385,"line":3404},[3383,12258,12259],{"class":3637},"                  error_description=\"Authorization header required\"\n",[3383,12261,12262,12264,12266],{"class":3385,"line":3411},[3383,12263,3730],{"class":3657},[3383,12265,3795],{"class":3780},[3383,12267,7373],{"class":3798},[3383,12269,12270],{"class":3385,"line":3417},[3383,12271,3408],{"emptyLinePlaceholder":3407},[3383,12273,12274],{"class":3385,"line":3423},[3383,12275,5292],{"class":3637},[3383,12277,12278,12280,12282,12285],{"class":3385,"line":3429},[3383,12279,12108],{"class":6434},[3383,12281,6438],{"class":3637},[3383,12283,12284],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fproblems\u002Funauthorized\"",[3383,12286,5305],{"class":3637},[3383,12288,12289,12291,12293,12296],{"class":3385,"line":3435},[3383,12290,7398],{"class":6434},[3383,12292,6438],{"class":3637},[3383,12294,12295],{"class":3798},"\"Unauthorized\"",[3383,12297,5305],{"class":3637},[3383,12299,12300,12302,12304,12307],{"class":3385,"line":3441},[3383,12301,7386],{"class":6434},[3383,12303,6438],{"class":3637},[3383,12305,12306],{"class":3786},"401",[3383,12308,5305],{"class":3637},[3383,12310,12311,12313,12315],{"class":3385,"line":3447},[3383,12312,7607],{"class":6434},[3383,12314,6438],{"class":3637},[3383,12316,12317],{"class":3798},"\"Відсутній або прострочений токен авторизації\"\n",[3383,12319,12320],{"class":3385,"line":3453},[3383,12321,4091],{"class":3637},[3317,12323,12324,12326],{},[3321,12325,12178],{}," відсутній токен, прострочений JWT, невалідні Basic Auth credentials.",[8496,12328,12331,12341,12375,12456],{"icon":12329,"label":12330},"i-lucide-shield-off","403 Forbidden",[3317,12332,12186,12333,12336,12337,12340],{},[3321,12334,12335],{},"аутентифікований",", але ",[3321,12338,12339],{},"не має прав"," на цю операцію.",[3373,12342,12344],{"className":3625,"code":12343,"language":3627,"meta":3378,"style":3378},"DELETE \u002Fapi\u002Fusers\u002F1 HTTP\u002F1.1\nHost: api.example.com\nAuthorization: Bearer eyJhbGci...  (токен звичайного user, не admin)\n",[3380,12345,12346,12358,12366],{"__ignoreMap":3378},[3383,12347,12348,12350,12352,12354,12356],{"class":3385,"line":3386},[3383,12349,7467],{"class":3634},[3383,12351,8678],{"class":3637},[3383,12353,3334],{"class":3780},[3383,12355,3783],{"class":3637},[3383,12357,3907],{"class":3786},[3383,12359,12360,12362,12364],{"class":3385,"line":3392},[3383,12361,3884],{"class":3657},[3383,12363,3795],{"class":3780},[3383,12365,6141],{"class":3798},[3383,12367,12368,12370,12372],{"class":3385,"line":3398},[3383,12369,6165],{"class":3657},[3383,12371,3795],{"class":3780},[3383,12373,12374],{"class":3798}," Bearer eyJhbGci...  (токен звичайного user, не admin)\n",[3373,12376,12378],{"className":3625,"code":12377,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 403 Forbidden\nContent-Type: application\u002Fproblem+json\n\n{\n  \"type\": \"https:\u002F\u002Fexample.com\u002Fproblems\u002Fforbidden\",\n  \"title\": \"Forbidden\",\n  \"status\": 403,\n  \"detail\": \"Видалення користувачів доступне лише адміністраторам\"\n}\n",[3380,12379,12380,12394,12402,12406,12410,12421,12432,12443,12452],{"__ignoreMap":3378},[3383,12381,12382,12384,12386,12388,12391],{"class":3385,"line":3386},[3383,12383,3334],{"class":3780},[3383,12385,3783],{"class":3637},[3383,12387,3946],{"class":3786},[3383,12389,12390],{"class":3786}," 403",[3383,12392,12393],{"class":3798}," Forbidden\n",[3383,12395,12396,12398,12400],{"class":3385,"line":3392},[3383,12397,3730],{"class":3657},[3383,12399,3795],{"class":3780},[3383,12401,7373],{"class":3798},[3383,12403,12404],{"class":3385,"line":3398},[3383,12405,3408],{"emptyLinePlaceholder":3407},[3383,12407,12408],{"class":3385,"line":3404},[3383,12409,5292],{"class":3637},[3383,12411,12412,12414,12416,12419],{"class":3385,"line":3411},[3383,12413,12108],{"class":6434},[3383,12415,6438],{"class":3637},[3383,12417,12418],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fproblems\u002Fforbidden\"",[3383,12420,5305],{"class":3637},[3383,12422,12423,12425,12427,12430],{"class":3385,"line":3417},[3383,12424,7398],{"class":6434},[3383,12426,6438],{"class":3637},[3383,12428,12429],{"class":3798},"\"Forbidden\"",[3383,12431,5305],{"class":3637},[3383,12433,12434,12436,12438,12441],{"class":3385,"line":3423},[3383,12435,7386],{"class":6434},[3383,12437,6438],{"class":3637},[3383,12439,12440],{"class":3786},"403",[3383,12442,5305],{"class":3637},[3383,12444,12445,12447,12449],{"class":3385,"line":3429},[3383,12446,7607],{"class":6434},[3383,12448,6438],{"class":3637},[3383,12450,12451],{"class":3798},"\"Видалення користувачів доступне лише адміністраторам\"\n",[3383,12453,12454],{"class":3385,"line":3435},[3383,12455,4091],{"class":3637},[3317,12457,12458,12460],{},[3321,12459,12178],{}," недостатньо ролей\u002Fдозволів, доступ до чужого ресурсу, заблокований IP.",[8496,12462,12465,12471,12497,12574],{"icon":12463,"label":12464},"i-lucide-search-x","404 Not Found",[3317,12466,11652,12467,12470],{},[3321,12468,12469],{},"не знайдено"," за вказаним URL.",[3373,12472,12474],{"className":3625,"code":12473,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fusers\u002F99999 HTTP\u002F1.1\nHost: api.example.com\n",[3380,12475,12476,12489],{"__ignoreMap":3378},[3383,12477,12478,12480,12483,12485,12487],{"class":3385,"line":3386},[3383,12479,3621],{"class":3634},[3383,12481,12482],{"class":3637}," \u002Fapi\u002Fusers\u002F99999 ",[3383,12484,3334],{"class":3780},[3383,12486,3783],{"class":3637},[3383,12488,3907],{"class":3786},[3383,12490,12491,12493,12495],{"class":3385,"line":3392},[3383,12492,3884],{"class":3657},[3383,12494,3795],{"class":3780},[3383,12496,6141],{"class":3798},[3373,12498,12500],{"className":3625,"code":12499,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 404 Not Found\nContent-Type: application\u002Fproblem+json\n\n{\n  \"type\": \"https:\u002F\u002Fexample.com\u002Fproblems\u002Fnot-found\",\n  \"title\": \"Not Found\",\n  \"status\": 404,\n  \"detail\": \"Користувача з ID 99999 не існує\"\n}\n",[3380,12501,12502,12514,12522,12526,12530,12541,12551,12561,12570],{"__ignoreMap":3378},[3383,12503,12504,12506,12508,12510,12512],{"class":3385,"line":3386},[3383,12505,3334],{"class":3780},[3383,12507,3783],{"class":3637},[3383,12509,3946],{"class":3786},[3383,12511,7561],{"class":3786},[3383,12513,7564],{"class":3798},[3383,12515,12516,12518,12520],{"class":3385,"line":3392},[3383,12517,3730],{"class":3657},[3383,12519,3795],{"class":3780},[3383,12521,7373],{"class":3798},[3383,12523,12524],{"class":3385,"line":3398},[3383,12525,3408],{"emptyLinePlaceholder":3407},[3383,12527,12528],{"class":3385,"line":3404},[3383,12529,5292],{"class":3637},[3383,12531,12532,12534,12536,12539],{"class":3385,"line":3411},[3383,12533,12108],{"class":6434},[3383,12535,6438],{"class":3637},[3383,12537,12538],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fproblems\u002Fnot-found\"",[3383,12540,5305],{"class":3637},[3383,12542,12543,12545,12547,12549],{"class":3385,"line":3417},[3383,12544,7398],{"class":6434},[3383,12546,6438],{"class":3637},[3383,12548,7600],{"class":3798},[3383,12550,5305],{"class":3637},[3383,12552,12553,12555,12557,12559],{"class":3385,"line":3423},[3383,12554,7386],{"class":6434},[3383,12556,6438],{"class":3637},[3383,12558,7589],{"class":3786},[3383,12560,5305],{"class":3637},[3383,12562,12563,12565,12567],{"class":3385,"line":3429},[3383,12564,7607],{"class":6434},[3383,12566,6438],{"class":3637},[3383,12568,12569],{"class":3798},"\"Користувача з ID 99999 не існує\"\n",[3383,12571,12572],{"class":3385,"line":3435},[3383,12573,4091],{"class":3637},[3317,12575,12576,12578,12579,12581],{},[3321,12577,12178],{}," ресурс видалений, неправильний ID, помилка в URL. Також використовується замість ",[3380,12580,12440],{}," для приховування існування ресурсу.",[8496,12583,12586,12589,12638,12709,12715,12743,12778],{"icon":12584,"label":12585},"i-lucide-git-merge","409 Conflict",[3317,12587,12588],{},"Конфлікт із поточним станом ресурсу.",[3373,12590,12592],{"className":3625,"code":12591,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Fusers HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{\"name\": \"Іван\", \"email\": \"ivan@example.com\"}\n",[3380,12593,12594,12606,12614,12618],{"__ignoreMap":3378},[3383,12595,12596,12598,12600,12602,12604],{"class":3385,"line":3386},[3383,12597,3746],{"class":3634},[3383,12599,7056],{"class":3637},[3383,12601,3334],{"class":3780},[3383,12603,3783],{"class":3637},[3383,12605,3907],{"class":3786},[3383,12607,12608,12610,12612],{"class":3385,"line":3392},[3383,12609,3730],{"class":3657},[3383,12611,3795],{"class":3780},[3383,12613,6150],{"class":3798},[3383,12615,12616],{"class":3385,"line":3398},[3383,12617,3408],{"emptyLinePlaceholder":3407},[3383,12619,12620,12622,12624,12626,12628,12630,12632,12634,12636],{"class":3385,"line":3404},[3383,12621,5466],{"class":3637},[3383,12623,6445],{"class":6434},[3383,12625,6438],{"class":3637},[3383,12627,8629],{"class":3798},[3383,12629,3731],{"class":3637},[3383,12631,6455],{"class":6434},[3383,12633,6438],{"class":3637},[3383,12635,9161],{"class":3798},[3383,12637,4091],{"class":3637},[3373,12639,12641],{"className":3625,"code":12640,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 409 Conflict\nContent-Type: application\u002Fjson\n\n{\n  \"error\": \"Conflict\",\n  \"message\": \"Користувач з таким email вже існує\",\n  \"conflictingField\": \"email\"\n}\n",[3380,12642,12643,12657,12665,12669,12673,12684,12695,12705],{"__ignoreMap":3378},[3383,12644,12645,12647,12649,12651,12654],{"class":3385,"line":3386},[3383,12646,3334],{"class":3780},[3383,12648,3783],{"class":3637},[3383,12650,3946],{"class":3786},[3383,12652,12653],{"class":3786}," 409",[3383,12655,12656],{"class":3798}," Conflict\n",[3383,12658,12659,12661,12663],{"class":3385,"line":3392},[3383,12660,3730],{"class":3657},[3383,12662,3795],{"class":3780},[3383,12664,6150],{"class":3798},[3383,12666,12667],{"class":3385,"line":3398},[3383,12668,3408],{"emptyLinePlaceholder":3407},[3383,12670,12671],{"class":3385,"line":3404},[3383,12672,5292],{"class":3637},[3383,12674,12675,12677,12679,12682],{"class":3385,"line":3411},[3383,12676,10196],{"class":6434},[3383,12678,6438],{"class":3637},[3383,12680,12681],{"class":3798},"\"Conflict\"",[3383,12683,5305],{"class":3637},[3383,12685,12686,12688,12690,12693],{"class":3385,"line":3417},[3383,12687,10207],{"class":6434},[3383,12689,6438],{"class":3637},[3383,12691,12692],{"class":3798},"\"Користувач з таким email вже існує\"",[3383,12694,5305],{"class":3637},[3383,12696,12697,12700,12702],{"class":3385,"line":3423},[3383,12698,12699],{"class":6434},"  \"conflictingField\"",[3383,12701,6438],{"class":3637},[3383,12703,12704],{"class":3798},"\"email\"\n",[3383,12706,12707],{"class":3385,"line":3429},[3383,12708,4091],{"class":3637},[3317,12710,12711,12714],{},[3321,12712,12713],{},"Також:"," optimistic concurrency conflict:",[3373,12716,12718],{"className":3625,"code":12717,"language":3627,"meta":3378,"style":3378},"PUT \u002Fapi\u002Fposts\u002F5 HTTP\u002F1.1\nIf-Match: \"old-etag-value\"\n",[3380,12719,12720,12733],{"__ignoreMap":3378},[3383,12721,12722,12724,12727,12729,12731],{"class":3385,"line":3386},[3383,12723,8412],{"class":3634},[3383,12725,12726],{"class":3637}," \u002Fapi\u002Fposts\u002F5 ",[3383,12728,3334],{"class":3780},[3383,12730,3783],{"class":3637},[3383,12732,3907],{"class":3786},[3383,12734,12735,12738,12740],{"class":3385,"line":3392},[3383,12736,12737],{"class":3657},"If-Match",[3383,12739,3795],{"class":3780},[3383,12741,12742],{"class":3798}," \"old-etag-value\"\n",[3373,12744,12746],{"className":3625,"code":12745,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 409 Conflict\n\n{\"error\": \"Resource was modified by another request. Please reload.\"}\n",[3380,12747,12748,12760,12764],{"__ignoreMap":3378},[3383,12749,12750,12752,12754,12756,12758],{"class":3385,"line":3386},[3383,12751,3334],{"class":3780},[3383,12753,3783],{"class":3637},[3383,12755,3946],{"class":3786},[3383,12757,12653],{"class":3786},[3383,12759,12656],{"class":3798},[3383,12761,12762],{"class":3385,"line":3392},[3383,12763,3408],{"emptyLinePlaceholder":3407},[3383,12765,12766,12768,12771,12773,12776],{"class":3385,"line":3398},[3383,12767,5466],{"class":3637},[3383,12769,12770],{"class":6434},"\"error\"",[3383,12772,6438],{"class":3637},[3383,12774,12775],{"class":3798},"\"Resource was modified by another request. Please reload.\"",[3383,12777,4091],{"class":3637},[3317,12779,12780,12782],{},[3321,12781,12178],{}," дублікат унікального поля, конфлікт версій (optimistic locking), спроба перевести у несумісний стан.",[8496,12784,12787,12794,12864,12956],{"icon":12785,"label":12786},"i-lucide-file-x","422 Unprocessable Entity",[3317,12788,12789,12790,12793],{},"Синтаксис JSON правильний, але ",[3321,12791,12792],{},"семантика невалідна"," — бізнес-правила порушено.",[3373,12795,12797],{"className":3625,"code":12796,"language":3627,"meta":3378,"style":3378},"POST \u002Fapi\u002Forders HTTP\u002F1.1\nContent-Type: application\u002Fjson\n\n{\n  \"product_id\": 42,\n  \"quantity\": -5,\n  \"delivery_date\": \"2020-01-01\"\n}\n",[3380,12798,12799,12811,12819,12823,12827,12838,12850,12860],{"__ignoreMap":3378},[3383,12800,12801,12803,12805,12807,12809],{"class":3385,"line":3386},[3383,12802,3746],{"class":3634},[3383,12804,10627],{"class":3637},[3383,12806,3334],{"class":3780},[3383,12808,3783],{"class":3637},[3383,12810,3907],{"class":3786},[3383,12812,12813,12815,12817],{"class":3385,"line":3392},[3383,12814,3730],{"class":3657},[3383,12816,3795],{"class":3780},[3383,12818,6150],{"class":3798},[3383,12820,12821],{"class":3385,"line":3398},[3383,12822,3408],{"emptyLinePlaceholder":3407},[3383,12824,12825],{"class":3385,"line":3404},[3383,12826,5292],{"class":3637},[3383,12828,12829,12832,12834,12836],{"class":3385,"line":3411},[3383,12830,12831],{"class":6434},"  \"product_id\"",[3383,12833,6438],{"class":3637},[3383,12835,6903],{"class":3786},[3383,12837,5305],{"class":3637},[3383,12839,12840,12843,12845,12848],{"class":3385,"line":3417},[3383,12841,12842],{"class":6434},"  \"quantity\"",[3383,12844,6438],{"class":3637},[3383,12846,12847],{"class":3786},"-5",[3383,12849,5305],{"class":3637},[3383,12851,12852,12855,12857],{"class":3385,"line":3423},[3383,12853,12854],{"class":6434},"  \"delivery_date\"",[3383,12856,6438],{"class":3637},[3383,12858,12859],{"class":3798},"\"2020-01-01\"\n",[3383,12861,12862],{"class":3385,"line":3429},[3383,12863,4091],{"class":3637},[3373,12865,12867],{"className":3625,"code":12866,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 422 Unprocessable Entity\nContent-Type: application\u002Fproblem+json\n\n{\n  \"title\": \"Unprocessable Entity\",\n  \"status\": 422,\n  \"errors\": {\n    \"quantity\": [\"Кількість повинна бути більше 0\"],\n    \"delivery_date\": [\"Дата доставки не може бути в минулому\"]\n  }\n}\n",[3380,12868,12869,12881,12889,12893,12897,12908,12918,12924,12936,12948,12952],{"__ignoreMap":3378},[3383,12870,12871,12873,12875,12877,12879],{"class":3385,"line":3386},[3383,12872,3334],{"class":3780},[3383,12874,3783],{"class":3637},[3383,12876,3946],{"class":3786},[3383,12878,7361],{"class":3786},[3383,12880,7364],{"class":3798},[3383,12882,12883,12885,12887],{"class":3385,"line":3392},[3383,12884,3730],{"class":3657},[3383,12886,3795],{"class":3780},[3383,12888,7373],{"class":3798},[3383,12890,12891],{"class":3385,"line":3398},[3383,12892,3408],{"emptyLinePlaceholder":3407},[3383,12894,12895],{"class":3385,"line":3404},[3383,12896,5292],{"class":3637},[3383,12898,12899,12901,12903,12906],{"class":3385,"line":3411},[3383,12900,7398],{"class":6434},[3383,12902,6438],{"class":3637},[3383,12904,12905],{"class":3798},"\"Unprocessable Entity\"",[3383,12907,5305],{"class":3637},[3383,12909,12910,12912,12914,12916],{"class":3385,"line":3417},[3383,12911,7386],{"class":6434},[3383,12913,6438],{"class":3637},[3383,12915,7391],{"class":3786},[3383,12917,5305],{"class":3637},[3383,12919,12920,12922],{"class":3385,"line":3423},[3383,12921,7410],{"class":6434},[3383,12923,7413],{"class":3637},[3383,12925,12926,12929,12931,12934],{"class":3385,"line":3429},[3383,12927,12928],{"class":6434},"    \"quantity\"",[3383,12930,7421],{"class":3637},[3383,12932,12933],{"class":3798},"\"Кількість повинна бути більше 0\"",[3383,12935,7427],{"class":3637},[3383,12937,12938,12941,12943,12946],{"class":3385,"line":3435},[3383,12939,12940],{"class":6434},"    \"delivery_date\"",[3383,12942,7421],{"class":3637},[3383,12944,12945],{"class":3798},"\"Дата доставки не може бути в минулому\"",[3383,12947,6499],{"class":3637},[3383,12949,12950],{"class":3385,"line":3441},[3383,12951,7444],{"class":3637},[3383,12953,12954],{"class":3385,"line":3447},[3383,12955,4091],{"class":3637},[3317,12957,12958,12960],{},[3321,12959,12178],{}," порушення бізнес-правил, семантично некоректні дані, валідаційні помилки у REST API.",[8496,12962,12965,12972,13006,13115],{"icon":12963,"label":12964},"i-lucide-timer-off","429 Too Many Requests",[3317,12966,12967,12968,12971],{},"Клієнт перевищив ",[3321,12969,12970],{},"ліміт запитів"," (rate limiting).",[3373,12973,12975],{"className":3625,"code":12974,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Fsearch?q=test HTTP\u002F1.1\nHost: api.example.com\nAuthorization: Bearer eyJhbGci...\n",[3380,12976,12977,12990,12998],{"__ignoreMap":3378},[3383,12978,12979,12981,12984,12986,12988],{"class":3385,"line":3386},[3383,12980,3621],{"class":3634},[3383,12982,12983],{"class":3637}," \u002Fapi\u002Fsearch?q=test ",[3383,12985,3334],{"class":3780},[3383,12987,3783],{"class":3637},[3383,12989,3907],{"class":3786},[3383,12991,12992,12994,12996],{"class":3385,"line":3392},[3383,12993,3884],{"class":3657},[3383,12995,3795],{"class":3780},[3383,12997,6141],{"class":3798},[3383,12999,13000,13002,13004],{"class":3385,"line":3398},[3383,13001,6165],{"class":3657},[3383,13003,3795],{"class":3780},[3383,13005,8558],{"class":3798},[3373,13007,13009],{"className":3625,"code":13008,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 429 Too Many Requests\nRetry-After: 60\nX-RateLimit-Limit: 100\nX-RateLimit-Remaining: 0\nX-RateLimit-Reset: 1747480800\nContent-Type: application\u002Fjson\n\n{\n  \"error\": \"Too Many Requests\",\n  \"message\": \"Перевищено ліміт: 100 запитів на хвилину\",\n  \"retry_after\": 60\n}\n",[3380,13010,13011,13025,13035,13044,13053,13063,13071,13075,13079,13090,13101,13111],{"__ignoreMap":3378},[3383,13012,13013,13015,13017,13019,13022],{"class":3385,"line":3386},[3383,13014,3334],{"class":3780},[3383,13016,3783],{"class":3637},[3383,13018,3946],{"class":3786},[3383,13020,13021],{"class":3786}," 429",[3383,13023,13024],{"class":3798}," Too Many Requests\n",[3383,13026,13027,13030,13032],{"class":3385,"line":3392},[3383,13028,13029],{"class":3657},"Retry-After",[3383,13031,3795],{"class":3780},[3383,13033,13034],{"class":3798}," 60\n",[3383,13036,13037,13040,13042],{"class":3385,"line":3398},[3383,13038,13039],{"class":3657},"X-RateLimit-Limit",[3383,13041,3795],{"class":3780},[3383,13043,7087],{"class":3798},[3383,13045,13046,13049,13051],{"class":3385,"line":3404},[3383,13047,13048],{"class":3657},"X-RateLimit-Remaining",[3383,13050,3795],{"class":3780},[3383,13052,7699],{"class":3798},[3383,13054,13055,13058,13060],{"class":3385,"line":3411},[3383,13056,13057],{"class":3657},"X-RateLimit-Reset",[3383,13059,3795],{"class":3780},[3383,13061,13062],{"class":3798}," 1747480800\n",[3383,13064,13065,13067,13069],{"class":3385,"line":3417},[3383,13066,3730],{"class":3657},[3383,13068,3795],{"class":3780},[3383,13070,6150],{"class":3798},[3383,13072,13073],{"class":3385,"line":3423},[3383,13074,3408],{"emptyLinePlaceholder":3407},[3383,13076,13077],{"class":3385,"line":3429},[3383,13078,5292],{"class":3637},[3383,13080,13081,13083,13085,13088],{"class":3385,"line":3435},[3383,13082,10196],{"class":6434},[3383,13084,6438],{"class":3637},[3383,13086,13087],{"class":3798},"\"Too Many Requests\"",[3383,13089,5305],{"class":3637},[3383,13091,13092,13094,13096,13099],{"class":3385,"line":3441},[3383,13093,10207],{"class":6434},[3383,13095,6438],{"class":3637},[3383,13097,13098],{"class":3798},"\"Перевищено ліміт: 100 запитів на хвилину\"",[3383,13100,5305],{"class":3637},[3383,13102,13103,13106,13108],{"class":3385,"line":3447},[3383,13104,13105],{"class":6434},"  \"retry_after\"",[3383,13107,6438],{"class":3637},[3383,13109,13110],{"class":3786},"60\n",[3383,13112,13113],{"class":3385,"line":3453},[3383,13114,4091],{"class":3637},[3317,13116,13117,13119],{},[3321,13118,12178],{}," rate limiting по IP або токену, захист від DDoS, обмеження free tier.",[3599,13121,13123],{"id":13122},"_5xx-помилки-сервера","5xx — Помилки сервера",[13125,13126,13127,13130,13131,13134,13135,13138],"warning",{},[3321,13128,13129],{},"Ключова відмінність 4xx від 5xx:"," 4xx — помилка на стороні ",[3321,13132,13133],{},"клієнта"," (неправильний запит), 5xx — помилка на стороні ",[3321,13136,13137],{},"сервера"," (правильний запит, але сервер не зміг обробити). При 5xx клієнт може спробувати повторити запит пізніше.",[8493,13140,13141,13281,13350,13441],{},[8496,13142,13145,13148,13174,13267],{"icon":13143,"label":13144},"i-lucide-server-crash","500 Internal Server Error",[3317,13146,13147],{},"Необроблений виняток у коді сервера.",[3373,13149,13151],{"className":3625,"code":13150,"language":3627,"meta":3378,"style":3378},"GET \u002Fapi\u002Freport\u002Fgenerate HTTP\u002F1.1\nHost: api.example.com\n",[3380,13152,13153,13166],{"__ignoreMap":3378},[3383,13154,13155,13157,13160,13162,13164],{"class":3385,"line":3386},[3383,13156,3621],{"class":3634},[3383,13158,13159],{"class":3637}," \u002Fapi\u002Freport\u002Fgenerate ",[3383,13161,3334],{"class":3780},[3383,13163,3783],{"class":3637},[3383,13165,3907],{"class":3786},[3383,13167,13168,13170,13172],{"class":3385,"line":3392},[3383,13169,3884],{"class":3657},[3383,13171,3795],{"class":3780},[3383,13173,6141],{"class":3798},[3373,13175,13177],{"className":3625,"code":13176,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 500 Internal Server Error\nContent-Type: application\u002Fproblem+json\n\n{\n  \"type\": \"https:\u002F\u002Fexample.com\u002Fproblems\u002Finternal-error\",\n  \"title\": \"Internal Server Error\",\n  \"status\": 500,\n  \"detail\": \"Сталася внутрішня помилка сервера\",\n  \"trace_id\": \"a3f8b2c1-d9e2-4f1a\"\n}\n",[3380,13178,13179,13193,13201,13205,13209,13220,13231,13242,13253,13263],{"__ignoreMap":3378},[3383,13180,13181,13183,13185,13187,13190],{"class":3385,"line":3386},[3383,13182,3334],{"class":3780},[3383,13184,3783],{"class":3637},[3383,13186,3946],{"class":3786},[3383,13188,13189],{"class":3786}," 500",[3383,13191,13192],{"class":3798}," Internal Server Error\n",[3383,13194,13195,13197,13199],{"class":3385,"line":3392},[3383,13196,3730],{"class":3657},[3383,13198,3795],{"class":3780},[3383,13200,7373],{"class":3798},[3383,13202,13203],{"class":3385,"line":3398},[3383,13204,3408],{"emptyLinePlaceholder":3407},[3383,13206,13207],{"class":3385,"line":3404},[3383,13208,5292],{"class":3637},[3383,13210,13211,13213,13215,13218],{"class":3385,"line":3411},[3383,13212,12108],{"class":6434},[3383,13214,6438],{"class":3637},[3383,13216,13217],{"class":3798},"\"https:\u002F\u002Fexample.com\u002Fproblems\u002Finternal-error\"",[3383,13219,5305],{"class":3637},[3383,13221,13222,13224,13226,13229],{"class":3385,"line":3417},[3383,13223,7398],{"class":6434},[3383,13225,6438],{"class":3637},[3383,13227,13228],{"class":3798},"\"Internal Server Error\"",[3383,13230,5305],{"class":3637},[3383,13232,13233,13235,13237,13240],{"class":3385,"line":3423},[3383,13234,7386],{"class":6434},[3383,13236,6438],{"class":3637},[3383,13238,13239],{"class":3786},"500",[3383,13241,5305],{"class":3637},[3383,13243,13244,13246,13248,13251],{"class":3385,"line":3429},[3383,13245,7607],{"class":6434},[3383,13247,6438],{"class":3637},[3383,13249,13250],{"class":3798},"\"Сталася внутрішня помилка сервера\"",[3383,13252,5305],{"class":3637},[3383,13254,13255,13258,13260],{"class":3385,"line":3435},[3383,13256,13257],{"class":6434},"  \"trace_id\"",[3383,13259,6438],{"class":3637},[3383,13261,13262],{"class":3798},"\"a3f8b2c1-d9e2-4f1a\"\n",[3383,13264,13265],{"class":3385,"line":3441},[3383,13266,4091],{"class":3637},[3317,13268,13269,13272,13273,13276,13277,13280],{},[3321,13270,13271],{},"Увага:"," у production ",[3321,13274,13275],{},"ніколи не розкривайте"," stack trace у відповіді — лише ",[3380,13278,13279],{},"trace_id"," для пошуку у логах.",[8496,13282,13284,13287,13345],{"icon":658,"label":13283},"502 Bad Gateway",[3317,13285,13286],{},"Проксі або gateway отримав невалідну відповідь від upstream сервера.",[3373,13288,13290],{"className":3625,"code":13289,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 502 Bad Gateway\nContent-Type: text\u002Fhtml\n\n\u003Chtml>\u003Cbody>Bad Gateway: upstream server returned 502\u003C\u002Fbody>\u003C\u002Fhtml>\n",[3380,13291,13292,13306,13314,13318],{"__ignoreMap":3378},[3383,13293,13294,13296,13298,13300,13303],{"class":3385,"line":3386},[3383,13295,3334],{"class":3780},[3383,13297,3783],{"class":3637},[3383,13299,3946],{"class":3786},[3383,13301,13302],{"class":3786}," 502",[3383,13304,13305],{"class":3798}," Bad Gateway\n",[3383,13307,13308,13310,13312],{"class":3385,"line":3392},[3383,13309,3730],{"class":3657},[3383,13311,3795],{"class":3780},[3383,13313,3799],{"class":3798},[3383,13315,13316],{"class":3385,"line":3398},[3383,13317,3408],{"emptyLinePlaceholder":3407},[3383,13319,13320,13322,13324,13327,13329,13331,13334,13336,13338,13341,13343],{"class":3385,"line":3404},[3383,13321,3654],{"class":3653},[3383,13323,3646],{"class":3657},[3383,13325,13326],{"class":3653},">\u003C",[3383,13328,3668],{"class":3657},[3383,13330,3680],{"class":3653},[3383,13332,13333],{"class":3637},"Bad Gateway: upstream server returned 502",[3383,13335,3686],{"class":3653},[3383,13337,3668],{"class":3657},[3383,13339,13340],{"class":3653},">\u003C\u002F",[3383,13342,3646],{"class":3657},[3383,13344,3660],{"class":3653},[3317,13346,13347,13349],{},[3321,13348,12178],{}," nginx не може достукатись до FastAPI\u002FNode.js backend, мікросервіс повернув некоректну відповідь.",[8496,13351,13354,13357,13436],{"icon":13352,"label":13353},"i-lucide-cloud-off","503 Service Unavailable",[3317,13355,13356],{},"Сервер тимчасово недоступний — перевантажений або на обслуговуванні.",[3373,13358,13360],{"className":3625,"code":13359,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 503 Service Unavailable\nRetry-After: 300\nContent-Type: application\u002Fjson\n\n{\n  \"error\": \"Service Unavailable\",\n  \"message\": \"Технічне обслуговування до 12:00 UTC\",\n  \"retry_after\": 300\n}\n",[3380,13361,13362,13376,13385,13393,13397,13401,13412,13423,13432],{"__ignoreMap":3378},[3383,13363,13364,13366,13368,13370,13373],{"class":3385,"line":3386},[3383,13365,3334],{"class":3780},[3383,13367,3783],{"class":3637},[3383,13369,3946],{"class":3786},[3383,13371,13372],{"class":3786}," 503",[3383,13374,13375],{"class":3798}," Service Unavailable\n",[3383,13377,13378,13380,13382],{"class":3385,"line":3392},[3383,13379,13029],{"class":3657},[3383,13381,3795],{"class":3780},[3383,13383,13384],{"class":3798}," 300\n",[3383,13386,13387,13389,13391],{"class":3385,"line":3398},[3383,13388,3730],{"class":3657},[3383,13390,3795],{"class":3780},[3383,13392,6150],{"class":3798},[3383,13394,13395],{"class":3385,"line":3404},[3383,13396,3408],{"emptyLinePlaceholder":3407},[3383,13398,13399],{"class":3385,"line":3411},[3383,13400,5292],{"class":3637},[3383,13402,13403,13405,13407,13410],{"class":3385,"line":3417},[3383,13404,10196],{"class":6434},[3383,13406,6438],{"class":3637},[3383,13408,13409],{"class":3798},"\"Service Unavailable\"",[3383,13411,5305],{"class":3637},[3383,13413,13414,13416,13418,13421],{"class":3385,"line":3423},[3383,13415,10207],{"class":6434},[3383,13417,6438],{"class":3637},[3383,13419,13420],{"class":3798},"\"Технічне обслуговування до 12:00 UTC\"",[3383,13422,5305],{"class":3637},[3383,13424,13425,13427,13429],{"class":3385,"line":3429},[3383,13426,13105],{"class":6434},[3383,13428,6438],{"class":3637},[3383,13430,13431],{"class":3786},"300\n",[3383,13433,13434],{"class":3385,"line":3435},[3383,13435,4091],{"class":3637},[3317,13437,13438,13440],{},[3321,13439,12178],{}," планове обслуговування, перевантаження, circuit breaker відкрито.",[8496,13442,13445,13448,13507],{"icon":13443,"label":13444},"i-lucide-timer-reset","504 Gateway Timeout",[3317,13446,13447],{},"Проксі не отримав відповідь від upstream за відведений час.",[3373,13449,13451],{"className":3625,"code":13450,"language":3627,"meta":3378,"style":3378},"HTTP\u002F1.1 504 Gateway Timeout\nContent-Type: application\u002Fjson\n\n{\n  \"error\": \"Gateway Timeout\",\n  \"message\": \"Upstream server не відповів протягом 30 секунд\"\n}\n",[3380,13452,13453,13467,13475,13479,13483,13494,13503],{"__ignoreMap":3378},[3383,13454,13455,13457,13459,13461,13464],{"class":3385,"line":3386},[3383,13456,3334],{"class":3780},[3383,13458,3783],{"class":3637},[3383,13460,3946],{"class":3786},[3383,13462,13463],{"class":3786}," 504",[3383,13465,13466],{"class":3798}," Gateway Timeout\n",[3383,13468,13469,13471,13473],{"class":3385,"line":3392},[3383,13470,3730],{"class":3657},[3383,13472,3795],{"class":3780},[3383,13474,6150],{"class":3798},[3383,13476,13477],{"class":3385,"line":3398},[3383,13478,3408],{"emptyLinePlaceholder":3407},[3383,13480,13481],{"class":3385,"line":3404},[3383,13482,5292],{"class":3637},[3383,13484,13485,13487,13489,13492],{"class":3385,"line":3411},[3383,13486,10196],{"class":6434},[3383,13488,6438],{"class":3637},[3383,13490,13491],{"class":3798},"\"Gateway Timeout\"",[3383,13493,5305],{"class":3637},[3383,13495,13496,13498,13500],{"class":3385,"line":3417},[3383,13497,10207],{"class":6434},[3383,13499,6438],{"class":3637},[3383,13501,13502],{"class":3798},"\"Upstream server не відповів протягом 30 секунд\"\n",[3383,13504,13505],{"class":3385,"line":3423},[3383,13506,4091],{"class":3637},[3317,13508,13509,13511],{},[3321,13510,12178],{}," повільний database query, зависла зовнішня API, мікросервіс завантажений.",[3360,13513],{},[3312,13515,13517],{"id":13516},"http-headers-детальний-розбір","HTTP Headers: детальний розбір",[3317,13519,13520,13521,13524],{},"Заголовки — це ",[3321,13522,13523],{},"метадані"," HTTP-повідомлення. Вони несуть інформацію про формат тіла, аутентифікацію, кешування, кодування, а також власні розширення застосунку. Заголовки розділяються на кілька категорій.",[3370,13526,13527],{},[3373,13528,13530],{"className":3375,"code":13529,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\npackage \"HTTP Headers\" #f5f5f5 {\n\n    package \"General Headers\\n(запит і відповідь)\" #e3f2fd {\n        rectangle \"Date\" as date #bbdefb\n        rectangle \"Connection\" as conn #bbdefb\n        rectangle \"Cache-Control\" as cc #bbdefb\n        rectangle \"Transfer-Encoding\" as te #bbdefb\n    }\n\n    package \"Request Headers\" #e8f5e9 {\n        rectangle \"Host\" as host #a5d6a7\n        rectangle \"Accept \u002F Accept-*\" as accept #a5d6a7\n        rectangle \"Authorization\" as auth #a5d6a7\n        rectangle \"User-Agent\" as ua #a5d6a7\n        rectangle \"Referer\" as ref #a5d6a7\n        rectangle \"If-None-Match\" as inm #a5d6a7\n    }\n\n    package \"Response Headers\" #fff3e0 {\n        rectangle \"Content-Type\" as ct #ffcc80\n        rectangle \"Content-Length\" as cl #ffcc80\n        rectangle \"Location\" as loc #ffcc80\n        rectangle \"Set-Cookie\" as sc #ffcc80\n        rectangle \"WWW-Authenticate\" as wa #ffcc80\n        rectangle \"ETag\" as etag #ffcc80\n    }\n\n    package \"Representation Headers\\n(про тіло)\" #fce4ec {\n        rectangle \"Content-Encoding\" as ce #f48fb1\n        rectangle \"Content-Language\" as clang #f48fb1\n        rectangle \"Content-Location\" as cloc #f48fb1\n    }\n}\n\n@enduml\n",[3380,13531,13532,13536,13540,13544,13548,13553,13557,13562,13567,13572,13577,13582,13586,13590,13595,13600,13605,13610,13615,13620,13625,13629,13633,13638,13643,13648,13653,13658,13663,13668,13672,13676,13681,13686,13691,13696,13700,13704,13708],{"__ignoreMap":3378},[3383,13533,13534],{"class":3385,"line":3386},[3383,13535,4064],{},[3383,13537,13538],{"class":3385,"line":3392},[3383,13539,3395],{},[3383,13541,13542],{"class":3385,"line":3398},[3383,13543,3401],{},[3383,13545,13546],{"class":3385,"line":3404},[3383,13547,3408],{"emptyLinePlaceholder":3407},[3383,13549,13550],{"class":3385,"line":3411},[3383,13551,13552],{},"package \"HTTP Headers\" #f5f5f5 {\n",[3383,13554,13555],{"class":3385,"line":3417},[3383,13556,3408],{"emptyLinePlaceholder":3407},[3383,13558,13559],{"class":3385,"line":3423},[3383,13560,13561],{},"    package \"General Headers\\n(запит і відповідь)\" #e3f2fd {\n",[3383,13563,13564],{"class":3385,"line":3429},[3383,13565,13566],{},"        rectangle \"Date\" as date #bbdefb\n",[3383,13568,13569],{"class":3385,"line":3435},[3383,13570,13571],{},"        rectangle \"Connection\" as conn #bbdefb\n",[3383,13573,13574],{"class":3385,"line":3441},[3383,13575,13576],{},"        rectangle \"Cache-Control\" as cc #bbdefb\n",[3383,13578,13579],{"class":3385,"line":3447},[3383,13580,13581],{},"        rectangle \"Transfer-Encoding\" as te #bbdefb\n",[3383,13583,13584],{"class":3385,"line":3453},[3383,13585,5946],{},[3383,13587,13588],{"class":3385,"line":3459},[3383,13589,3408],{"emptyLinePlaceholder":3407},[3383,13591,13592],{"class":3385,"line":3465},[3383,13593,13594],{},"    package \"Request Headers\" #e8f5e9 {\n",[3383,13596,13597],{"class":3385,"line":3471},[3383,13598,13599],{},"        rectangle \"Host\" as host #a5d6a7\n",[3383,13601,13602],{"class":3385,"line":3477},[3383,13603,13604],{},"        rectangle \"Accept \u002F Accept-*\" as accept #a5d6a7\n",[3383,13606,13607],{"class":3385,"line":3483},[3383,13608,13609],{},"        rectangle \"Authorization\" as auth #a5d6a7\n",[3383,13611,13612],{"class":3385,"line":3489},[3383,13613,13614],{},"        rectangle \"User-Agent\" as ua #a5d6a7\n",[3383,13616,13617],{"class":3385,"line":3495},[3383,13618,13619],{},"        rectangle \"Referer\" as ref #a5d6a7\n",[3383,13621,13622],{"class":3385,"line":3501},[3383,13623,13624],{},"        rectangle \"If-None-Match\" as inm #a5d6a7\n",[3383,13626,13627],{"class":3385,"line":3507},[3383,13628,5946],{},[3383,13630,13631],{"class":3385,"line":3513},[3383,13632,3408],{"emptyLinePlaceholder":3407},[3383,13634,13635],{"class":3385,"line":3519},[3383,13636,13637],{},"    package \"Response Headers\" #fff3e0 {\n",[3383,13639,13640],{"class":3385,"line":3525},[3383,13641,13642],{},"        rectangle \"Content-Type\" as ct #ffcc80\n",[3383,13644,13645],{"class":3385,"line":3531},[3383,13646,13647],{},"        rectangle \"Content-Length\" as cl #ffcc80\n",[3383,13649,13650],{"class":3385,"line":3537},[3383,13651,13652],{},"        rectangle \"Location\" as loc #ffcc80\n",[3383,13654,13655],{"class":3385,"line":3543},[3383,13656,13657],{},"        rectangle \"Set-Cookie\" as sc #ffcc80\n",[3383,13659,13660],{"class":3385,"line":3549},[3383,13661,13662],{},"        rectangle \"WWW-Authenticate\" as wa #ffcc80\n",[3383,13664,13665],{"class":3385,"line":3555},[3383,13666,13667],{},"        rectangle \"ETag\" as etag #ffcc80\n",[3383,13669,13670],{"class":3385,"line":3561},[3383,13671,5946],{},[3383,13673,13674],{"class":3385,"line":3567},[3383,13675,3408],{"emptyLinePlaceholder":3407},[3383,13677,13678],{"class":3385,"line":3573},[3383,13679,13680],{},"    package \"Representation Headers\\n(про тіло)\" #fce4ec {\n",[3383,13682,13683],{"class":3385,"line":3579},[3383,13684,13685],{},"        rectangle \"Content-Encoding\" as ce #f48fb1\n",[3383,13687,13688],{"class":3385,"line":4215},[3383,13689,13690],{},"        rectangle \"Content-Language\" as clang #f48fb1\n",[3383,13692,13693],{"class":3385,"line":4220},[3383,13694,13695],{},"        rectangle \"Content-Location\" as cloc #f48fb1\n",[3383,13697,13698],{"class":3385,"line":4225},[3383,13699,5946],{},[3383,13701,13702],{"class":3385,"line":4231},[3383,13703,4091],{},[3383,13705,13706],{"class":3385,"line":4237},[3383,13707,3408],{"emptyLinePlaceholder":3407},[3383,13709,13710],{"class":3385,"line":4243},[3383,13711,4284],{},[3599,13713,13715],{"id":13714},"найважливіші-заголовки-запиту","Найважливіші заголовки запиту",[4655,13717,13718,13729,13744,13773,13799,13811,13825],{},[4658,13719,13721,13722,4775,13725,13728],{"name":3884,"type":13720},"string (обов'язковий у HTTP\u002F1.1)","Доменне ім'я та опціональний порт цільового сервера: ",[3380,13723,13724],{},"Host: api.example.com",[3380,13726,13727],{},"Host: localhost:5000",". Обов'язковий починаючи з HTTP\u002F1.1 — без нього сервер не знає, для якого віртуального хосту призначений запит. Єдиний обов'язковий заголовок у HTTP\u002F1.1.",[4658,13730,13732,13733,13736,13737,13740,13741,4760],{"name":3792,"type":13731},"MIME-типи з q-factor","Вказує, які формати відповіді клієнт ",[3321,13734,13735],{},"розуміє",". Підтримує q-factor (пріоритет, від 0 до 1):\n",[3380,13738,13739],{},"Accept: text\u002Fhtml, application\u002Fjson;q=0.9, *\u002F*;q=0.8","\nСервер обирає найкращий доступний формат — це ",[3321,13742,13743],{},"content negotiation",[4658,13745,13747,13754],{"name":3730,"type":13746},"MIME-тип",[3317,13748,13749,13750,13753],{},"Формат тіла ",[3321,13751,13752],{},"запиту"," (у POST, PUT, PATCH). Обов'язковий, якщо є тіло:",[3719,13755,13756,13761,13767],{},[3722,13757,13758,13760],{},[3380,13759,4027],{}," — JSON",[3722,13762,13763,13766],{},[3380,13764,13765],{},"Content-Type: application\u002Fx-www-form-urlencoded"," — HTML-форма",[3722,13768,13769,13772],{},[3380,13770,13771],{},"Content-Type: multipart\u002Fform-data; boundary=----..."," — форма з файлами",[4658,13774,13776,13779],{"name":6165,"type":13775},"scheme credentials",[3317,13777,13778],{},"Облікові дані для аутентифікації:",[3719,13780,13781,13787,13793],{},[3722,13782,13783,13786],{},[3380,13784,13785],{},"Authorization: Basic dXNlcjpwYXNz"," — Base64 (login:password)",[3722,13788,13789,13792],{},[3380,13790,13791],{},"Authorization: Bearer eyJhbGc..."," — JWT або OAuth токен",[3722,13794,13795,13798],{},[3380,13796,13797],{},"Authorization: Digest ..."," — Digest Auth",[4658,13800,13802,13803,13806,13807,13810],{"name":6791,"type":13801},"алгоритми стиснення","Алгоритми стиснення, які підтримує клієнт: ",[3380,13804,13805],{},"Accept-Encoding: gzip, deflate, br",". Сервер може стиснути відповідь і вказати ",[3380,13808,13809],{},"Content-Encoding: gzip",". Браузери завжди підтримують gzip та brotli.",[4658,13812,13814,13815,13818,13819,13821,13822,4760],{"name":6952,"type":13813},"ETag value","Умовний запит: надіслати відповідь тільки якщо ETag ресурсу ",[3321,13816,13817],{},"відрізняється"," від вказаного. Якщо ресурс не змінився — сервер повертає ",[3380,13820,11712],{}," без тіла. Це основа ",[3321,13823,13824],{},"HTTP-кешування",[4658,13826,13827,13828,4760],{"name":6175,"type":4709},"Ідентифікатор клієнта: браузера, бібліотеки або застосунку. Сервери іноді використовують для fingerprinting або видачі різного контенту. ",[3380,13829,13830],{},"User-Agent: dotnet-httpclient\u002F8.0",[3599,13832,13834],{"id":13833},"найважливіші-заголовки-відповіді","Найважливіші заголовки відповіді",[4655,13836,13837,13869,13879,13917,13931,13945,13953],{},[4658,13838,13840,13846],{"name":3730,"type":13839},"MIME-тип; charset",[3317,13841,13749,13842,13845],{},[3321,13843,13844],{},"відповіді",". Клієнт використовує для розбору:",[3719,13847,13848,13853,13858,13863],{},[3722,13849,13850],{},[3380,13851,13852],{},"Content-Type: application\u002Fjson; charset=utf-8",[3722,13854,13855],{},[3380,13856,13857],{},"Content-Type: text\u002Fhtml; charset=utf-8",[3722,13859,13860],{},[3380,13861,13862],{},"Content-Type: image\u002Fwebp",[3722,13864,13865,13868],{},[3380,13866,13867],{},"Content-Type: application\u002Foctet-stream"," — довільні бінарні дані",[4658,13870,13872,13873,13875,13876,13878],{"name":3734,"type":13871},"uint (байти)","Точний розмір тіла у байтах. Якщо відсутній — використовується ",[3380,13874,6590],{}," для потокової передачі. При ",[3380,13877,3734],{}," клієнт знає заздалегідь, скільки читати.",[4658,13880,13882,13885],{"name":6393,"type":13881},"директиви",[3317,13883,13884],{},"Управління кешуванням. Найважливіші директиви:",[3719,13886,13887,13893,13899,13905,13911],{},[3722,13888,13889,13892],{},[3380,13890,13891],{},"no-cache"," — перевіряти актуальність перед використанням кешу",[3722,13894,13895,13898],{},[3380,13896,13897],{},"no-store"," — ніколи не кешувати (особисті дані)",[3722,13900,13901,13904],{},[3380,13902,13903],{},"max-age=3600"," — кешувати 3600 секунд",[3722,13906,13907,13910],{},[3380,13908,13909],{},"public"," — можна кешувати у CDN та проксі",[3722,13912,13913,13916],{},[3380,13914,13915],{},"private"," — тільки у браузері користувача",[4658,13918,13920,13921,13924,13925,13927,13928,13930],{"name":6871,"type":13919},"string (версія ресурсу)","«Відбиток» (fingerprint) поточної версії ресурсу: ",[3380,13922,13923],{},"ETag: \"33a64df5\"",". Клієнт зберігає і передає у наступному запиті як ",[3380,13926,6952],{},". Якщо збігається — ",[3380,13929,11712],{},". Якщо ні — нова версія ресурсу.",[4658,13932,13933,13934,13936,13937,13939,13940,3783,13942,13944],{"name":7191,"type":4299},"URL для редиректу (",[3380,13935,6535],{},") або URL нового ресурсу (",[3380,13938,7150],{},"). При ",[3380,13941,11907],{},[3380,13943,11810],{}," браузер автоматично переходить за цим URL.",[4658,13946,13949,13950],{"name":13947,"type":13948},"Set-Cookie","cookie-string","Встановлює cookie у браузері клієнта. Один заголовок — один cookie. Формат:\n",[3380,13951,13952],{},"Set-Cookie: session=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=3600; Path=\u002F",[4658,13954,13956,13957,13959,13960],{"name":12244,"type":13955},"scheme realm","Супроводжує ",[3380,13958,12183],{},". Вказує, яку схему аутентифікації очікує сервер:\n",[3380,13961,13962],{},"WWW-Authenticate: Bearer realm=\"api.example.com\", error=\"invalid_token\"",[5854,13964,13965,13968,13969,13972,13973,3731,13975,13978,13979,3731,13982,13985,13986,3743,13989,13991],{},[3321,13966,13967],{},"Власні заголовки:"," Для власних метаданих використовуйте префікс ",[3380,13970,13971],{},"X-"," (застаріла конвенція, RFC 6648 скасував її у 2012) або просто описові назви: ",[3380,13974,6403],{},[3380,13976,13977],{},"X-Rate-Limit-Remaining",". Всі популярні фреймворки додають власні заголовки: ",[3380,13980,13981],{},"X-Powered-By",[3380,13983,13984],{},"Server",", тощо. У production рекомендується ",[3321,13987,13988],{},"приховувати",[3380,13990,13984],{}," заголовок з міркувань безпеки.",[3360,13993],{},[3312,13995,13997],{"id":13996},"http-у-net-екосистема-httpclient","HTTP у .NET: екосистема HttpClient",[3599,13999,14001],{"id":14000},"огляд-архітектури","Огляд архітектури",[3317,14003,14004],{},"Платформа .NET надає кілька рівнів абстракції для роботи з HTTP. Розуміння їх взаємозв'язку є ключем до правильного вибору інструменту.",[3370,14006,14007],{},[3373,14008,14010],{"className":3375,"code":14009,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\npackage \"System.Net.Http\" #e3f2fd {\n\n    class \"HttpClient\" as hc #bbdefb {\n        + BaseAddress: Uri?\n        + DefaultRequestHeaders: HttpRequestHeaders\n        + Timeout: TimeSpan\n        ---\n        + GetAsync(url): Task\u003CHttpResponseMessage>\n        + PostAsync(url, content): Task\u003CHttpResponseMessage>\n        + PutAsync(url, content): Task\u003CHttpResponseMessage>\n        + PatchAsync(url, content): Task\u003CHttpResponseMessage>\n        + DeleteAsync(url): Task\u003CHttpResponseMessage>\n        + SendAsync(request): Task\u003CHttpResponseMessage>\n    }\n\n    class \"HttpRequestMessage\" as hrq #c8e6c9 {\n        + Method: HttpMethod\n        + RequestUri: Uri?\n        + Headers: HttpRequestHeaders\n        + Content: HttpContent?\n        + Version: Version\n    }\n\n    class \"HttpResponseMessage\" as hrs #fff9c4 {\n        + StatusCode: HttpStatusCode\n        + IsSuccessStatusCode: bool\n        + Headers: HttpResponseHeaders\n        + Content: HttpContent\n        ---\n        + EnsureSuccessStatusCode()\n    }\n\n    class \"HttpMessageHandler\" as hmh #f3e5f5 {\n        # SendAsync(request, ct)\n    }\n\n    class \"HttpClientHandler\" as hch #e1bee7 {\n        + AllowAutoRedirect: bool\n        + UseCookies: bool\n        + CookieContainer\n        + ServerCertificateCustomValidation\n        + AutomaticDecompression\n    }\n\n    class \"DelegatingHandler\" as dh #fce4ec {\n        Перехоплення запитів:\\nлогування, retry, auth\n    }\n\n    hc --> hmh : використовує\n    hch --|> hmh\n    dh --|> hmh\n    dh --> hmh : InnerHandler\n    hc ..> hrq : приймає\n    hc ..> hrs : повертає\n}\n\npackage \"Microsoft.Extensions.Http\" #e8f5e9 {\n    class \"IHttpClientFactory\" as ihcf #a5d6a7 {\n        + CreateClient(name): HttpClient\n    }\n    ihcf --> hc : створює\n}\n\n@enduml\n",[3380,14011,14012,14016,14020,14024,14028,14033,14037,14042,14047,14052,14057,14062,14067,14072,14077,14082,14087,14092,14096,14100,14105,14110,14115,14120,14125,14130,14134,14138,14143,14148,14153,14158,14163,14167,14172,14176,14180,14185,14190,14194,14198,14203,14208,14213,14218,14223,14228,14232,14236,14241,14246,14250,14254,14259,14264,14269,14274,14279,14284,14288,14292,14297,14302,14307,14311,14316,14320,14325],{"__ignoreMap":3378},[3383,14013,14014],{"class":3385,"line":3386},[3383,14015,4064],{},[3383,14017,14018],{"class":3385,"line":3392},[3383,14019,3395],{},[3383,14021,14022],{"class":3385,"line":3398},[3383,14023,3401],{},[3383,14025,14026],{"class":3385,"line":3404},[3383,14027,3408],{"emptyLinePlaceholder":3407},[3383,14029,14030],{"class":3385,"line":3411},[3383,14031,14032],{},"package \"System.Net.Http\" #e3f2fd {\n",[3383,14034,14035],{"class":3385,"line":3417},[3383,14036,3408],{"emptyLinePlaceholder":3407},[3383,14038,14039],{"class":3385,"line":3423},[3383,14040,14041],{},"    class \"HttpClient\" as hc #bbdefb {\n",[3383,14043,14044],{"class":3385,"line":3429},[3383,14045,14046],{},"        + BaseAddress: Uri?\n",[3383,14048,14049],{"class":3385,"line":3435},[3383,14050,14051],{},"        + DefaultRequestHeaders: HttpRequestHeaders\n",[3383,14053,14054],{"class":3385,"line":3441},[3383,14055,14056],{},"        + Timeout: TimeSpan\n",[3383,14058,14059],{"class":3385,"line":3447},[3383,14060,14061],{},"        ---\n",[3383,14063,14064],{"class":3385,"line":3453},[3383,14065,14066],{},"        + GetAsync(url): Task\u003CHttpResponseMessage>\n",[3383,14068,14069],{"class":3385,"line":3459},[3383,14070,14071],{},"        + PostAsync(url, content): Task\u003CHttpResponseMessage>\n",[3383,14073,14074],{"class":3385,"line":3465},[3383,14075,14076],{},"        + PutAsync(url, content): Task\u003CHttpResponseMessage>\n",[3383,14078,14079],{"class":3385,"line":3471},[3383,14080,14081],{},"        + PatchAsync(url, content): Task\u003CHttpResponseMessage>\n",[3383,14083,14084],{"class":3385,"line":3477},[3383,14085,14086],{},"        + DeleteAsync(url): Task\u003CHttpResponseMessage>\n",[3383,14088,14089],{"class":3385,"line":3483},[3383,14090,14091],{},"        + SendAsync(request): Task\u003CHttpResponseMessage>\n",[3383,14093,14094],{"class":3385,"line":3489},[3383,14095,5946],{},[3383,14097,14098],{"class":3385,"line":3495},[3383,14099,3408],{"emptyLinePlaceholder":3407},[3383,14101,14102],{"class":3385,"line":3501},[3383,14103,14104],{},"    class \"HttpRequestMessage\" as hrq #c8e6c9 {\n",[3383,14106,14107],{"class":3385,"line":3507},[3383,14108,14109],{},"        + Method: HttpMethod\n",[3383,14111,14112],{"class":3385,"line":3513},[3383,14113,14114],{},"        + RequestUri: Uri?\n",[3383,14116,14117],{"class":3385,"line":3519},[3383,14118,14119],{},"        + Headers: HttpRequestHeaders\n",[3383,14121,14122],{"class":3385,"line":3525},[3383,14123,14124],{},"        + Content: HttpContent?\n",[3383,14126,14127],{"class":3385,"line":3531},[3383,14128,14129],{},"        + Version: Version\n",[3383,14131,14132],{"class":3385,"line":3537},[3383,14133,5946],{},[3383,14135,14136],{"class":3385,"line":3543},[3383,14137,3408],{"emptyLinePlaceholder":3407},[3383,14139,14140],{"class":3385,"line":3549},[3383,14141,14142],{},"    class \"HttpResponseMessage\" as hrs #fff9c4 {\n",[3383,14144,14145],{"class":3385,"line":3555},[3383,14146,14147],{},"        + StatusCode: HttpStatusCode\n",[3383,14149,14150],{"class":3385,"line":3561},[3383,14151,14152],{},"        + IsSuccessStatusCode: bool\n",[3383,14154,14155],{"class":3385,"line":3567},[3383,14156,14157],{},"        + Headers: HttpResponseHeaders\n",[3383,14159,14160],{"class":3385,"line":3573},[3383,14161,14162],{},"        + Content: HttpContent\n",[3383,14164,14165],{"class":3385,"line":3579},[3383,14166,14061],{},[3383,14168,14169],{"class":3385,"line":4215},[3383,14170,14171],{},"        + EnsureSuccessStatusCode()\n",[3383,14173,14174],{"class":3385,"line":4220},[3383,14175,5946],{},[3383,14177,14178],{"class":3385,"line":4225},[3383,14179,3408],{"emptyLinePlaceholder":3407},[3383,14181,14182],{"class":3385,"line":4231},[3383,14183,14184],{},"    class \"HttpMessageHandler\" as hmh #f3e5f5 {\n",[3383,14186,14187],{"class":3385,"line":4237},[3383,14188,14189],{},"        # SendAsync(request, ct)\n",[3383,14191,14192],{"class":3385,"line":4243},[3383,14193,5946],{},[3383,14195,14196],{"class":3385,"line":4248},[3383,14197,3408],{"emptyLinePlaceholder":3407},[3383,14199,14200],{"class":3385,"line":4253},[3383,14201,14202],{},"    class \"HttpClientHandler\" as hch #e1bee7 {\n",[3383,14204,14205],{"class":3385,"line":4259},[3383,14206,14207],{},"        + AllowAutoRedirect: bool\n",[3383,14209,14210],{"class":3385,"line":4265},[3383,14211,14212],{},"        + UseCookies: bool\n",[3383,14214,14215],{"class":3385,"line":4271},[3383,14216,14217],{},"        + CookieContainer\n",[3383,14219,14220],{"class":3385,"line":4276},[3383,14221,14222],{},"        + ServerCertificateCustomValidation\n",[3383,14224,14225],{"class":3385,"line":4281},[3383,14226,14227],{},"        + AutomaticDecompression\n",[3383,14229,14230],{"class":3385,"line":4540},[3383,14231,5946],{},[3383,14233,14234],{"class":3385,"line":4545},[3383,14235,3408],{"emptyLinePlaceholder":3407},[3383,14237,14238],{"class":3385,"line":4551},[3383,14239,14240],{},"    class \"DelegatingHandler\" as dh #fce4ec {\n",[3383,14242,14243],{"class":3385,"line":4557},[3383,14244,14245],{},"        Перехоплення запитів:\\nлогування, retry, auth\n",[3383,14247,14248],{"class":3385,"line":4563},[3383,14249,5946],{},[3383,14251,14252],{"class":3385,"line":4569},[3383,14253,3408],{"emptyLinePlaceholder":3407},[3383,14255,14256],{"class":3385,"line":4574},[3383,14257,14258],{},"    hc --> hmh : використовує\n",[3383,14260,14261],{"class":3385,"line":4579},[3383,14262,14263],{},"    hch --|> hmh\n",[3383,14265,14266],{"class":3385,"line":4585},[3383,14267,14268],{},"    dh --|> hmh\n",[3383,14270,14271],{"class":3385,"line":4591},[3383,14272,14273],{},"    dh --> hmh : InnerHandler\n",[3383,14275,14276],{"class":3385,"line":4597},[3383,14277,14278],{},"    hc ..> hrq : приймає\n",[3383,14280,14281],{"class":3385,"line":4603},[3383,14282,14283],{},"    hc ..> hrs : повертає\n",[3383,14285,14286],{"class":3385,"line":4608},[3383,14287,4091],{},[3383,14289,14290],{"class":3385,"line":4613},[3383,14291,3408],{"emptyLinePlaceholder":3407},[3383,14293,14294],{"class":3385,"line":4619},[3383,14295,14296],{},"package \"Microsoft.Extensions.Http\" #e8f5e9 {\n",[3383,14298,14299],{"class":3385,"line":4625},[3383,14300,14301],{},"    class \"IHttpClientFactory\" as ihcf #a5d6a7 {\n",[3383,14303,14304],{"class":3385,"line":4631},[3383,14305,14306],{},"        + CreateClient(name): HttpClient\n",[3383,14308,14309],{"class":3385,"line":4637},[3383,14310,5946],{},[3383,14312,14313],{"class":3385,"line":4642},[3383,14314,14315],{},"    ihcf --> hc : створює\n",[3383,14317,14318],{"class":3385,"line":4647},[3383,14319,4091],{},[3383,14321,14323],{"class":3385,"line":14322},67,[3383,14324,3408],{"emptyLinePlaceholder":3407},[3383,14326,14328],{"class":3385,"line":14327},68,[3383,14329,4284],{},[3599,14331,14333],{"id":14332},"клас-httpclient-детальний-розбір","Клас HttpClient: детальний розбір",[3317,14335,14336,14338,14339,14342,14343,6587,14346,4871],{},[3380,14337,7821],{}," — основний клас для HTTP-запитів у .NET. Він ",[3321,14340,14341],{},"не є"," безпечним для повторного створення на кожен запит — правильна практика: ",[3321,14344,14345],{},"один екземпляр на час життя застосунку",[3380,14347,14348],{},"IHttpClientFactory",[14350,14351,14352,14358,14359,14361,14362,14364,14365,14368,14369,14371,14372,14375,14376,14379,14380,4760],"caution",{},[3321,14353,14354,14355],{},"Класична пастка: ",[3380,14356,14357],{},"using var client = new HttpClient()","\nЯкщо створювати новий ",[3380,14360,7821],{}," для кожного запиту через ",[3380,14363,5100],{},", виникає ",[3321,14366,14367],{},"socket exhaustion"," — вичерпання портів. ",[3380,14370,7821],{}," утримує TCP-з'єднання у стані ",[3380,14373,14374],{},"TIME_WAIT"," ще кілька хвилин після ",[3380,14377,14378],{},"Dispose()",". При великому навантаженні це призводить до помилки ",[3380,14381,14382],{},"SocketException: Only one usage of each socket address is permitted",[4655,14384,14385,14398,14413],{},[4658,14386,14389,14390,14393,14394,14397],{"name":14387,"type":14388},"BaseAddress","Uri?","Базова адреса для всіх відносних запитів: ",[3380,14391,14392],{},"client.BaseAddress = new Uri(\"https:\u002F\u002Fapi.example.com\u002Fv1\u002F\")",". Дозволяє писати ",[3380,14395,14396],{},"client.GetAsync(\"users\")"," замість повної URL.",[4658,14399,14402,14403,14406,14407,3731,14409,3731,14411,4760],{"name":14400,"type":14401},"DefaultRequestHeaders","HttpRequestHeaders","Заголовки, що автоматично додаються до ",[3321,14404,14405],{},"кожного"," запиту. Ідеально для ",[3380,14408,6165],{},[3380,14410,3792],{},[3380,14412,6175],{},[4658,14414,14417,14418,14421,14422,14425,14426,14429],{"name":14415,"type":14416},"Timeout","TimeSpan","Максимальний час очікування для запиту (за замовчуванням ",[3321,14419,14420],{},"100 секунд","). При перевищенні — ",[3380,14423,14424],{},"TaskCanceledException",". Для різних операцій можна передавати ",[3380,14427,14428],{},"CancellationToken"," безпосередньо.",[3599,14431,14433],{"id":14432},"основні-методи-та-їх-використання","Основні методи та їх використання",[6747,14435,14436,14794,15087,15438],{},[6750,14437,14439],{"label":14438},"GET запит",[3373,14440,14442],{"className":5090,"code":14441,"language":5092,"meta":5093,"style":3378},"using System.Net.Http.Json;\n\n\u002F\u002F ✅ Правильно: HttpClient як singleton або через DI\nusing var client = new HttpClient\n{\n    BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\")\n};\n\n\u002F\u002F GET з десеріалізацією JSON у один рядок\nTodo? todo = await client.GetFromJsonAsync\u003CTodo>(\"todos\u002F1\");\nConsole.WriteLine($\"Title: {todo?.Title}\");\n\n\u002F\u002F GET зі перевіркою статус-коду\nHttpResponseMessage response = await client.GetAsync(\"todos\u002F999\");\nif (response.StatusCode == System.Net.HttpStatusCode.NotFound)\n{\n    Console.WriteLine(\"Не знайдено!\");\n    return;\n}\n\n\u002F\u002F EnsureSuccessStatusCode() кидає HttpRequestException при 4xx\u002F5xx\nresponse.EnsureSuccessStatusCode();\nstring json = await response.Content.ReadAsStringAsync();\nConsole.WriteLine(json);\n\nrecord Todo(int Id, string Title, bool Completed);\n",[3380,14443,14444,14466,14470,14475,14492,14496,14515,14519,14523,14528,14563,14593,14597,14602,14628,14665,14669,14685,14692,14696,14700,14705,14717,14742,14757,14761],{"__ignoreMap":3378},[3383,14445,14446,14448,14450,14452,14454,14456,14459,14461,14464],{"class":3385,"line":3386},[3383,14447,5100],{"class":3634},[3383,14449,5104],{"class":5103},[3383,14451,4760],{"class":3637},[3383,14453,5109],{"class":5103},[3383,14455,4760],{"class":3637},[3383,14457,14458],{"class":5103},"Http",[3383,14460,4760],{"class":3637},[3383,14462,14463],{"class":5103},"Json",[3383,14465,5112],{"class":3637},[3383,14467,14468],{"class":3385,"line":3392},[3383,14469,3408],{"emptyLinePlaceholder":3407},[3383,14471,14472],{"class":3385,"line":3398},[3383,14473,14474],{"class":5030},"\u002F\u002F ✅ Правильно: HttpClient як singleton або через DI\n",[3383,14476,14477,14479,14482,14485,14487,14489],{"class":3385,"line":3404},[3383,14478,5100],{"class":3634},[3383,14480,14481],{"class":3780}," var",[3383,14483,14484],{"class":5132}," client",[3383,14486,4744],{"class":3637},[3383,14488,5276],{"class":3780},[3383,14490,14491],{"class":5103}," HttpClient\n",[3383,14493,14494],{"class":3385,"line":3411},[3383,14495,5292],{"class":3637},[3383,14497,14498,14501,14503,14505,14508,14510,14513],{"class":3385,"line":3417},[3383,14499,14500],{"class":5132},"    BaseAddress",[3383,14502,4744],{"class":3637},[3383,14504,5276],{"class":3780},[3383,14506,14507],{"class":5103}," Uri",[3383,14509,5170],{"class":3637},[3383,14511,14512],{"class":3798},"\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\"",[3383,14514,5287],{"class":3637},[3383,14516,14517],{"class":3385,"line":3423},[3383,14518,5326],{"class":3637},[3383,14520,14521],{"class":3385,"line":3429},[3383,14522,3408],{"emptyLinePlaceholder":3407},[3383,14524,14525],{"class":3385,"line":3435},[3383,14526,14527],{"class":5030},"\u002F\u002F GET з десеріалізацією JSON у один рядок\n",[3383,14529,14530,14533,14536,14539,14541,14544,14546,14548,14551,14553,14555,14558,14561],{"class":3385,"line":3441},[3383,14531,14532],{"class":5103},"Todo",[3383,14534,14535],{"class":3637},"? ",[3383,14537,14538],{"class":5132},"todo",[3383,14540,4744],{"class":3637},[3383,14542,14543],{"class":3780},"await",[3383,14545,14484],{"class":5132},[3383,14547,4760],{"class":3637},[3383,14549,14550],{"class":5166},"GetFromJsonAsync",[3383,14552,3654],{"class":3637},[3383,14554,14532],{"class":5103},[3383,14556,14557],{"class":3637},">(",[3383,14559,14560],{"class":3798},"\"todos\u002F1\"",[3383,14562,5176],{"class":3637},[3383,14564,14565,14567,14569,14571,14573,14576,14578,14580,14582,14584,14587,14589,14591],{"class":3385,"line":3447},[3383,14566,5520],{"class":5132},[3383,14568,4760],{"class":3637},[3383,14570,5525],{"class":5166},[3383,14572,5170],{"class":3637},[3383,14574,14575],{"class":3798},"$\"Title: ",[3383,14577,5466],{"class":5465},[3383,14579,14538],{"class":5132},[3383,14581,4827],{"class":3637},[3383,14583,4760],{"class":5465},[3383,14585,14586],{"class":5132},"Title",[3383,14588,5583],{"class":5465},[3383,14590,5508],{"class":3798},[3383,14592,5176],{"class":3637},[3383,14594,14595],{"class":3385,"line":3453},[3383,14596,3408],{"emptyLinePlaceholder":3407},[3383,14598,14599],{"class":3385,"line":3459},[3383,14600,14601],{"class":5030},"\u002F\u002F GET зі перевіркою статус-коду\n",[3383,14603,14604,14607,14610,14612,14614,14616,14618,14621,14623,14626],{"class":3385,"line":3465},[3383,14605,14606],{"class":5103},"HttpResponseMessage",[3383,14608,14609],{"class":5132}," response",[3383,14611,4744],{"class":3637},[3383,14613,14543],{"class":3780},[3383,14615,14484],{"class":5132},[3383,14617,4760],{"class":3637},[3383,14619,14620],{"class":5166},"GetAsync",[3383,14622,5170],{"class":3637},[3383,14624,14625],{"class":3798},"\"todos\u002F999\"",[3383,14627,5176],{"class":3637},[3383,14629,14630,14633,14635,14638,14640,14643,14646,14649,14651,14653,14655,14658,14660,14663],{"class":3385,"line":3471},[3383,14631,14632],{"class":3634},"if",[3383,14634,3727],{"class":3637},[3383,14636,14637],{"class":5132},"response",[3383,14639,4760],{"class":3637},[3383,14641,14642],{"class":5132},"StatusCode",[3383,14644,14645],{"class":3637}," == ",[3383,14647,14648],{"class":5132},"System",[3383,14650,4760],{"class":3637},[3383,14652,5109],{"class":5132},[3383,14654,4760],{"class":3637},[3383,14656,14657],{"class":5132},"HttpStatusCode",[3383,14659,4760],{"class":3637},[3383,14661,14662],{"class":5132},"NotFound",[3383,14664,5287],{"class":3637},[3383,14666,14667],{"class":3385,"line":3477},[3383,14668,5292],{"class":3637},[3383,14670,14671,14674,14676,14678,14680,14683],{"class":3385,"line":3483},[3383,14672,14673],{"class":5132},"    Console",[3383,14675,4760],{"class":3637},[3383,14677,5525],{"class":5166},[3383,14679,5170],{"class":3637},[3383,14681,14682],{"class":3798},"\"Не знайдено!\"",[3383,14684,5176],{"class":3637},[3383,14686,14687,14690],{"class":3385,"line":3489},[3383,14688,14689],{"class":3634},"    return",[3383,14691,5112],{"class":3637},[3383,14693,14694],{"class":3385,"line":3495},[3383,14695,4091],{"class":3637},[3383,14697,14698],{"class":3385,"line":3501},[3383,14699,3408],{"emptyLinePlaceholder":3407},[3383,14701,14702],{"class":3385,"line":3507},[3383,14703,14704],{"class":5030},"\u002F\u002F EnsureSuccessStatusCode() кидає HttpRequestException при 4xx\u002F5xx\n",[3383,14706,14707,14709,14711,14714],{"class":3385,"line":3513},[3383,14708,14637],{"class":5132},[3383,14710,4760],{"class":3637},[3383,14712,14713],{"class":5166},"EnsureSuccessStatusCode",[3383,14715,14716],{"class":3637},"();\n",[3383,14718,14719,14721,14724,14726,14728,14730,14732,14735,14737,14740],{"class":3385,"line":3519},[3383,14720,4709],{"class":3780},[3383,14722,14723],{"class":5132}," json",[3383,14725,4744],{"class":3637},[3383,14727,14543],{"class":3780},[3383,14729,14609],{"class":5132},[3383,14731,4760],{"class":3637},[3383,14733,14734],{"class":5132},"Content",[3383,14736,4760],{"class":3637},[3383,14738,14739],{"class":5166},"ReadAsStringAsync",[3383,14741,14716],{"class":3637},[3383,14743,14744,14746,14748,14750,14752,14755],{"class":3385,"line":3525},[3383,14745,5520],{"class":5132},[3383,14747,4760],{"class":3637},[3383,14749,5525],{"class":5166},[3383,14751,5170],{"class":3637},[3383,14753,14754],{"class":5132},"json",[3383,14756,5176],{"class":3637},[3383,14758,14759],{"class":3385,"line":3531},[3383,14760,3408],{"emptyLinePlaceholder":3407},[3383,14762,14763,14766,14769,14771,14774,14777,14779,14781,14784,14786,14789,14792],{"class":3385,"line":3537},[3383,14764,14765],{"class":3780},"record",[3383,14767,14768],{"class":5103}," Todo",[3383,14770,5170],{"class":3637},[3383,14772,14773],{"class":3780},"int",[3383,14775,14776],{"class":5132}," Id",[3383,14778,3731],{"class":3637},[3383,14780,4709],{"class":3780},[3383,14782,14783],{"class":5132}," Title",[3383,14785,3731],{"class":3637},[3383,14787,14788],{"class":3780},"bool",[3383,14790,14791],{"class":5132}," Completed",[3383,14793,5176],{"class":3637},[6750,14795,14797],{"label":14796},"POST запит",[3373,14798,14800],{"className":5090,"code":14799,"language":5092,"meta":5093,"style":3378},"using System.Net.Http.Json;\n\nusing var client = new HttpClient\n{\n    BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\")\n};\n\n\u002F\u002F POST: серіалізація об'єкта в JSON автоматично\nvar newPost = new CreatePostRequest(\"My Title\", \"Body text\", 1);\n\n\u002F\u002F PostAsJsonAsync серіалізує і встановлює Content-Type: application\u002Fjson\nHttpResponseMessage response = await client.PostAsJsonAsync(\"posts\", newPost);\nresponse.EnsureSuccessStatusCode();\n\n\u002F\u002F Десеріалізація відповіді\nPost? created = await response.Content.ReadFromJsonAsync\u003CPost>();\nConsole.WriteLine($\"Created with ID: {created?.Id}\");\n\nrecord CreatePostRequest(string Title, string Body, int UserId);\nrecord Post(int Id, string Title, string Body, int UserId);\n",[3380,14801,14802,14822,14826,14840,14844,14860,14864,14868,14873,14903,14907,14912,14941,14951,14955,14960,14992,15022,15026,15054],{"__ignoreMap":3378},[3383,14803,14804,14806,14808,14810,14812,14814,14816,14818,14820],{"class":3385,"line":3386},[3383,14805,5100],{"class":3634},[3383,14807,5104],{"class":5103},[3383,14809,4760],{"class":3637},[3383,14811,5109],{"class":5103},[3383,14813,4760],{"class":3637},[3383,14815,14458],{"class":5103},[3383,14817,4760],{"class":3637},[3383,14819,14463],{"class":5103},[3383,14821,5112],{"class":3637},[3383,14823,14824],{"class":3385,"line":3392},[3383,14825,3408],{"emptyLinePlaceholder":3407},[3383,14827,14828,14830,14832,14834,14836,14838],{"class":3385,"line":3398},[3383,14829,5100],{"class":3634},[3383,14831,14481],{"class":3780},[3383,14833,14484],{"class":5132},[3383,14835,4744],{"class":3637},[3383,14837,5276],{"class":3780},[3383,14839,14491],{"class":5103},[3383,14841,14842],{"class":3385,"line":3404},[3383,14843,5292],{"class":3637},[3383,14845,14846,14848,14850,14852,14854,14856,14858],{"class":3385,"line":3411},[3383,14847,14500],{"class":5132},[3383,14849,4744],{"class":3637},[3383,14851,5276],{"class":3780},[3383,14853,14507],{"class":5103},[3383,14855,5170],{"class":3637},[3383,14857,14512],{"class":3798},[3383,14859,5287],{"class":3637},[3383,14861,14862],{"class":3385,"line":3417},[3383,14863,5326],{"class":3637},[3383,14865,14866],{"class":3385,"line":3423},[3383,14867,3408],{"emptyLinePlaceholder":3407},[3383,14869,14870],{"class":3385,"line":3429},[3383,14871,14872],{"class":5030},"\u002F\u002F POST: серіалізація об'єкта в JSON автоматично\n",[3383,14874,14875,14877,14880,14882,14884,14887,14889,14892,14894,14897,14899,14901],{"class":3385,"line":3435},[3383,14876,5268],{"class":3780},[3383,14878,14879],{"class":5132}," newPost",[3383,14881,4744],{"class":3637},[3383,14883,5276],{"class":3780},[3383,14885,14886],{"class":5103}," CreatePostRequest",[3383,14888,5170],{"class":3637},[3383,14890,14891],{"class":3798},"\"My Title\"",[3383,14893,3731],{"class":3637},[3383,14895,14896],{"class":3798},"\"Body text\"",[3383,14898,3731],{"class":3637},[3383,14900,5316],{"class":3786},[3383,14902,5176],{"class":3637},[3383,14904,14905],{"class":3385,"line":3441},[3383,14906,3408],{"emptyLinePlaceholder":3407},[3383,14908,14909],{"class":3385,"line":3447},[3383,14910,14911],{"class":5030},"\u002F\u002F PostAsJsonAsync серіалізує і встановлює Content-Type: application\u002Fjson\n",[3383,14913,14914,14916,14918,14920,14922,14924,14926,14929,14931,14934,14936,14939],{"class":3385,"line":3453},[3383,14915,14606],{"class":5103},[3383,14917,14609],{"class":5132},[3383,14919,4744],{"class":3637},[3383,14921,14543],{"class":3780},[3383,14923,14484],{"class":5132},[3383,14925,4760],{"class":3637},[3383,14927,14928],{"class":5166},"PostAsJsonAsync",[3383,14930,5170],{"class":3637},[3383,14932,14933],{"class":3798},"\"posts\"",[3383,14935,3731],{"class":3637},[3383,14937,14938],{"class":5132},"newPost",[3383,14940,5176],{"class":3637},[3383,14942,14943,14945,14947,14949],{"class":3385,"line":3459},[3383,14944,14637],{"class":5132},[3383,14946,4760],{"class":3637},[3383,14948,14713],{"class":5166},[3383,14950,14716],{"class":3637},[3383,14952,14953],{"class":3385,"line":3465},[3383,14954,3408],{"emptyLinePlaceholder":3407},[3383,14956,14957],{"class":3385,"line":3471},[3383,14958,14959],{"class":5030},"\u002F\u002F Десеріалізація відповіді\n",[3383,14961,14962,14965,14967,14970,14972,14974,14976,14978,14980,14982,14985,14987,14989],{"class":3385,"line":3477},[3383,14963,14964],{"class":5103},"Post",[3383,14966,14535],{"class":3637},[3383,14968,14969],{"class":5132},"created",[3383,14971,4744],{"class":3637},[3383,14973,14543],{"class":3780},[3383,14975,14609],{"class":5132},[3383,14977,4760],{"class":3637},[3383,14979,14734],{"class":5132},[3383,14981,4760],{"class":3637},[3383,14983,14984],{"class":5166},"ReadFromJsonAsync",[3383,14986,3654],{"class":3637},[3383,14988,14964],{"class":5103},[3383,14990,14991],{"class":3637},">();\n",[3383,14993,14994,14996,14998,15000,15002,15005,15007,15009,15011,15013,15016,15018,15020],{"class":3385,"line":3483},[3383,14995,5520],{"class":5132},[3383,14997,4760],{"class":3637},[3383,14999,5525],{"class":5166},[3383,15001,5170],{"class":3637},[3383,15003,15004],{"class":3798},"$\"Created with ID: ",[3383,15006,5466],{"class":5465},[3383,15008,14969],{"class":5132},[3383,15010,4827],{"class":3637},[3383,15012,4760],{"class":5465},[3383,15014,15015],{"class":5132},"Id",[3383,15017,5583],{"class":5465},[3383,15019,5508],{"class":3798},[3383,15021,5176],{"class":3637},[3383,15023,15024],{"class":3385,"line":3489},[3383,15025,3408],{"emptyLinePlaceholder":3407},[3383,15027,15028,15030,15032,15034,15036,15038,15040,15042,15045,15047,15049,15052],{"class":3385,"line":3495},[3383,15029,14765],{"class":3780},[3383,15031,14886],{"class":5103},[3383,15033,5170],{"class":3637},[3383,15035,4709],{"class":3780},[3383,15037,14783],{"class":5132},[3383,15039,3731],{"class":3637},[3383,15041,4709],{"class":3780},[3383,15043,15044],{"class":5132}," Body",[3383,15046,3731],{"class":3637},[3383,15048,14773],{"class":3780},[3383,15050,15051],{"class":5132}," UserId",[3383,15053,5176],{"class":3637},[3383,15055,15056,15058,15061,15063,15065,15067,15069,15071,15073,15075,15077,15079,15081,15083,15085],{"class":3385,"line":3501},[3383,15057,14765],{"class":3780},[3383,15059,15060],{"class":5103}," Post",[3383,15062,5170],{"class":3637},[3383,15064,14773],{"class":3780},[3383,15066,14776],{"class":5132},[3383,15068,3731],{"class":3637},[3383,15070,4709],{"class":3780},[3383,15072,14783],{"class":5132},[3383,15074,3731],{"class":3637},[3383,15076,4709],{"class":3780},[3383,15078,15044],{"class":5132},[3383,15080,3731],{"class":3637},[3383,15082,14773],{"class":3780},[3383,15084,15051],{"class":5132},[3383,15086,5176],{"class":3637},[6750,15088,15090],{"label":15089},"PUT \u002F PATCH \u002F DELETE",[3373,15091,15093],{"className":5090,"code":15092,"language":5092,"meta":5093,"style":3378},"using System.Net.Http.Json;\n\nusing var client = new HttpClient\n{\n    BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\")\n};\n\n\u002F\u002F PUT — повна заміна\nvar updated = new Post(1, \"New Title\", \"New body\", 1);\nvar putResponse = await client.PutAsJsonAsync(\"posts\u002F1\", updated);\nputResponse.EnsureSuccessStatusCode();\n\n\u002F\u002F PATCH — часткове оновлення (через HttpRequestMessage для PATCH)\nvar patch = new { Title = \"Patched Title\" };\nvar patchContent = JsonContent.Create(patch);\nvar patchResponse = await client.PatchAsync(\"posts\u002F1\", patchContent);\npatchResponse.EnsureSuccessStatusCode();\n\n\u002F\u002F DELETE\nHttpResponseMessage deleteResponse = await client.DeleteAsync(\"posts\u002F1\");\nConsole.WriteLine($\"Delete: {deleteResponse.StatusCode}\"); \u002F\u002F 200 OK\n\nrecord Post(int Id, string Title, string Body, int UserId);\n",[3380,15094,15095,15115,15119,15133,15137,15153,15157,15161,15166,15199,15229,15240,15244,15249,15273,15297,15326,15337,15341,15346,15370,15402,15406],{"__ignoreMap":3378},[3383,15096,15097,15099,15101,15103,15105,15107,15109,15111,15113],{"class":3385,"line":3386},[3383,15098,5100],{"class":3634},[3383,15100,5104],{"class":5103},[3383,15102,4760],{"class":3637},[3383,15104,5109],{"class":5103},[3383,15106,4760],{"class":3637},[3383,15108,14458],{"class":5103},[3383,15110,4760],{"class":3637},[3383,15112,14463],{"class":5103},[3383,15114,5112],{"class":3637},[3383,15116,15117],{"class":3385,"line":3392},[3383,15118,3408],{"emptyLinePlaceholder":3407},[3383,15120,15121,15123,15125,15127,15129,15131],{"class":3385,"line":3398},[3383,15122,5100],{"class":3634},[3383,15124,14481],{"class":3780},[3383,15126,14484],{"class":5132},[3383,15128,4744],{"class":3637},[3383,15130,5276],{"class":3780},[3383,15132,14491],{"class":5103},[3383,15134,15135],{"class":3385,"line":3404},[3383,15136,5292],{"class":3637},[3383,15138,15139,15141,15143,15145,15147,15149,15151],{"class":3385,"line":3411},[3383,15140,14500],{"class":5132},[3383,15142,4744],{"class":3637},[3383,15144,5276],{"class":3780},[3383,15146,14507],{"class":5103},[3383,15148,5170],{"class":3637},[3383,15150,14512],{"class":3798},[3383,15152,5287],{"class":3637},[3383,15154,15155],{"class":3385,"line":3417},[3383,15156,5326],{"class":3637},[3383,15158,15159],{"class":3385,"line":3423},[3383,15160,3408],{"emptyLinePlaceholder":3407},[3383,15162,15163],{"class":3385,"line":3429},[3383,15164,15165],{"class":5030},"\u002F\u002F PUT — повна заміна\n",[3383,15167,15168,15170,15173,15175,15177,15179,15181,15183,15185,15188,15190,15193,15195,15197],{"class":3385,"line":3435},[3383,15169,5268],{"class":3780},[3383,15171,15172],{"class":5132}," updated",[3383,15174,4744],{"class":3637},[3383,15176,5276],{"class":3780},[3383,15178,15060],{"class":5103},[3383,15180,5170],{"class":3637},[3383,15182,5316],{"class":3786},[3383,15184,3731],{"class":3637},[3383,15186,15187],{"class":3798},"\"New Title\"",[3383,15189,3731],{"class":3637},[3383,15191,15192],{"class":3798},"\"New body\"",[3383,15194,3731],{"class":3637},[3383,15196,5316],{"class":3786},[3383,15198,5176],{"class":3637},[3383,15200,15201,15203,15206,15208,15210,15212,15214,15217,15219,15222,15224,15227],{"class":3385,"line":3441},[3383,15202,5268],{"class":3780},[3383,15204,15205],{"class":5132}," putResponse",[3383,15207,4744],{"class":3637},[3383,15209,14543],{"class":3780},[3383,15211,14484],{"class":5132},[3383,15213,4760],{"class":3637},[3383,15215,15216],{"class":5166},"PutAsJsonAsync",[3383,15218,5170],{"class":3637},[3383,15220,15221],{"class":3798},"\"posts\u002F1\"",[3383,15223,3731],{"class":3637},[3383,15225,15226],{"class":5132},"updated",[3383,15228,5176],{"class":3637},[3383,15230,15231,15234,15236,15238],{"class":3385,"line":3447},[3383,15232,15233],{"class":5132},"putResponse",[3383,15235,4760],{"class":3637},[3383,15237,14713],{"class":5166},[3383,15239,14716],{"class":3637},[3383,15241,15242],{"class":3385,"line":3453},[3383,15243,3408],{"emptyLinePlaceholder":3407},[3383,15245,15246],{"class":3385,"line":3459},[3383,15247,15248],{"class":5030},"\u002F\u002F PATCH — часткове оновлення (через HttpRequestMessage для PATCH)\n",[3383,15250,15251,15253,15256,15258,15260,15263,15265,15267,15270],{"class":3385,"line":3465},[3383,15252,5268],{"class":3780},[3383,15254,15255],{"class":5132}," patch",[3383,15257,4744],{"class":3637},[3383,15259,5276],{"class":3780},[3383,15261,15262],{"class":3637}," { ",[3383,15264,14586],{"class":5132},[3383,15266,4744],{"class":3637},[3383,15268,15269],{"class":3798},"\"Patched Title\"",[3383,15271,15272],{"class":3637}," };\n",[3383,15274,15275,15277,15280,15282,15285,15287,15290,15292,15295],{"class":3385,"line":3471},[3383,15276,5268],{"class":3780},[3383,15278,15279],{"class":5132}," patchContent",[3383,15281,4744],{"class":3637},[3383,15283,15284],{"class":5132},"JsonContent",[3383,15286,4760],{"class":3637},[3383,15288,15289],{"class":5166},"Create",[3383,15291,5170],{"class":3637},[3383,15293,15294],{"class":5132},"patch",[3383,15296,5176],{"class":3637},[3383,15298,15299,15301,15304,15306,15308,15310,15312,15315,15317,15319,15321,15324],{"class":3385,"line":3477},[3383,15300,5268],{"class":3780},[3383,15302,15303],{"class":5132}," patchResponse",[3383,15305,4744],{"class":3637},[3383,15307,14543],{"class":3780},[3383,15309,14484],{"class":5132},[3383,15311,4760],{"class":3637},[3383,15313,15314],{"class":5166},"PatchAsync",[3383,15316,5170],{"class":3637},[3383,15318,15221],{"class":3798},[3383,15320,3731],{"class":3637},[3383,15322,15323],{"class":5132},"patchContent",[3383,15325,5176],{"class":3637},[3383,15327,15328,15331,15333,15335],{"class":3385,"line":3483},[3383,15329,15330],{"class":5132},"patchResponse",[3383,15332,4760],{"class":3637},[3383,15334,14713],{"class":5166},[3383,15336,14716],{"class":3637},[3383,15338,15339],{"class":3385,"line":3489},[3383,15340,3408],{"emptyLinePlaceholder":3407},[3383,15342,15343],{"class":3385,"line":3495},[3383,15344,15345],{"class":5030},"\u002F\u002F DELETE\n",[3383,15347,15348,15350,15353,15355,15357,15359,15361,15364,15366,15368],{"class":3385,"line":3501},[3383,15349,14606],{"class":5103},[3383,15351,15352],{"class":5132}," deleteResponse",[3383,15354,4744],{"class":3637},[3383,15356,14543],{"class":3780},[3383,15358,14484],{"class":5132},[3383,15360,4760],{"class":3637},[3383,15362,15363],{"class":5166},"DeleteAsync",[3383,15365,5170],{"class":3637},[3383,15367,15221],{"class":3798},[3383,15369,5176],{"class":3637},[3383,15371,15372,15374,15376,15378,15380,15383,15385,15388,15390,15392,15394,15396,15399],{"class":3385,"line":3507},[3383,15373,5520],{"class":5132},[3383,15375,4760],{"class":3637},[3383,15377,5525],{"class":5166},[3383,15379,5170],{"class":3637},[3383,15381,15382],{"class":3798},"$\"Delete: ",[3383,15384,5466],{"class":5465},[3383,15386,15387],{"class":5132},"deleteResponse",[3383,15389,4760],{"class":5465},[3383,15391,14642],{"class":5132},[3383,15393,5583],{"class":5465},[3383,15395,5508],{"class":3798},[3383,15397,15398],{"class":3637},"); ",[3383,15400,15401],{"class":5030},"\u002F\u002F 200 OK\n",[3383,15403,15404],{"class":3385,"line":3513},[3383,15405,3408],{"emptyLinePlaceholder":3407},[3383,15407,15408,15410,15412,15414,15416,15418,15420,15422,15424,15426,15428,15430,15432,15434,15436],{"class":3385,"line":3519},[3383,15409,14765],{"class":3780},[3383,15411,15060],{"class":5103},[3383,15413,5170],{"class":3637},[3383,15415,14773],{"class":3780},[3383,15417,14776],{"class":5132},[3383,15419,3731],{"class":3637},[3383,15421,4709],{"class":3780},[3383,15423,14783],{"class":5132},[3383,15425,3731],{"class":3637},[3383,15427,4709],{"class":3780},[3383,15429,15044],{"class":5132},[3383,15431,3731],{"class":3637},[3383,15433,14773],{"class":3780},[3383,15435,15051],{"class":5132},[3383,15437,5176],{"class":3637},[6750,15439,15441],{"label":15440},"Тонке налаштування",[3373,15442,15444],{"className":5090,"code":15443,"language":5092,"meta":5093,"style":3378},"using System.Net.Http.Headers;\n\nusing var client = new HttpClient();\n\n\u002F\u002F Створюємо запит вручну для повного контролю\nvar request = new HttpRequestMessage(HttpMethod.Get, \"https:\u002F\u002Fapi.example.com\u002Fdata\")\n{\n    \u002F\u002F Версія HTTP\n    Version = new Version(2, 0),\n    VersionPolicy = HttpVersionPolicy.RequestVersionOrHigher,\n\n    \u002F\u002F Заголовки специфічні для цього запиту\n    Headers =\n    {\n        { \"X-Request-Id\", Guid.NewGuid().ToString() },\n        Accept = { new MediaTypeWithQualityHeaderValue(\"application\u002Fjson\") }\n    }\n};\n\n\u002F\u002F Додаємо Authorization (тільки для цього запиту)\nrequest.Headers.Authorization =\n    new AuthenticationHeaderValue(\"Bearer\", \"eyJhbGci...\");\n\nusing HttpResponseMessage response = await client.SendAsync(\n    request,\n    HttpCompletionOption.ResponseHeadersRead, \u002F\u002F не читаємо тіло одразу\n    CancellationToken.None\n);\n\n\u002F\u002F Потокове читання великого тіла\nawait using Stream stream = await response.Content.ReadAsStreamAsync();\n\u002F\u002F ... обробка stream\n",[3380,15445,15446,15466,15470,15487,15491,15496,15527,15531,15536,15560,15577,15581,15586,15594,15599,15626,15647,15651,15655,15659,15664,15679,15698,15702,15725,15732,15747,15757,15761,15765,15770,15800],{"__ignoreMap":3378},[3383,15447,15448,15450,15452,15454,15456,15458,15460,15462,15464],{"class":3385,"line":3386},[3383,15449,5100],{"class":3634},[3383,15451,5104],{"class":5103},[3383,15453,4760],{"class":3637},[3383,15455,5109],{"class":5103},[3383,15457,4760],{"class":3637},[3383,15459,14458],{"class":5103},[3383,15461,4760],{"class":3637},[3383,15463,6565],{"class":5103},[3383,15465,5112],{"class":3637},[3383,15467,15468],{"class":3385,"line":3392},[3383,15469,3408],{"emptyLinePlaceholder":3407},[3383,15471,15472,15474,15476,15478,15480,15482,15485],{"class":3385,"line":3398},[3383,15473,5100],{"class":3634},[3383,15475,14481],{"class":3780},[3383,15477,14484],{"class":5132},[3383,15479,4744],{"class":3637},[3383,15481,5276],{"class":3780},[3383,15483,15484],{"class":5103}," HttpClient",[3383,15486,14716],{"class":3637},[3383,15488,15489],{"class":3385,"line":3404},[3383,15490,3408],{"emptyLinePlaceholder":3407},[3383,15492,15493],{"class":3385,"line":3411},[3383,15494,15495],{"class":5030},"\u002F\u002F Створюємо запит вручну для повного контролю\n",[3383,15497,15498,15500,15503,15505,15507,15510,15512,15515,15517,15520,15522,15525],{"class":3385,"line":3417},[3383,15499,5268],{"class":3780},[3383,15501,15502],{"class":5132}," request",[3383,15504,4744],{"class":3637},[3383,15506,5276],{"class":3780},[3383,15508,15509],{"class":5103}," HttpRequestMessage",[3383,15511,5170],{"class":3637},[3383,15513,15514],{"class":5132},"HttpMethod",[3383,15516,4760],{"class":3637},[3383,15518,15519],{"class":5132},"Get",[3383,15521,3731],{"class":3637},[3383,15523,15524],{"class":3798},"\"https:\u002F\u002Fapi.example.com\u002Fdata\"",[3383,15526,5287],{"class":3637},[3383,15528,15529],{"class":3385,"line":3423},[3383,15530,5292],{"class":3637},[3383,15532,15533],{"class":3385,"line":3429},[3383,15534,15535],{"class":5030},"    \u002F\u002F Версія HTTP\n",[3383,15537,15538,15541,15543,15545,15548,15550,15552,15554,15557],{"class":3385,"line":3435},[3383,15539,15540],{"class":5132},"    Version",[3383,15542,4744],{"class":3637},[3383,15544,5276],{"class":3780},[3383,15546,15547],{"class":5103}," Version",[3383,15549,5170],{"class":3637},[3383,15551,6474],{"class":3786},[3383,15553,3731],{"class":3637},[3383,15555,15556],{"class":3786},"0",[3383,15558,15559],{"class":3637},"),\n",[3383,15561,15562,15565,15567,15570,15572,15575],{"class":3385,"line":3441},[3383,15563,15564],{"class":5132},"    VersionPolicy",[3383,15566,4744],{"class":3637},[3383,15568,15569],{"class":5132},"HttpVersionPolicy",[3383,15571,4760],{"class":3637},[3383,15573,15574],{"class":5132},"RequestVersionOrHigher",[3383,15576,5305],{"class":3637},[3383,15578,15579],{"class":3385,"line":3447},[3383,15580,3408],{"emptyLinePlaceholder":3407},[3383,15582,15583],{"class":3385,"line":3453},[3383,15584,15585],{"class":5030},"    \u002F\u002F Заголовки специфічні для цього запиту\n",[3383,15587,15588,15591],{"class":3385,"line":3459},[3383,15589,15590],{"class":5132},"    Headers",[3383,15592,15593],{"class":3637}," =\n",[3383,15595,15596],{"class":3385,"line":3465},[3383,15597,15598],{"class":3637},"    {\n",[3383,15600,15601,15604,15607,15609,15612,15614,15617,15620,15623],{"class":3385,"line":3471},[3383,15602,15603],{"class":3637},"        { ",[3383,15605,15606],{"class":3798},"\"X-Request-Id\"",[3383,15608,3731],{"class":3637},[3383,15610,15611],{"class":5132},"Guid",[3383,15613,4760],{"class":3637},[3383,15615,15616],{"class":5166},"NewGuid",[3383,15618,15619],{"class":3637},"().",[3383,15621,15622],{"class":5166},"ToString",[3383,15624,15625],{"class":3637},"() },\n",[3383,15627,15628,15631,15634,15636,15639,15641,15644],{"class":3385,"line":3477},[3383,15629,15630],{"class":5132},"        Accept",[3383,15632,15633],{"class":3637}," = { ",[3383,15635,5276],{"class":3780},[3383,15637,15638],{"class":5103}," MediaTypeWithQualityHeaderValue",[3383,15640,5170],{"class":3637},[3383,15642,15643],{"class":3798},"\"application\u002Fjson\"",[3383,15645,15646],{"class":3637},") }\n",[3383,15648,15649],{"class":3385,"line":3483},[3383,15650,5946],{"class":3637},[3383,15652,15653],{"class":3385,"line":3489},[3383,15654,5326],{"class":3637},[3383,15656,15657],{"class":3385,"line":3495},[3383,15658,3408],{"emptyLinePlaceholder":3407},[3383,15660,15661],{"class":3385,"line":3501},[3383,15662,15663],{"class":5030},"\u002F\u002F Додаємо Authorization (тільки для цього запиту)\n",[3383,15665,15666,15669,15671,15673,15675,15677],{"class":3385,"line":3507},[3383,15667,15668],{"class":5132},"request",[3383,15670,4760],{"class":3637},[3383,15672,6565],{"class":5132},[3383,15674,4760],{"class":3637},[3383,15676,6165],{"class":5132},[3383,15678,15593],{"class":3637},[3383,15680,15681,15684,15687,15689,15692,15694,15696],{"class":3385,"line":3513},[3383,15682,15683],{"class":3780},"    new",[3383,15685,15686],{"class":5103}," AuthenticationHeaderValue",[3383,15688,5170],{"class":3637},[3383,15690,15691],{"class":3798},"\"Bearer\"",[3383,15693,3731],{"class":3637},[3383,15695,9220],{"class":3798},[3383,15697,5176],{"class":3637},[3383,15699,15700],{"class":3385,"line":3519},[3383,15701,3408],{"emptyLinePlaceholder":3407},[3383,15703,15704,15706,15709,15711,15713,15715,15717,15719,15722],{"class":3385,"line":3525},[3383,15705,5100],{"class":3634},[3383,15707,15708],{"class":5103}," HttpResponseMessage",[3383,15710,14609],{"class":5103},[3383,15712,4744],{"class":3637},[3383,15714,14543],{"class":5103},[3383,15716,14484],{"class":5103},[3383,15718,4760],{"class":3637},[3383,15720,15721],{"class":5103},"SendAsync",[3383,15723,15724],{"class":3637},"(\n",[3383,15726,15727,15730],{"class":3385,"line":3531},[3383,15728,15729],{"class":5103},"    request",[3383,15731,5305],{"class":3637},[3383,15733,15734,15737,15739,15742,15744],{"class":3385,"line":3537},[3383,15735,15736],{"class":5103},"    HttpCompletionOption",[3383,15738,4760],{"class":3637},[3383,15740,15741],{"class":5103},"ResponseHeadersRead",[3383,15743,3731],{"class":3637},[3383,15745,15746],{"class":5030},"\u002F\u002F не читаємо тіло одразу\n",[3383,15748,15749,15752,15754],{"class":3385,"line":3543},[3383,15750,15751],{"class":5103},"    CancellationToken",[3383,15753,4760],{"class":3637},[3383,15755,15756],{"class":5103},"None\n",[3383,15758,15759],{"class":3385,"line":3549},[3383,15760,5176],{"class":3637},[3383,15762,15763],{"class":3385,"line":3555},[3383,15764,3408],{"emptyLinePlaceholder":3407},[3383,15766,15767],{"class":3385,"line":3561},[3383,15768,15769],{"class":5030},"\u002F\u002F Потокове читання великого тіла\n",[3383,15771,15772,15774,15777,15780,15783,15785,15787,15789,15791,15793,15795,15798],{"class":3385,"line":3567},[3383,15773,14543],{"class":3780},[3383,15775,15776],{"class":3634}," using",[3383,15778,15779],{"class":5103}," Stream",[3383,15781,15782],{"class":5132}," stream",[3383,15784,4744],{"class":3637},[3383,15786,14543],{"class":3780},[3383,15788,14609],{"class":5132},[3383,15790,4760],{"class":3637},[3383,15792,14734],{"class":5132},[3383,15794,4760],{"class":3637},[3383,15796,15797],{"class":5166},"ReadAsStreamAsync",[3383,15799,14716],{"class":3637},[3383,15801,15802],{"class":3385,"line":3573},[3383,15803,15804],{"class":5030},"\u002F\u002F ... обробка stream\n",[3360,15806],{},[3599,15808,15810],{"id":15809},"ihttpclientfactory-правильний-спосіб-в-di-застосунках","IHttpClientFactory: правильний спосіб в DI-застосунках",[3317,15812,15813,15814,15817,15818,15820,15821,4760],{},"У застосунках на основі ",[3380,15815,15816],{},"Microsoft.Extensions.DependencyInjection"," (ASP.NET Core, Worker Services) слід використовувати ",[3380,15819,14348],{}," замість прямого ",[3380,15822,15823],{},"new HttpClient()",[3370,15825,15826],{},[3373,15827,15829],{"className":3375,"code":15828,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nactor \"Код застосунку\" as app\n\ncomponent \"IHttpClientFactory\" as factory #a5d6a7 {\n    component \"Named Client Pool\" as pool #c8e6c9\n    component \"HttpMessageHandler Pool\\n(керування lifecycle)\" as handlerPool #c8e6c9\n    pool --> handlerPool\n}\n\ncomponent \"HttpClient\" as hc #bbdefb\ncomponent \"HttpMessageHandler\" as hmh #e1bee7\n\napp -> factory : CreateClient(\"MyApi\")\nfactory -> pool : отримати або створити\npool -> hc : новий HttpClient\\n(легкий об'єкт)\nhc --> hmh : посилається\nhandlerPool --> hmh : керує lifecycle\\n(2 хвилини за замовчуванням)\n\nnote right of handlerPool\n    Handler живе 2 хвилини,\n    потім замінюється новим.\n    DNS-зміни підхоплюються.\n    Немає socket exhaustion.\nend note\n\n@enduml\n",[3380,15830,15831,15835,15839,15843,15847,15852,15856,15861,15866,15871,15876,15880,15884,15889,15894,15898,15903,15908,15913,15918,15923,15927,15932,15937,15942,15947,15952,15956,15960],{"__ignoreMap":3378},[3383,15832,15833],{"class":3385,"line":3386},[3383,15834,4064],{},[3383,15836,15837],{"class":3385,"line":3392},[3383,15838,3395],{},[3383,15840,15841],{"class":3385,"line":3398},[3383,15842,3401],{},[3383,15844,15845],{"class":3385,"line":3404},[3383,15846,3408],{"emptyLinePlaceholder":3407},[3383,15848,15849],{"class":3385,"line":3411},[3383,15850,15851],{},"actor \"Код застосунку\" as app\n",[3383,15853,15854],{"class":3385,"line":3417},[3383,15855,3408],{"emptyLinePlaceholder":3407},[3383,15857,15858],{"class":3385,"line":3423},[3383,15859,15860],{},"component \"IHttpClientFactory\" as factory #a5d6a7 {\n",[3383,15862,15863],{"class":3385,"line":3429},[3383,15864,15865],{},"    component \"Named Client Pool\" as pool #c8e6c9\n",[3383,15867,15868],{"class":3385,"line":3435},[3383,15869,15870],{},"    component \"HttpMessageHandler Pool\\n(керування lifecycle)\" as handlerPool #c8e6c9\n",[3383,15872,15873],{"class":3385,"line":3441},[3383,15874,15875],{},"    pool --> handlerPool\n",[3383,15877,15878],{"class":3385,"line":3447},[3383,15879,4091],{},[3383,15881,15882],{"class":3385,"line":3453},[3383,15883,3408],{"emptyLinePlaceholder":3407},[3383,15885,15886],{"class":3385,"line":3459},[3383,15887,15888],{},"component \"HttpClient\" as hc #bbdefb\n",[3383,15890,15891],{"class":3385,"line":3465},[3383,15892,15893],{},"component \"HttpMessageHandler\" as hmh #e1bee7\n",[3383,15895,15896],{"class":3385,"line":3471},[3383,15897,3408],{"emptyLinePlaceholder":3407},[3383,15899,15900],{"class":3385,"line":3477},[3383,15901,15902],{},"app -> factory : CreateClient(\"MyApi\")\n",[3383,15904,15905],{"class":3385,"line":3483},[3383,15906,15907],{},"factory -> pool : отримати або створити\n",[3383,15909,15910],{"class":3385,"line":3489},[3383,15911,15912],{},"pool -> hc : новий HttpClient\\n(легкий об'єкт)\n",[3383,15914,15915],{"class":3385,"line":3495},[3383,15916,15917],{},"hc --> hmh : посилається\n",[3383,15919,15920],{"class":3385,"line":3501},[3383,15921,15922],{},"handlerPool --> hmh : керує lifecycle\\n(2 хвилини за замовчуванням)\n",[3383,15924,15925],{"class":3385,"line":3507},[3383,15926,3408],{"emptyLinePlaceholder":3407},[3383,15928,15929],{"class":3385,"line":3513},[3383,15930,15931],{},"note right of handlerPool\n",[3383,15933,15934],{"class":3385,"line":3519},[3383,15935,15936],{},"    Handler живе 2 хвилини,\n",[3383,15938,15939],{"class":3385,"line":3525},[3383,15940,15941],{},"    потім замінюється новим.\n",[3383,15943,15944],{"class":3385,"line":3531},[3383,15945,15946],{},"    DNS-зміни підхоплюються.\n",[3383,15948,15949],{"class":3385,"line":3537},[3383,15950,15951],{},"    Немає socket exhaustion.\n",[3383,15953,15954],{"class":3385,"line":3543},[3383,15955,4193],{},[3383,15957,15958],{"class":3385,"line":3549},[3383,15959,3408],{"emptyLinePlaceholder":3407},[3383,15961,15962],{"class":3385,"line":3555},[3383,15963,4284],{},[3373,15965,15967],{"className":5090,"code":15966,"language":5092,"meta":5093,"style":3378},"\u002F\u002F Program.cs — реєстрація іменованого клієнта\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.Hosting;\n\nvar builder = Host.CreateApplicationBuilder(args);\n\n\u002F\u002F Реєстрація іменованого HTTP-клієнта\nbuilder.Services.AddHttpClient(\"JsonPlaceholder\", client =>\n{\n    client.BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\");\n    client.DefaultRequestHeaders.Add(\"Accept\", \"application\u002Fjson\");\n    client.Timeout = TimeSpan.FromSeconds(30);\n});\n\n\u002F\u002F Або типізований клієнт (рекомендовано для великих застосунків)\nbuilder.Services.AddHttpClient\u003CITodoService, TodoService>(client =>\n{\n    client.BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\");\n});\n\nvar app = builder.Build();\n\n\u002F\u002F ── У сервісі ────────────────────────────────────────────────────────────────\n\npublic interface ITodoService\n{\n    Task\u003CTodo[]> GetAllAsync(CancellationToken ct = default);\n}\n\npublic sealed class TodoService(HttpClient client) : ITodoService\n{\n    \u002F\u002F HttpClient вже налаштований через AddHttpClient\u003CITodoService, TodoService>\n    public async Task\u003CTodo[]> GetAllAsync(CancellationToken ct = default)\n    {\n        return await client.GetFromJsonAsync\u003CTodo[]>(\"todos\", ct) ?? [];\n    }\n}\n\nrecord Todo(int Id, int UserId, string Title, bool Completed);\n",[3380,15968,15969,15974,15993,16010,16014,16036,16040,16045,16071,16075,16096,16120,16144,16149,16153,16158,16186,16190,16210,16214,16218,16236,16240,16245,16249,16259,16263,16292,16296,16300,16325,16329,16334,16365,16369,16401,16405,16409,16413],{"__ignoreMap":3378},[3383,15970,15971],{"class":3385,"line":3386},[3383,15972,15973],{"class":5030},"\u002F\u002F Program.cs — реєстрація іменованого клієнта\n",[3383,15975,15976,15978,15981,15983,15986,15988,15991],{"class":3385,"line":3392},[3383,15977,5100],{"class":3634},[3383,15979,15980],{"class":5103}," Microsoft",[3383,15982,4760],{"class":3637},[3383,15984,15985],{"class":5103},"Extensions",[3383,15987,4760],{"class":3637},[3383,15989,15990],{"class":5103},"DependencyInjection",[3383,15992,5112],{"class":3637},[3383,15994,15995,15997,15999,16001,16003,16005,16008],{"class":3385,"line":3398},[3383,15996,5100],{"class":3634},[3383,15998,15980],{"class":5103},[3383,16000,4760],{"class":3637},[3383,16002,15985],{"class":5103},[3383,16004,4760],{"class":3637},[3383,16006,16007],{"class":5103},"Hosting",[3383,16009,5112],{"class":3637},[3383,16011,16012],{"class":3385,"line":3404},[3383,16013,3408],{"emptyLinePlaceholder":3407},[3383,16015,16016,16018,16020,16022,16024,16026,16029,16031,16034],{"class":3385,"line":3411},[3383,16017,5268],{"class":3780},[3383,16019,5271],{"class":5132},[3383,16021,4744],{"class":3637},[3383,16023,3884],{"class":5132},[3383,16025,4760],{"class":3637},[3383,16027,16028],{"class":5166},"CreateApplicationBuilder",[3383,16030,5170],{"class":3637},[3383,16032,16033],{"class":5132},"args",[3383,16035,5176],{"class":3637},[3383,16037,16038],{"class":3385,"line":3417},[3383,16039,3408],{"emptyLinePlaceholder":3407},[3383,16041,16042],{"class":3385,"line":3423},[3383,16043,16044],{"class":5030},"\u002F\u002F Реєстрація іменованого HTTP-клієнта\n",[3383,16046,16047,16049,16051,16054,16056,16059,16061,16064,16066,16069],{"class":3385,"line":3429},[3383,16048,5418],{"class":5132},[3383,16050,4760],{"class":3637},[3383,16052,16053],{"class":5132},"Services",[3383,16055,4760],{"class":3637},[3383,16057,16058],{"class":5166},"AddHttpClient",[3383,16060,5170],{"class":3637},[3383,16062,16063],{"class":3798},"\"JsonPlaceholder\"",[3383,16065,3731],{"class":3637},[3383,16067,16068],{"class":5132},"client",[3383,16070,5457],{"class":3637},[3383,16072,16073],{"class":3385,"line":3435},[3383,16074,5292],{"class":3637},[3383,16076,16077,16080,16082,16084,16086,16088,16090,16092,16094],{"class":3385,"line":3441},[3383,16078,16079],{"class":5132},"    client",[3383,16081,4760],{"class":3637},[3383,16083,14387],{"class":5132},[3383,16085,4744],{"class":3637},[3383,16087,5276],{"class":3780},[3383,16089,14507],{"class":5103},[3383,16091,5170],{"class":3637},[3383,16093,14512],{"class":3798},[3383,16095,5176],{"class":3637},[3383,16097,16098,16100,16102,16104,16106,16109,16111,16114,16116,16118],{"class":3385,"line":3447},[3383,16099,16079],{"class":5132},[3383,16101,4760],{"class":3637},[3383,16103,14400],{"class":5132},[3383,16105,4760],{"class":3637},[3383,16107,16108],{"class":5166},"Add",[3383,16110,5170],{"class":3637},[3383,16112,16113],{"class":3798},"\"Accept\"",[3383,16115,3731],{"class":3637},[3383,16117,15643],{"class":3798},[3383,16119,5176],{"class":3637},[3383,16121,16122,16124,16126,16128,16130,16132,16134,16137,16139,16142],{"class":3385,"line":3453},[3383,16123,16079],{"class":5132},[3383,16125,4760],{"class":3637},[3383,16127,14415],{"class":5132},[3383,16129,4744],{"class":3637},[3383,16131,14416],{"class":5132},[3383,16133,4760],{"class":3637},[3383,16135,16136],{"class":5166},"FromSeconds",[3383,16138,5170],{"class":3637},[3383,16140,16141],{"class":3786},"30",[3383,16143,5176],{"class":3637},[3383,16145,16146],{"class":3385,"line":3459},[3383,16147,16148],{"class":3637},"});\n",[3383,16150,16151],{"class":3385,"line":3465},[3383,16152,3408],{"emptyLinePlaceholder":3407},[3383,16154,16155],{"class":3385,"line":3471},[3383,16156,16157],{"class":5030},"\u002F\u002F Або типізований клієнт (рекомендовано для великих застосунків)\n",[3383,16159,16160,16162,16164,16166,16168,16170,16172,16175,16177,16180,16182,16184],{"class":3385,"line":3477},[3383,16161,5418],{"class":5132},[3383,16163,4760],{"class":3637},[3383,16165,16053],{"class":5132},[3383,16167,4760],{"class":3637},[3383,16169,16058],{"class":5166},[3383,16171,3654],{"class":3637},[3383,16173,16174],{"class":5103},"ITodoService",[3383,16176,3731],{"class":3637},[3383,16178,16179],{"class":5103},"TodoService",[3383,16181,14557],{"class":3637},[3383,16183,16068],{"class":5132},[3383,16185,5457],{"class":3637},[3383,16187,16188],{"class":3385,"line":3483},[3383,16189,5292],{"class":3637},[3383,16191,16192,16194,16196,16198,16200,16202,16204,16206,16208],{"class":3385,"line":3489},[3383,16193,16079],{"class":5132},[3383,16195,4760],{"class":3637},[3383,16197,14387],{"class":5132},[3383,16199,4744],{"class":3637},[3383,16201,5276],{"class":3780},[3383,16203,14507],{"class":5103},[3383,16205,5170],{"class":3637},[3383,16207,14512],{"class":3798},[3383,16209,5176],{"class":3637},[3383,16211,16212],{"class":3385,"line":3495},[3383,16213,16148],{"class":3637},[3383,16215,16216],{"class":3385,"line":3501},[3383,16217,3408],{"emptyLinePlaceholder":3407},[3383,16219,16220,16222,16225,16227,16229,16231,16234],{"class":3385,"line":3507},[3383,16221,5268],{"class":3780},[3383,16223,16224],{"class":5132}," app",[3383,16226,4744],{"class":3637},[3383,16228,5418],{"class":5132},[3383,16230,4760],{"class":3637},[3383,16232,16233],{"class":5166},"Build",[3383,16235,14716],{"class":3637},[3383,16237,16238],{"class":3385,"line":3513},[3383,16239,3408],{"emptyLinePlaceholder":3407},[3383,16241,16242],{"class":3385,"line":3519},[3383,16243,16244],{"class":5030},"\u002F\u002F ── У сервісі ────────────────────────────────────────────────────────────────\n",[3383,16246,16247],{"class":3385,"line":3525},[3383,16248,3408],{"emptyLinePlaceholder":3407},[3383,16250,16251,16253,16256],{"class":3385,"line":3531},[3383,16252,13909],{"class":3780},[3383,16254,16255],{"class":3780}," interface",[3383,16257,16258],{"class":5103}," ITodoService\n",[3383,16260,16261],{"class":3385,"line":3537},[3383,16262,5292],{"class":3637},[3383,16264,16265,16268,16270,16272,16275,16278,16280,16282,16285,16287,16290],{"class":3385,"line":3543},[3383,16266,16267],{"class":5103},"    Task",[3383,16269,3654],{"class":3637},[3383,16271,14532],{"class":5103},[3383,16273,16274],{"class":3637},"[]> ",[3383,16276,16277],{"class":5166},"GetAllAsync",[3383,16279,5170],{"class":3637},[3383,16281,14428],{"class":5103},[3383,16283,16284],{"class":5132}," ct",[3383,16286,4744],{"class":3637},[3383,16288,16289],{"class":3780},"default",[3383,16291,5176],{"class":3637},[3383,16293,16294],{"class":3385,"line":3549},[3383,16295,4091],{"class":3637},[3383,16297,16298],{"class":3385,"line":3555},[3383,16299,3408],{"emptyLinePlaceholder":3407},[3383,16301,16302,16304,16307,16310,16313,16315,16317,16319,16322],{"class":3385,"line":3561},[3383,16303,13909],{"class":3780},[3383,16305,16306],{"class":3780}," sealed",[3383,16308,16309],{"class":3780}," class",[3383,16311,16312],{"class":5103}," TodoService",[3383,16314,5170],{"class":3637},[3383,16316,7821],{"class":5103},[3383,16318,14484],{"class":5132},[3383,16320,16321],{"class":3637},") : ",[3383,16323,16324],{"class":5103},"ITodoService\n",[3383,16326,16327],{"class":3385,"line":3567},[3383,16328,5292],{"class":3637},[3383,16330,16331],{"class":3385,"line":3573},[3383,16332,16333],{"class":5030},"    \u002F\u002F HttpClient вже налаштований через AddHttpClient\u003CITodoService, TodoService>\n",[3383,16335,16336,16339,16342,16345,16347,16349,16351,16353,16355,16357,16359,16361,16363],{"class":3385,"line":3579},[3383,16337,16338],{"class":3780},"    public",[3383,16340,16341],{"class":3780}," async",[3383,16343,16344],{"class":5103}," Task",[3383,16346,3654],{"class":3637},[3383,16348,14532],{"class":5103},[3383,16350,16274],{"class":3637},[3383,16352,16277],{"class":5166},[3383,16354,5170],{"class":3637},[3383,16356,14428],{"class":5103},[3383,16358,16284],{"class":5132},[3383,16360,4744],{"class":3637},[3383,16362,16289],{"class":3780},[3383,16364,5287],{"class":3637},[3383,16366,16367],{"class":3385,"line":4215},[3383,16368,15598],{"class":3637},[3383,16370,16371,16374,16377,16379,16381,16383,16385,16387,16390,16393,16395,16398],{"class":3385,"line":4220},[3383,16372,16373],{"class":3634},"        return",[3383,16375,16376],{"class":3780}," await",[3383,16378,14484],{"class":5132},[3383,16380,4760],{"class":3637},[3383,16382,14550],{"class":5166},[3383,16384,3654],{"class":3637},[3383,16386,14532],{"class":5103},[3383,16388,16389],{"class":3637},"[]>(",[3383,16391,16392],{"class":3798},"\"todos\"",[3383,16394,3731],{"class":3637},[3383,16396,16397],{"class":5132},"ct",[3383,16399,16400],{"class":3637},") ?? [];\n",[3383,16402,16403],{"class":3385,"line":4225},[3383,16404,5946],{"class":3637},[3383,16406,16407],{"class":3385,"line":4231},[3383,16408,4091],{"class":3637},[3383,16410,16411],{"class":3385,"line":4237},[3383,16412,3408],{"emptyLinePlaceholder":3407},[3383,16414,16415,16417,16419,16421,16423,16425,16427,16429,16431,16433,16435,16437,16439,16441,16443],{"class":3385,"line":4243},[3383,16416,14765],{"class":3780},[3383,16418,14768],{"class":5103},[3383,16420,5170],{"class":3637},[3383,16422,14773],{"class":3780},[3383,16424,14776],{"class":5132},[3383,16426,3731],{"class":3637},[3383,16428,14773],{"class":3780},[3383,16430,15051],{"class":5132},[3383,16432,3731],{"class":3637},[3383,16434,4709],{"class":3780},[3383,16436,14783],{"class":5132},[3383,16438,3731],{"class":3637},[3383,16440,14788],{"class":3780},[3383,16442,14791],{"class":5132},[3383,16444,5176],{"class":3637},[3360,16446],{},[3312,16448,16450],{"id":16449},"практичний-проєкт-консольний-http-клієнт","Практичний проєкт: Консольний HTTP-клієнт",[3317,16452,16453,16454,16456,16457,4760],{},"Побудуємо простий консольний застосунок, що демонструє всі основні HTTP-операції. Мета — побачити HTTP у дії: реальні запити, реальні статус-коди, реальні відповіді. Ніяких складних патернів — лише ",[3380,16455,7821],{}," і публічний API ",[16458,16459,16463],"a",{"href":16460,"rel":16461},"https:\u002F\u002Fjsonplaceholder.typicode.com",[16462],"nofollow","JSONPlaceholder",[3353,16465,16466,16468,16469,3731,16471,3731,16473,3731,16475,3731,16477,16479,16480,3731,16483,3731,16485,3731,16488,16491],{},[3321,16467,16463],{}," — безкоштовний публічний REST API для тестування. Підтримує ",[3380,16470,3621],{},[3380,16472,3746],{},[3380,16474,8412],{},[3380,16476,8428],{},[3380,16478,7467],{}," для ресурсів ",[3380,16481,16482],{},"\u002Fposts",[3380,16484,4798],{},[3380,16486,16487],{},"\u002Ftodos",[3380,16489,16490],{},"\u002Fcomments",". Зміни не зберігаються на сервері — ідеально для навчання.",[3599,16493,16495],{"id":16494},"що-будуємо","Що будуємо",[3370,16497,16498],{},[3373,16499,16501],{"className":3375,"code":16500,"language":3377,"meta":3378,"style":3378},"@startuml\nskinparam style plain\nskinparam backgroundColor #ffffff\n\nactor \"Консоль\" as console\nparticipant \"Program.cs\" as app #e3f2fd\nparticipant \"jsonplaceholder\\n.typicode.com\" as api #e8f5e9\n\nconsole -> app : запуск\napp -> api : GET \u002Fposts\napi --> app : 200 OK + масив\napp -> console : список перших 3\n\napp -> api : GET \u002Fposts\u002F9999\napi --> app : 404 Not Found\napp -> console : \"не знайдено\"\n\napp -> api : POST \u002Fposts\napi --> app : 201 Created\napp -> console : Новий ID = 101\n\napp -> api : PUT \u002Fposts\u002F1\napi --> app : 200 OK\n\napp -> api : PATCH \u002Fposts\u002F1\napi --> app : 200 OK\n\napp -> api : DELETE \u002Fposts\u002F1\napi --> app : 200 OK\n\n@enduml\n",[3380,16502,16503,16507,16511,16515,16519,16524,16529,16534,16538,16543,16548,16553,16558,16562,16567,16572,16577,16581,16586,16591,16596,16600,16605,16610,16614,16619,16623,16627,16632,16636,16640],{"__ignoreMap":3378},[3383,16504,16505],{"class":3385,"line":3386},[3383,16506,4064],{},[3383,16508,16509],{"class":3385,"line":3392},[3383,16510,3395],{},[3383,16512,16513],{"class":3385,"line":3398},[3383,16514,3401],{},[3383,16516,16517],{"class":3385,"line":3404},[3383,16518,3408],{"emptyLinePlaceholder":3407},[3383,16520,16521],{"class":3385,"line":3411},[3383,16522,16523],{},"actor \"Консоль\" as console\n",[3383,16525,16526],{"class":3385,"line":3417},[3383,16527,16528],{},"participant \"Program.cs\" as app #e3f2fd\n",[3383,16530,16531],{"class":3385,"line":3423},[3383,16532,16533],{},"participant \"jsonplaceholder\\n.typicode.com\" as api #e8f5e9\n",[3383,16535,16536],{"class":3385,"line":3429},[3383,16537,3408],{"emptyLinePlaceholder":3407},[3383,16539,16540],{"class":3385,"line":3435},[3383,16541,16542],{},"console -> app : запуск\n",[3383,16544,16545],{"class":3385,"line":3441},[3383,16546,16547],{},"app -> api : GET \u002Fposts\n",[3383,16549,16550],{"class":3385,"line":3447},[3383,16551,16552],{},"api --> app : 200 OK + масив\n",[3383,16554,16555],{"class":3385,"line":3453},[3383,16556,16557],{},"app -> console : список перших 3\n",[3383,16559,16560],{"class":3385,"line":3459},[3383,16561,3408],{"emptyLinePlaceholder":3407},[3383,16563,16564],{"class":3385,"line":3465},[3383,16565,16566],{},"app -> api : GET \u002Fposts\u002F9999\n",[3383,16568,16569],{"class":3385,"line":3471},[3383,16570,16571],{},"api --> app : 404 Not Found\n",[3383,16573,16574],{"class":3385,"line":3477},[3383,16575,16576],{},"app -> console : \"не знайдено\"\n",[3383,16578,16579],{"class":3385,"line":3483},[3383,16580,3408],{"emptyLinePlaceholder":3407},[3383,16582,16583],{"class":3385,"line":3489},[3383,16584,16585],{},"app -> api : POST \u002Fposts\n",[3383,16587,16588],{"class":3385,"line":3495},[3383,16589,16590],{},"api --> app : 201 Created\n",[3383,16592,16593],{"class":3385,"line":3501},[3383,16594,16595],{},"app -> console : Новий ID = 101\n",[3383,16597,16598],{"class":3385,"line":3507},[3383,16599,3408],{"emptyLinePlaceholder":3407},[3383,16601,16602],{"class":3385,"line":3513},[3383,16603,16604],{},"app -> api : PUT \u002Fposts\u002F1\n",[3383,16606,16607],{"class":3385,"line":3519},[3383,16608,16609],{},"api --> app : 200 OK\n",[3383,16611,16612],{"class":3385,"line":3525},[3383,16613,3408],{"emptyLinePlaceholder":3407},[3383,16615,16616],{"class":3385,"line":3531},[3383,16617,16618],{},"app -> api : PATCH \u002Fposts\u002F1\n",[3383,16620,16621],{"class":3385,"line":3537},[3383,16622,16609],{},[3383,16624,16625],{"class":3385,"line":3543},[3383,16626,3408],{"emptyLinePlaceholder":3407},[3383,16628,16629],{"class":3385,"line":3549},[3383,16630,16631],{},"app -> api : DELETE \u002Fposts\u002F1\n",[3383,16633,16634],{"class":3385,"line":3555},[3383,16635,16609],{},[3383,16637,16638],{"class":3385,"line":3561},[3383,16639,3408],{"emptyLinePlaceholder":3407},[3383,16641,16642],{"class":3385,"line":3567},[3383,16643,4284],{},[3599,16645,16647],{"id":16646},"кроки","Кроки",[3604,16649,16650,16654,16685,16689,16696,16700],{},[3599,16651,16653],{"id":16652},"створюємо-проєкт","Створюємо проєкт",[3373,16655,16659],{"className":16656,"code":16657,"language":16658,"meta":3378,"style":3378},"language-bash shiki shiki-themes light-plus dark-plus dark-plus","dotnet new console -n PostsExplorer\ncd PostsExplorer\n","bash",[3380,16660,16661,16678],{"__ignoreMap":3378},[3383,16662,16663,16666,16669,16672,16675],{"class":3385,"line":3386},[3383,16664,16665],{"class":5166},"dotnet",[3383,16667,16668],{"class":3798}," new",[3383,16670,16671],{"class":3798}," console",[3383,16673,16674],{"class":3780}," -n",[3383,16676,16677],{"class":3798}," PostsExplorer\n",[3383,16679,16680,16683],{"class":3385,"line":3392},[3383,16681,16682],{"class":5166},"cd",[3383,16684,16677],{"class":3798},[3599,16686,16688],{"id":16687},"замінюємо-programcs","Замінюємо Program.cs",[3317,16690,16691,16692,16695],{},"Вставте код нижче у ",[3380,16693,16694],{},"Program.cs"," — більше жодних файлів не потрібно.",[3599,16697,16699],{"id":16698},"запускаємо","Запускаємо",[3373,16701,16703],{"className":16656,"code":16702,"language":16658,"meta":3378,"style":3378},"dotnet run\n",[3380,16704,16705],{"__ignoreMap":3378},[3383,16706,16707,16709],{"class":3385,"line":3386},[3383,16708,16665],{"class":5166},[3383,16710,16711],{"class":3798}," run\n",[3599,16713,16694],{"id":16714},"programcs",[3373,16716,16718],{"className":5090,"code":16717,"language":5092,"meta":5093,"style":3378},"\u002F\u002F Program.cs — Posts Explorer\n\u002F\u002F Демонструє всі HTTP-методи через HttpClient на JSONPlaceholder API\nusing System.Net;\nusing System.Net.Http.Json;\n\n\u002F\u002F ── Один HttpClient на весь застосунок ──────────────────────────────────────\n\u002F\u002F Правило: не створюйте new HttpClient() для кожного запиту!\n\u002F\u002F Це призводить до вичерпання портів (socket exhaustion).\nvar http = new HttpClient\n{\n    BaseAddress = new Uri(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002F\"),\n    Timeout = TimeSpan.FromSeconds(15)\n};\n\n\u002F\u002F Content negotiation: кажемо серверу, що приймаємо JSON\nhttp.DefaultRequestHeaders.Add(\"Accept\", \"application\u002Fjson\");\n\nHeader(\"Posts Explorer — HTTP Demo\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 1. GET \u002Fposts — отримати колекцію\n\u002F\u002F    HTTP GET: безпечний + ідемпотентний, без тіла запиту\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"1. GET \u002Fposts — список постів\");\nHttpResponseMessage r1 = await http.GetAsync(\"posts\");\nPrintStatus(r1);\n\nPost[]? allPosts = await r1.Content.ReadFromJsonAsync\u003CPost[]>();\nConsole.WriteLine($\"   Отримано постів: {allPosts?.Length}. Перші 3:\");\nforeach (Post p in allPosts?.Take(3) ?? [])\n    Console.WriteLine($\"   [{p.Id,3}] {p.Title[..Math.Min(50, p.Title.Length)]}\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 2. GET \u002Fposts\u002F1 — отримати конкретний ресурс\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"2. GET \u002Fposts\u002F1 — один ресурс\");\nHttpResponseMessage r2 = await http.GetAsync(\"posts\u002F1\");\nPrintStatus(r2);\nPost? single = await r2.Content.ReadFromJsonAsync\u003CPost>();\nConsole.WriteLine($\"   Title: {single?.Title}\");\nConsole.WriteLine($\"   Body:  {single?.Body[..50]}...\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 3. GET \u002Fposts\u002F9999 — ресурс не існує → 404\n\u002F\u002F    Обробляємо 404 явно, без виключення\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"3. GET \u002Fposts\u002F9999 — обробка 404\");\nHttpResponseMessage r3 = await http.GetAsync(\"posts\u002F9999\");\nPrintStatus(r3);\nif (r3.StatusCode == HttpStatusCode.NotFound)\n    Console.WriteLine(\"   → Ресурс не знайдено. 404 оброблено gracefully.\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 4. POST \u002Fposts — створити ресурс\n\u002F\u002F    HTTP POST: не ідемпотентний, сервер повертає 201 + Location header\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"4. POST \u002Fposts — створити пост\");\nvar newPost = new PostInput(\"Мій перший HTTP-пост\", \"Навчаюсь HTTP в C#!\", UserId: 1);\nHttpResponseMessage r4 = await http.PostAsJsonAsync(\"posts\", newPost);\nPrintStatus(r4);\n\u002F\u002F 201 Created: перевіряємо Location header з URL нового ресурсу\nConsole.WriteLine($\"   Location: {r4.Headers.Location}\");\nPost? created = await r4.Content.ReadFromJsonAsync\u003CPost>();\nConsole.WriteLine($\"   Новий ID: {created?.Id}\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 5. PUT \u002Fposts\u002F1 — повна заміна ресурсу\n\u002F\u002F    HTTP PUT: ідемпотентний, передаємо ВСІ поля\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"5. PUT \u002Fposts\u002F1 — повна заміна\");\nvar replacement = new Post(1, 1, \"Повністю замінений заголовок\", \"Весь текст змінено\");\nHttpResponseMessage r5 = await http.PutAsJsonAsync(\"posts\u002F1\", replacement);\nPrintStatus(r5);\nPost? replaced = await r5.Content.ReadFromJsonAsync\u003CPost>();\nConsole.WriteLine($\"   Title: {replaced?.Title}\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 6. PATCH \u002Fposts\u002F1 — часткове оновлення\n\u002F\u002F    Надсилаємо ТІЛЬКИ поля, що змінились\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"6. PATCH \u002Fposts\u002F1 — оновити лише title\");\nvar patch = new { title = \"Оновлений через PATCH\" };\nHttpResponseMessage r6 = await http.PatchAsync(\"posts\u002F1\", JsonContent.Create(patch));\nPrintStatus(r6);\nPost? patched = await r6.Content.ReadFromJsonAsync\u003CPost>();\nConsole.WriteLine($\"   Title: {patched?.Title}\");\nConsole.WriteLine($\"   Body залишився: {patched?.Body[..40]}...\");\n\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n\u002F\u002F 7. DELETE \u002Fposts\u002F1 — видалити ресурс\n\u002F\u002F    HTTP DELETE: ідемпотентний — повторний виклик не змінить стан\n\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\nSection(\"7. DELETE \u002Fposts\u002F1 — видалити\");\nHttpResponseMessage r7 = await http.DeleteAsync(\"posts\u002F1\");\nPrintStatus(r7);\nConsole.WriteLine(r7.IsSuccessStatusCode ? \"   ✓ Видалено\" : \"   ✗ Помилка\");\n\nHeader(\"Готово! Всі HTTP-методи виконано.\");\n\n\u002F\u002F ── Допоміжні методи ──────────────────────────────────────────────────────────\nvoid Header(string msg)\n{\n    Console.WriteLine();\n    Console.WriteLine(new string('═', 48));\n    Console.WriteLine($\"  {msg}\");\n    Console.WriteLine(new string('═', 48));\n}\n\nvoid Section(string title)\n{\n    Console.WriteLine();\n    Console.ForegroundColor = ConsoleColor.Cyan;\n    Console.WriteLine($\"▶ {title}\");\n    Console.ResetColor();\n}\n\nvoid PrintStatus(HttpResponseMessage response)\n{\n    int code = (int)response.StatusCode;\n    Console.ForegroundColor = code switch\n    {\n        >= 200 and \u003C 300 => ConsoleColor.Green,\n        >= 300 and \u003C 400 => ConsoleColor.Yellow,\n        _                => ConsoleColor.Red\n    };\n    Console.Write($\"   HTTP {code} {response.StatusCode}\");\n    Console.ResetColor();\n    Console.WriteLine($\"  ← {response.RequestMessage?.Method} {response.RequestMessage?.RequestUri?.PathAndQuery}\");\n}\n\n\u002F\u002F ── Моделі ────────────────────────────────────────────────────────────────────\nrecord Post(int Id, int UserId, string Title, string Body);\nrecord PostInput(string Title, string Body, int UserId);\n",[3380,16719,16720,16725,16730,16742,16762,16766,16771,16776,16781,16794,16798,16814,16833,16837,16841,16846,16868,16872,16884,16888,16893,16898,16903,16907,16919,16942,16954,16958,16989,17020,17052,17128,17132,17136,17141,17145,17156,17179,17190,17219,17248,17285,17289,17293,17298,17303,17307,17318,17342,17353,17375,17390,17394,17398,17403,17408,17412,17423,17457,17484,17495,17500,17531,17559,17588,17592,17596,17601,17606,17611,17623,17657,17686,17698,17728,17757,17762,17767,17773,17779,17784,17796,17819,17855,17867,17897,17926,17963,17968,17973,17979,17985,17990,18002,18026,18038,18070,18075,18087,18092,18098,18116,18121,18132,18160,18185,18210,18215,18220,18237,18242,18253,18275,18299,18311,18316,18321,18337,18342,18366,18382,18387,18417,18441,18457,18463,18499,18510,18570,18575,18580,18586,18619],{"__ignoreMap":3378},[3383,16721,16722],{"class":3385,"line":3386},[3383,16723,16724],{"class":5030},"\u002F\u002F Program.cs — Posts Explorer\n",[3383,16726,16727],{"class":3385,"line":3392},[3383,16728,16729],{"class":5030},"\u002F\u002F Демонструє всі HTTP-методи через HttpClient на JSONPlaceholder API\n",[3383,16731,16732,16734,16736,16738,16740],{"class":3385,"line":3398},[3383,16733,5100],{"class":3634},[3383,16735,5104],{"class":5103},[3383,16737,4760],{"class":3637},[3383,16739,5109],{"class":5103},[3383,16741,5112],{"class":3637},[3383,16743,16744,16746,16748,16750,16752,16754,16756,16758,16760],{"class":3385,"line":3404},[3383,16745,5100],{"class":3634},[3383,16747,5104],{"class":5103},[3383,16749,4760],{"class":3637},[3383,16751,5109],{"class":5103},[3383,16753,4760],{"class":3637},[3383,16755,14458],{"class":5103},[3383,16757,4760],{"class":3637},[3383,16759,14463],{"class":5103},[3383,16761,5112],{"class":3637},[3383,16763,16764],{"class":3385,"line":3411},[3383,16765,3408],{"emptyLinePlaceholder":3407},[3383,16767,16768],{"class":3385,"line":3417},[3383,16769,16770],{"class":5030},"\u002F\u002F ── Один HttpClient на весь застосунок ──────────────────────────────────────\n",[3383,16772,16773],{"class":3385,"line":3423},[3383,16774,16775],{"class":5030},"\u002F\u002F Правило: не створюйте new HttpClient() для кожного запиту!\n",[3383,16777,16778],{"class":3385,"line":3429},[3383,16779,16780],{"class":5030},"\u002F\u002F Це призводить до вичерпання портів (socket exhaustion).\n",[3383,16782,16783,16785,16788,16790,16792],{"class":3385,"line":3435},[3383,16784,5268],{"class":3780},[3383,16786,16787],{"class":5132}," http",[3383,16789,4744],{"class":3637},[3383,16791,5276],{"class":3780},[3383,16793,14491],{"class":5103},[3383,16795,16796],{"class":3385,"line":3441},[3383,16797,5292],{"class":3637},[3383,16799,16800,16802,16804,16806,16808,16810,16812],{"class":3385,"line":3447},[3383,16801,14500],{"class":5132},[3383,16803,4744],{"class":3637},[3383,16805,5276],{"class":3780},[3383,16807,14507],{"class":5103},[3383,16809,5170],{"class":3637},[3383,16811,14512],{"class":3798},[3383,16813,15559],{"class":3637},[3383,16815,16816,16819,16821,16823,16825,16827,16829,16831],{"class":3385,"line":3453},[3383,16817,16818],{"class":5132},"    Timeout",[3383,16820,4744],{"class":3637},[3383,16822,14416],{"class":5132},[3383,16824,4760],{"class":3637},[3383,16826,16136],{"class":5166},[3383,16828,5170],{"class":3637},[3383,16830,10289],{"class":3786},[3383,16832,5287],{"class":3637},[3383,16834,16835],{"class":3385,"line":3459},[3383,16836,5326],{"class":3637},[3383,16838,16839],{"class":3385,"line":3465},[3383,16840,3408],{"emptyLinePlaceholder":3407},[3383,16842,16843],{"class":3385,"line":3471},[3383,16844,16845],{"class":5030},"\u002F\u002F Content negotiation: кажемо серверу, що приймаємо JSON\n",[3383,16847,16848,16850,16852,16854,16856,16858,16860,16862,16864,16866],{"class":3385,"line":3477},[3383,16849,3627],{"class":5132},[3383,16851,4760],{"class":3637},[3383,16853,14400],{"class":5132},[3383,16855,4760],{"class":3637},[3383,16857,16108],{"class":5166},[3383,16859,5170],{"class":3637},[3383,16861,16113],{"class":3798},[3383,16863,3731],{"class":3637},[3383,16865,15643],{"class":3798},[3383,16867,5176],{"class":3637},[3383,16869,16870],{"class":3385,"line":3483},[3383,16871,3408],{"emptyLinePlaceholder":3407},[3383,16873,16874,16877,16879,16882],{"class":3385,"line":3489},[3383,16875,16876],{"class":5166},"Header",[3383,16878,5170],{"class":3637},[3383,16880,16881],{"class":3798},"\"Posts Explorer — HTTP Demo\"",[3383,16883,5176],{"class":3637},[3383,16885,16886],{"class":3385,"line":3495},[3383,16887,3408],{"emptyLinePlaceholder":3407},[3383,16889,16890],{"class":3385,"line":3501},[3383,16891,16892],{"class":5030},"\u002F\u002F ══════════════════════════════════════════════════════════════════════════════\n",[3383,16894,16895],{"class":3385,"line":3507},[3383,16896,16897],{"class":5030},"\u002F\u002F 1. GET \u002Fposts — отримати колекцію\n",[3383,16899,16900],{"class":3385,"line":3513},[3383,16901,16902],{"class":5030},"\u002F\u002F    HTTP GET: безпечний + ідемпотентний, без тіла запиту\n",[3383,16904,16905],{"class":3385,"line":3519},[3383,16906,16892],{"class":5030},[3383,16908,16909,16912,16914,16917],{"class":3385,"line":3525},[3383,16910,16911],{"class":5166},"Section",[3383,16913,5170],{"class":3637},[3383,16915,16916],{"class":3798},"\"1. GET \u002Fposts — список постів\"",[3383,16918,5176],{"class":3637},[3383,16920,16921,16923,16926,16928,16930,16932,16934,16936,16938,16940],{"class":3385,"line":3531},[3383,16922,14606],{"class":5103},[3383,16924,16925],{"class":5132}," r1",[3383,16927,4744],{"class":3637},[3383,16929,14543],{"class":3780},[3383,16931,16787],{"class":5132},[3383,16933,4760],{"class":3637},[3383,16935,14620],{"class":5166},[3383,16937,5170],{"class":3637},[3383,16939,14933],{"class":3798},[3383,16941,5176],{"class":3637},[3383,16943,16944,16947,16949,16952],{"class":3385,"line":3537},[3383,16945,16946],{"class":5166},"PrintStatus",[3383,16948,5170],{"class":3637},[3383,16950,16951],{"class":5132},"r1",[3383,16953,5176],{"class":3637},[3383,16955,16956],{"class":3385,"line":3543},[3383,16957,3408],{"emptyLinePlaceholder":3407},[3383,16959,16960,16962,16965,16968,16970,16972,16974,16976,16978,16980,16982,16984,16986],{"class":3385,"line":3549},[3383,16961,14964],{"class":5103},[3383,16963,16964],{"class":3637},"[]? ",[3383,16966,16967],{"class":5132},"allPosts",[3383,16969,4744],{"class":3637},[3383,16971,14543],{"class":3780},[3383,16973,16925],{"class":5132},[3383,16975,4760],{"class":3637},[3383,16977,14734],{"class":5132},[3383,16979,4760],{"class":3637},[3383,16981,14984],{"class":5166},[3383,16983,3654],{"class":3637},[3383,16985,14964],{"class":5103},[3383,16987,16988],{"class":3637},"[]>();\n",[3383,16990,16991,16993,16995,16997,16999,17002,17004,17006,17008,17010,17013,17015,17018],{"class":3385,"line":3555},[3383,16992,5520],{"class":5132},[3383,16994,4760],{"class":3637},[3383,16996,5525],{"class":5166},[3383,16998,5170],{"class":3637},[3383,17000,17001],{"class":3798},"$\"   Отримано постів: ",[3383,17003,5466],{"class":5465},[3383,17005,16967],{"class":5132},[3383,17007,4827],{"class":3637},[3383,17009,4760],{"class":5465},[3383,17011,17012],{"class":5132},"Length",[3383,17014,5583],{"class":5465},[3383,17016,17017],{"class":3798},". Перші 3:\"",[3383,17019,5176],{"class":3637},[3383,17021,17022,17025,17027,17029,17032,17035,17038,17041,17044,17046,17049],{"class":3385,"line":3561},[3383,17023,17024],{"class":3634},"foreach",[3383,17026,3727],{"class":3637},[3383,17028,14964],{"class":5103},[3383,17030,17031],{"class":5132}," p",[3383,17033,17034],{"class":3634}," in",[3383,17036,17037],{"class":5132}," allPosts",[3383,17039,17040],{"class":3637},"?.",[3383,17042,17043],{"class":5166},"Take",[3383,17045,5170],{"class":3637},[3383,17047,17048],{"class":3786},"3",[3383,17050,17051],{"class":3637},") ?? [])\n",[3383,17053,17054,17056,17058,17060,17062,17065,17067,17069,17071,17073,17076,17078,17080,17083,17085,17087,17089,17091,17094,17096,17099,17101,17104,17106,17109,17111,17113,17115,17117,17119,17121,17124,17126],{"class":3385,"line":3567},[3383,17055,14673],{"class":5132},[3383,17057,4760],{"class":3637},[3383,17059,5525],{"class":5166},[3383,17061,5170],{"class":3637},[3383,17063,17064],{"class":3798},"$\"   [",[3383,17066,5466],{"class":5465},[3383,17068,3317],{"class":5132},[3383,17070,4760],{"class":5465},[3383,17072,15015],{"class":5132},[3383,17074,17075],{"class":5465},",",[3383,17077,17048],{"class":3786},[3383,17079,5583],{"class":5465},[3383,17081,17082],{"class":3798},"] ",[3383,17084,5466],{"class":5465},[3383,17086,3317],{"class":5132},[3383,17088,4760],{"class":5465},[3383,17090,14586],{"class":5132},[3383,17092,17093],{"class":5465},"[",[3383,17095,4784],{"class":3637},[3383,17097,17098],{"class":5132},"Math",[3383,17100,4760],{"class":5465},[3383,17102,17103],{"class":5166},"Min",[3383,17105,5170],{"class":5465},[3383,17107,17108],{"class":3786},"50",[3383,17110,3731],{"class":5465},[3383,17112,3317],{"class":5132},[3383,17114,4760],{"class":5465},[3383,17116,14586],{"class":5132},[3383,17118,4760],{"class":5465},[3383,17120,17012],{"class":5132},[3383,17122,17123],{"class":5465},")]}",[3383,17125,5508],{"class":3798},[3383,17127,5176],{"class":3637},[3383,17129,17130],{"class":3385,"line":3573},[3383,17131,3408],{"emptyLinePlaceholder":3407},[3383,17133,17134],{"class":3385,"line":3579},[3383,17135,16892],{"class":5030},[3383,17137,17138],{"class":3385,"line":4215},[3383,17139,17140],{"class":5030},"\u002F\u002F 2. GET \u002Fposts\u002F1 — отримати конкретний ресурс\n",[3383,17142,17143],{"class":3385,"line":4220},[3383,17144,16892],{"class":5030},[3383,17146,17147,17149,17151,17154],{"class":3385,"line":4225},[3383,17148,16911],{"class":5166},[3383,17150,5170],{"class":3637},[3383,17152,17153],{"class":3798},"\"2. GET \u002Fposts\u002F1 — один ресурс\"",[3383,17155,5176],{"class":3637},[3383,17157,17158,17160,17163,17165,17167,17169,17171,17173,17175,17177],{"class":3385,"line":4231},[3383,17159,14606],{"class":5103},[3383,17161,17162],{"class":5132}," r2",[3383,17164,4744],{"class":3637},[3383,17166,14543],{"class":3780},[3383,17168,16787],{"class":5132},[3383,17170,4760],{"class":3637},[3383,17172,14620],{"class":5166},[3383,17174,5170],{"class":3637},[3383,17176,15221],{"class":3798},[3383,17178,5176],{"class":3637},[3383,17180,17181,17183,17185,17188],{"class":3385,"line":4237},[3383,17182,16946],{"class":5166},[3383,17184,5170],{"class":3637},[3383,17186,17187],{"class":5132},"r2",[3383,17189,5176],{"class":3637},[3383,17191,17192,17194,17196,17199,17201,17203,17205,17207,17209,17211,17213,17215,17217],{"class":3385,"line":4243},[3383,17193,14964],{"class":5103},[3383,17195,14535],{"class":3637},[3383,17197,17198],{"class":5132},"single",[3383,17200,4744],{"class":3637},[3383,17202,14543],{"class":3780},[3383,17204,17162],{"class":5132},[3383,17206,4760],{"class":3637},[3383,17208,14734],{"class":5132},[3383,17210,4760],{"class":3637},[3383,17212,14984],{"class":5166},[3383,17214,3654],{"class":3637},[3383,17216,14964],{"class":5103},[3383,17218,14991],{"class":3637},[3383,17220,17221,17223,17225,17227,17229,17232,17234,17236,17238,17240,17242,17244,17246],{"class":3385,"line":4248},[3383,17222,5520],{"class":5132},[3383,17224,4760],{"class":3637},[3383,17226,5525],{"class":5166},[3383,17228,5170],{"class":3637},[3383,17230,17231],{"class":3798},"$\"   Title: ",[3383,17233,5466],{"class":5465},[3383,17235,17198],{"class":5132},[3383,17237,4827],{"class":3637},[3383,17239,4760],{"class":5465},[3383,17241,14586],{"class":5132},[3383,17243,5583],{"class":5465},[3383,17245,5508],{"class":3798},[3383,17247,5176],{"class":3637},[3383,17249,17250,17252,17254,17256,17258,17261,17263,17265,17267,17269,17271,17273,17275,17277,17280,17283],{"class":3385,"line":4253},[3383,17251,5520],{"class":5132},[3383,17253,4760],{"class":3637},[3383,17255,5525],{"class":5166},[3383,17257,5170],{"class":3637},[3383,17259,17260],{"class":3798},"$\"   Body:  ",[3383,17262,5466],{"class":5465},[3383,17264,17198],{"class":5132},[3383,17266,4827],{"class":3637},[3383,17268,4760],{"class":5465},[3383,17270,6579],{"class":5132},[3383,17272,17093],{"class":5465},[3383,17274,4784],{"class":3637},[3383,17276,17108],{"class":3786},[3383,17278,17279],{"class":5465},"]}",[3383,17281,17282],{"class":3798},"...\"",[3383,17284,5176],{"class":3637},[3383,17286,17287],{"class":3385,"line":4259},[3383,17288,3408],{"emptyLinePlaceholder":3407},[3383,17290,17291],{"class":3385,"line":4265},[3383,17292,16892],{"class":5030},[3383,17294,17295],{"class":3385,"line":4271},[3383,17296,17297],{"class":5030},"\u002F\u002F 3. GET \u002Fposts\u002F9999 — ресурс не існує → 404\n",[3383,17299,17300],{"class":3385,"line":4276},[3383,17301,17302],{"class":5030},"\u002F\u002F    Обробляємо 404 явно, без виключення\n",[3383,17304,17305],{"class":3385,"line":4281},[3383,17306,16892],{"class":5030},[3383,17308,17309,17311,17313,17316],{"class":3385,"line":4540},[3383,17310,16911],{"class":5166},[3383,17312,5170],{"class":3637},[3383,17314,17315],{"class":3798},"\"3. GET \u002Fposts\u002F9999 — обробка 404\"",[3383,17317,5176],{"class":3637},[3383,17319,17320,17322,17325,17327,17329,17331,17333,17335,17337,17340],{"class":3385,"line":4545},[3383,17321,14606],{"class":5103},[3383,17323,17324],{"class":5132}," r3",[3383,17326,4744],{"class":3637},[3383,17328,14543],{"class":3780},[3383,17330,16787],{"class":5132},[3383,17332,4760],{"class":3637},[3383,17334,14620],{"class":5166},[3383,17336,5170],{"class":3637},[3383,17338,17339],{"class":3798},"\"posts\u002F9999\"",[3383,17341,5176],{"class":3637},[3383,17343,17344,17346,17348,17351],{"class":3385,"line":4551},[3383,17345,16946],{"class":5166},[3383,17347,5170],{"class":3637},[3383,17349,17350],{"class":5132},"r3",[3383,17352,5176],{"class":3637},[3383,17354,17355,17357,17359,17361,17363,17365,17367,17369,17371,17373],{"class":3385,"line":4557},[3383,17356,14632],{"class":3634},[3383,17358,3727],{"class":3637},[3383,17360,17350],{"class":5132},[3383,17362,4760],{"class":3637},[3383,17364,14642],{"class":5132},[3383,17366,14645],{"class":3637},[3383,17368,14657],{"class":5132},[3383,17370,4760],{"class":3637},[3383,17372,14662],{"class":5132},[3383,17374,5287],{"class":3637},[3383,17376,17377,17379,17381,17383,17385,17388],{"class":3385,"line":4563},[3383,17378,14673],{"class":5132},[3383,17380,4760],{"class":3637},[3383,17382,5525],{"class":5166},[3383,17384,5170],{"class":3637},[3383,17386,17387],{"class":3798},"\"   → Ресурс не знайдено. 404 оброблено gracefully.\"",[3383,17389,5176],{"class":3637},[3383,17391,17392],{"class":3385,"line":4569},[3383,17393,3408],{"emptyLinePlaceholder":3407},[3383,17395,17396],{"class":3385,"line":4574},[3383,17397,16892],{"class":5030},[3383,17399,17400],{"class":3385,"line":4579},[3383,17401,17402],{"class":5030},"\u002F\u002F 4. POST \u002Fposts — створити ресурс\n",[3383,17404,17405],{"class":3385,"line":4585},[3383,17406,17407],{"class":5030},"\u002F\u002F    HTTP POST: не ідемпотентний, сервер повертає 201 + Location header\n",[3383,17409,17410],{"class":3385,"line":4591},[3383,17411,16892],{"class":5030},[3383,17413,17414,17416,17418,17421],{"class":3385,"line":4597},[3383,17415,16911],{"class":5166},[3383,17417,5170],{"class":3637},[3383,17419,17420],{"class":3798},"\"4. POST \u002Fposts — створити пост\"",[3383,17422,5176],{"class":3637},[3383,17424,17425,17427,17429,17431,17433,17436,17438,17441,17443,17446,17448,17451,17453,17455],{"class":3385,"line":4603},[3383,17426,5268],{"class":3780},[3383,17428,14879],{"class":5132},[3383,17430,4744],{"class":3637},[3383,17432,5276],{"class":3780},[3383,17434,17435],{"class":5103}," PostInput",[3383,17437,5170],{"class":3637},[3383,17439,17440],{"class":3798},"\"Мій перший HTTP-пост\"",[3383,17442,3731],{"class":3637},[3383,17444,17445],{"class":3798},"\"Навчаюсь HTTP в C#!\"",[3383,17447,3731],{"class":3637},[3383,17449,17450],{"class":5132},"UserId",[3383,17452,6438],{"class":3637},[3383,17454,5316],{"class":3786},[3383,17456,5176],{"class":3637},[3383,17458,17459,17461,17464,17466,17468,17470,17472,17474,17476,17478,17480,17482],{"class":3385,"line":4608},[3383,17460,14606],{"class":5103},[3383,17462,17463],{"class":5132}," r4",[3383,17465,4744],{"class":3637},[3383,17467,14543],{"class":3780},[3383,17469,16787],{"class":5132},[3383,17471,4760],{"class":3637},[3383,17473,14928],{"class":5166},[3383,17475,5170],{"class":3637},[3383,17477,14933],{"class":3798},[3383,17479,3731],{"class":3637},[3383,17481,14938],{"class":5132},[3383,17483,5176],{"class":3637},[3383,17485,17486,17488,17490,17493],{"class":3385,"line":4613},[3383,17487,16946],{"class":5166},[3383,17489,5170],{"class":3637},[3383,17491,17492],{"class":5132},"r4",[3383,17494,5176],{"class":3637},[3383,17496,17497],{"class":3385,"line":4619},[3383,17498,17499],{"class":5030},"\u002F\u002F 201 Created: перевіряємо Location header з URL нового ресурсу\n",[3383,17501,17502,17504,17506,17508,17510,17513,17515,17517,17519,17521,17523,17525,17527,17529],{"class":3385,"line":4625},[3383,17503,5520],{"class":5132},[3383,17505,4760],{"class":3637},[3383,17507,5525],{"class":5166},[3383,17509,5170],{"class":3637},[3383,17511,17512],{"class":3798},"$\"   Location: ",[3383,17514,5466],{"class":5465},[3383,17516,17492],{"class":5132},[3383,17518,4760],{"class":5465},[3383,17520,6565],{"class":5132},[3383,17522,4760],{"class":5465},[3383,17524,7191],{"class":5132},[3383,17526,5583],{"class":5465},[3383,17528,5508],{"class":3798},[3383,17530,5176],{"class":3637},[3383,17532,17533,17535,17537,17539,17541,17543,17545,17547,17549,17551,17553,17555,17557],{"class":3385,"line":4631},[3383,17534,14964],{"class":5103},[3383,17536,14535],{"class":3637},[3383,17538,14969],{"class":5132},[3383,17540,4744],{"class":3637},[3383,17542,14543],{"class":3780},[3383,17544,17463],{"class":5132},[3383,17546,4760],{"class":3637},[3383,17548,14734],{"class":5132},[3383,17550,4760],{"class":3637},[3383,17552,14984],{"class":5166},[3383,17554,3654],{"class":3637},[3383,17556,14964],{"class":5103},[3383,17558,14991],{"class":3637},[3383,17560,17561,17563,17565,17567,17569,17572,17574,17576,17578,17580,17582,17584,17586],{"class":3385,"line":4637},[3383,17562,5520],{"class":5132},[3383,17564,4760],{"class":3637},[3383,17566,5525],{"class":5166},[3383,17568,5170],{"class":3637},[3383,17570,17571],{"class":3798},"$\"   Новий ID: ",[3383,17573,5466],{"class":5465},[3383,17575,14969],{"class":5132},[3383,17577,4827],{"class":3637},[3383,17579,4760],{"class":5465},[3383,17581,15015],{"class":5132},[3383,17583,5583],{"class":5465},[3383,17585,5508],{"class":3798},[3383,17587,5176],{"class":3637},[3383,17589,17590],{"class":3385,"line":4642},[3383,17591,3408],{"emptyLinePlaceholder":3407},[3383,17593,17594],{"class":3385,"line":4647},[3383,17595,16892],{"class":5030},[3383,17597,17598],{"class":3385,"line":14322},[3383,17599,17600],{"class":5030},"\u002F\u002F 5. PUT \u002Fposts\u002F1 — повна заміна ресурсу\n",[3383,17602,17603],{"class":3385,"line":14327},[3383,17604,17605],{"class":5030},"\u002F\u002F    HTTP PUT: ідемпотентний, передаємо ВСІ поля\n",[3383,17607,17609],{"class":3385,"line":17608},69,[3383,17610,16892],{"class":5030},[3383,17612,17614,17616,17618,17621],{"class":3385,"line":17613},70,[3383,17615,16911],{"class":5166},[3383,17617,5170],{"class":3637},[3383,17619,17620],{"class":3798},"\"5. PUT \u002Fposts\u002F1 — повна заміна\"",[3383,17622,5176],{"class":3637},[3383,17624,17626,17628,17631,17633,17635,17637,17639,17641,17643,17645,17647,17650,17652,17655],{"class":3385,"line":17625},71,[3383,17627,5268],{"class":3780},[3383,17629,17630],{"class":5132}," replacement",[3383,17632,4744],{"class":3637},[3383,17634,5276],{"class":3780},[3383,17636,15060],{"class":5103},[3383,17638,5170],{"class":3637},[3383,17640,5316],{"class":3786},[3383,17642,3731],{"class":3637},[3383,17644,5316],{"class":3786},[3383,17646,3731],{"class":3637},[3383,17648,17649],{"class":3798},"\"Повністю замінений заголовок\"",[3383,17651,3731],{"class":3637},[3383,17653,17654],{"class":3798},"\"Весь текст змінено\"",[3383,17656,5176],{"class":3637},[3383,17658,17660,17662,17665,17667,17669,17671,17673,17675,17677,17679,17681,17684],{"class":3385,"line":17659},72,[3383,17661,14606],{"class":5103},[3383,17663,17664],{"class":5132}," r5",[3383,17666,4744],{"class":3637},[3383,17668,14543],{"class":3780},[3383,17670,16787],{"class":5132},[3383,17672,4760],{"class":3637},[3383,17674,15216],{"class":5166},[3383,17676,5170],{"class":3637},[3383,17678,15221],{"class":3798},[3383,17680,3731],{"class":3637},[3383,17682,17683],{"class":5132},"replacement",[3383,17685,5176],{"class":3637},[3383,17687,17689,17691,17693,17696],{"class":3385,"line":17688},73,[3383,17690,16946],{"class":5166},[3383,17692,5170],{"class":3637},[3383,17694,17695],{"class":5132},"r5",[3383,17697,5176],{"class":3637},[3383,17699,17701,17703,17705,17708,17710,17712,17714,17716,17718,17720,17722,17724,17726],{"class":3385,"line":17700},74,[3383,17702,14964],{"class":5103},[3383,17704,14535],{"class":3637},[3383,17706,17707],{"class":5132},"replaced",[3383,17709,4744],{"class":3637},[3383,17711,14543],{"class":3780},[3383,17713,17664],{"class":5132},[3383,17715,4760],{"class":3637},[3383,17717,14734],{"class":5132},[3383,17719,4760],{"class":3637},[3383,17721,14984],{"class":5166},[3383,17723,3654],{"class":3637},[3383,17725,14964],{"class":5103},[3383,17727,14991],{"class":3637},[3383,17729,17731,17733,17735,17737,17739,17741,17743,17745,17747,17749,17751,17753,17755],{"class":3385,"line":17730},75,[3383,17732,5520],{"class":5132},[3383,17734,4760],{"class":3637},[3383,17736,5525],{"class":5166},[3383,17738,5170],{"class":3637},[3383,17740,17231],{"class":3798},[3383,17742,5466],{"class":5465},[3383,17744,17707],{"class":5132},[3383,17746,4827],{"class":3637},[3383,17748,4760],{"class":5465},[3383,17750,14586],{"class":5132},[3383,17752,5583],{"class":5465},[3383,17754,5508],{"class":3798},[3383,17756,5176],{"class":3637},[3383,17758,17760],{"class":3385,"line":17759},76,[3383,17761,3408],{"emptyLinePlaceholder":3407},[3383,17763,17765],{"class":3385,"line":17764},77,[3383,17766,16892],{"class":5030},[3383,17768,17770],{"class":3385,"line":17769},78,[3383,17771,17772],{"class":5030},"\u002F\u002F 6. PATCH \u002Fposts\u002F1 — часткове оновлення\n",[3383,17774,17776],{"class":3385,"line":17775},79,[3383,17777,17778],{"class":5030},"\u002F\u002F    Надсилаємо ТІЛЬКИ поля, що змінились\n",[3383,17780,17782],{"class":3385,"line":17781},80,[3383,17783,16892],{"class":5030},[3383,17785,17787,17789,17791,17794],{"class":3385,"line":17786},81,[3383,17788,16911],{"class":5166},[3383,17790,5170],{"class":3637},[3383,17792,17793],{"class":3798},"\"6. PATCH \u002Fposts\u002F1 — оновити лише title\"",[3383,17795,5176],{"class":3637},[3383,17797,17799,17801,17803,17805,17807,17809,17812,17814,17817],{"class":3385,"line":17798},82,[3383,17800,5268],{"class":3780},[3383,17802,15255],{"class":5132},[3383,17804,4744],{"class":3637},[3383,17806,5276],{"class":3780},[3383,17808,15262],{"class":3637},[3383,17810,17811],{"class":5132},"title",[3383,17813,4744],{"class":3637},[3383,17815,17816],{"class":3798},"\"Оновлений через PATCH\"",[3383,17818,15272],{"class":3637},[3383,17820,17822,17824,17827,17829,17831,17833,17835,17837,17839,17841,17843,17845,17847,17849,17851,17853],{"class":3385,"line":17821},83,[3383,17823,14606],{"class":5103},[3383,17825,17826],{"class":5132}," r6",[3383,17828,4744],{"class":3637},[3383,17830,14543],{"class":3780},[3383,17832,16787],{"class":5132},[3383,17834,4760],{"class":3637},[3383,17836,15314],{"class":5166},[3383,17838,5170],{"class":3637},[3383,17840,15221],{"class":3798},[3383,17842,3731],{"class":3637},[3383,17844,15284],{"class":5132},[3383,17846,4760],{"class":3637},[3383,17848,15289],{"class":5166},[3383,17850,5170],{"class":3637},[3383,17852,15294],{"class":5132},[3383,17854,5511],{"class":3637},[3383,17856,17858,17860,17862,17865],{"class":3385,"line":17857},84,[3383,17859,16946],{"class":5166},[3383,17861,5170],{"class":3637},[3383,17863,17864],{"class":5132},"r6",[3383,17866,5176],{"class":3637},[3383,17868,17870,17872,17874,17877,17879,17881,17883,17885,17887,17889,17891,17893,17895],{"class":3385,"line":17869},85,[3383,17871,14964],{"class":5103},[3383,17873,14535],{"class":3637},[3383,17875,17876],{"class":5132},"patched",[3383,17878,4744],{"class":3637},[3383,17880,14543],{"class":3780},[3383,17882,17826],{"class":5132},[3383,17884,4760],{"class":3637},[3383,17886,14734],{"class":5132},[3383,17888,4760],{"class":3637},[3383,17890,14984],{"class":5166},[3383,17892,3654],{"class":3637},[3383,17894,14964],{"class":5103},[3383,17896,14991],{"class":3637},[3383,17898,17900,17902,17904,17906,17908,17910,17912,17914,17916,17918,17920,17922,17924],{"class":3385,"line":17899},86,[3383,17901,5520],{"class":5132},[3383,17903,4760],{"class":3637},[3383,17905,5525],{"class":5166},[3383,17907,5170],{"class":3637},[3383,17909,17231],{"class":3798},[3383,17911,5466],{"class":5465},[3383,17913,17876],{"class":5132},[3383,17915,4827],{"class":3637},[3383,17917,4760],{"class":5465},[3383,17919,14586],{"class":5132},[3383,17921,5583],{"class":5465},[3383,17923,5508],{"class":3798},[3383,17925,5176],{"class":3637},[3383,17927,17929,17931,17933,17935,17937,17940,17942,17944,17946,17948,17950,17952,17954,17957,17959,17961],{"class":3385,"line":17928},87,[3383,17930,5520],{"class":5132},[3383,17932,4760],{"class":3637},[3383,17934,5525],{"class":5166},[3383,17936,5170],{"class":3637},[3383,17938,17939],{"class":3798},"$\"   Body залишився: ",[3383,17941,5466],{"class":5465},[3383,17943,17876],{"class":5132},[3383,17945,4827],{"class":3637},[3383,17947,4760],{"class":5465},[3383,17949,6579],{"class":5132},[3383,17951,17093],{"class":5465},[3383,17953,4784],{"class":3637},[3383,17955,17956],{"class":3786},"40",[3383,17958,17279],{"class":5465},[3383,17960,17282],{"class":3798},[3383,17962,5176],{"class":3637},[3383,17964,17966],{"class":3385,"line":17965},88,[3383,17967,3408],{"emptyLinePlaceholder":3407},[3383,17969,17971],{"class":3385,"line":17970},89,[3383,17972,16892],{"class":5030},[3383,17974,17976],{"class":3385,"line":17975},90,[3383,17977,17978],{"class":5030},"\u002F\u002F 7. DELETE \u002Fposts\u002F1 — видалити ресурс\n",[3383,17980,17982],{"class":3385,"line":17981},91,[3383,17983,17984],{"class":5030},"\u002F\u002F    HTTP DELETE: ідемпотентний — повторний виклик не змінить стан\n",[3383,17986,17988],{"class":3385,"line":17987},92,[3383,17989,16892],{"class":5030},[3383,17991,17993,17995,17997,18000],{"class":3385,"line":17992},93,[3383,17994,16911],{"class":5166},[3383,17996,5170],{"class":3637},[3383,17998,17999],{"class":3798},"\"7. DELETE \u002Fposts\u002F1 — видалити\"",[3383,18001,5176],{"class":3637},[3383,18003,18005,18007,18010,18012,18014,18016,18018,18020,18022,18024],{"class":3385,"line":18004},94,[3383,18006,14606],{"class":5103},[3383,18008,18009],{"class":5132}," r7",[3383,18011,4744],{"class":3637},[3383,18013,14543],{"class":3780},[3383,18015,16787],{"class":5132},[3383,18017,4760],{"class":3637},[3383,18019,15363],{"class":5166},[3383,18021,5170],{"class":3637},[3383,18023,15221],{"class":3798},[3383,18025,5176],{"class":3637},[3383,18027,18029,18031,18033,18036],{"class":3385,"line":18028},95,[3383,18030,16946],{"class":5166},[3383,18032,5170],{"class":3637},[3383,18034,18035],{"class":5132},"r7",[3383,18037,5176],{"class":3637},[3383,18039,18041,18043,18045,18047,18049,18051,18053,18056,18059,18062,18065,18068],{"class":3385,"line":18040},96,[3383,18042,5520],{"class":5132},[3383,18044,4760],{"class":3637},[3383,18046,5525],{"class":5166},[3383,18048,5170],{"class":3637},[3383,18050,18035],{"class":5132},[3383,18052,4760],{"class":3637},[3383,18054,18055],{"class":5132},"IsSuccessStatusCode",[3383,18057,18058],{"class":3637}," ? ",[3383,18060,18061],{"class":3798},"\"   ✓ Видалено\"",[3383,18063,18064],{"class":3637}," : ",[3383,18066,18067],{"class":3798},"\"   ✗ Помилка\"",[3383,18069,5176],{"class":3637},[3383,18071,18073],{"class":3385,"line":18072},97,[3383,18074,3408],{"emptyLinePlaceholder":3407},[3383,18076,18078,18080,18082,18085],{"class":3385,"line":18077},98,[3383,18079,16876],{"class":5166},[3383,18081,5170],{"class":3637},[3383,18083,18084],{"class":3798},"\"Готово! Всі HTTP-методи виконано.\"",[3383,18086,5176],{"class":3637},[3383,18088,18090],{"class":3385,"line":18089},99,[3383,18091,3408],{"emptyLinePlaceholder":3407},[3383,18093,18095],{"class":3385,"line":18094},100,[3383,18096,18097],{"class":5030},"\u002F\u002F ── Допоміжні методи ──────────────────────────────────────────────────────────\n",[3383,18099,18101,18104,18107,18109,18111,18114],{"class":3385,"line":18100},101,[3383,18102,18103],{"class":3780},"void",[3383,18105,18106],{"class":5166}," Header",[3383,18108,5170],{"class":3637},[3383,18110,4709],{"class":3780},[3383,18112,18113],{"class":5132}," msg",[3383,18115,5287],{"class":3637},[3383,18117,18119],{"class":3385,"line":18118},102,[3383,18120,5292],{"class":3637},[3383,18122,18124,18126,18128,18130],{"class":3385,"line":18123},103,[3383,18125,14673],{"class":5132},[3383,18127,4760],{"class":3637},[3383,18129,5525],{"class":5166},[3383,18131,14716],{"class":3637},[3383,18133,18135,18137,18139,18141,18143,18145,18148,18150,18153,18155,18158],{"class":3385,"line":18134},104,[3383,18136,14673],{"class":5132},[3383,18138,4760],{"class":3637},[3383,18140,5525],{"class":5166},[3383,18142,5170],{"class":3637},[3383,18144,5276],{"class":3780},[3383,18146,18147],{"class":3780}," string",[3383,18149,5170],{"class":3637},[3383,18151,18152],{"class":3798},"'═'",[3383,18154,3731],{"class":3637},[3383,18156,18157],{"class":3786},"48",[3383,18159,5511],{"class":3637},[3383,18161,18163,18165,18167,18169,18171,18174,18176,18179,18181,18183],{"class":3385,"line":18162},105,[3383,18164,14673],{"class":5132},[3383,18166,4760],{"class":3637},[3383,18168,5525],{"class":5166},[3383,18170,5170],{"class":3637},[3383,18172,18173],{"class":3798},"$\"  ",[3383,18175,5466],{"class":5465},[3383,18177,18178],{"class":5132},"msg",[3383,18180,5583],{"class":5465},[3383,18182,5508],{"class":3798},[3383,18184,5176],{"class":3637},[3383,18186,18188,18190,18192,18194,18196,18198,18200,18202,18204,18206,18208],{"class":3385,"line":18187},106,[3383,18189,14673],{"class":5132},[3383,18191,4760],{"class":3637},[3383,18193,5525],{"class":5166},[3383,18195,5170],{"class":3637},[3383,18197,5276],{"class":3780},[3383,18199,18147],{"class":3780},[3383,18201,5170],{"class":3637},[3383,18203,18152],{"class":3798},[3383,18205,3731],{"class":3637},[3383,18207,18157],{"class":3786},[3383,18209,5511],{"class":3637},[3383,18211,18213],{"class":3385,"line":18212},107,[3383,18214,4091],{"class":3637},[3383,18216,18218],{"class":3385,"line":18217},108,[3383,18219,3408],{"emptyLinePlaceholder":3407},[3383,18221,18223,18225,18228,18230,18232,18235],{"class":3385,"line":18222},109,[3383,18224,18103],{"class":3780},[3383,18226,18227],{"class":5166}," Section",[3383,18229,5170],{"class":3637},[3383,18231,4709],{"class":3780},[3383,18233,18234],{"class":5132}," title",[3383,18236,5287],{"class":3637},[3383,18238,18240],{"class":3385,"line":18239},110,[3383,18241,5292],{"class":3637},[3383,18243,18245,18247,18249,18251],{"class":3385,"line":18244},111,[3383,18246,14673],{"class":5132},[3383,18248,4760],{"class":3637},[3383,18250,5525],{"class":5166},[3383,18252,14716],{"class":3637},[3383,18254,18256,18258,18260,18263,18265,18268,18270,18273],{"class":3385,"line":18255},112,[3383,18257,14673],{"class":5132},[3383,18259,4760],{"class":3637},[3383,18261,18262],{"class":5132},"ForegroundColor",[3383,18264,4744],{"class":3637},[3383,18266,18267],{"class":5132},"ConsoleColor",[3383,18269,4760],{"class":3637},[3383,18271,18272],{"class":5132},"Cyan",[3383,18274,5112],{"class":3637},[3383,18276,18278,18280,18282,18284,18286,18289,18291,18293,18295,18297],{"class":3385,"line":18277},113,[3383,18279,14673],{"class":5132},[3383,18281,4760],{"class":3637},[3383,18283,5525],{"class":5166},[3383,18285,5170],{"class":3637},[3383,18287,18288],{"class":3798},"$\"▶ ",[3383,18290,5466],{"class":5465},[3383,18292,17811],{"class":5132},[3383,18294,5583],{"class":5465},[3383,18296,5508],{"class":3798},[3383,18298,5176],{"class":3637},[3383,18300,18302,18304,18306,18309],{"class":3385,"line":18301},114,[3383,18303,14673],{"class":5132},[3383,18305,4760],{"class":3637},[3383,18307,18308],{"class":5166},"ResetColor",[3383,18310,14716],{"class":3637},[3383,18312,18314],{"class":3385,"line":18313},115,[3383,18315,4091],{"class":3637},[3383,18317,18319],{"class":3385,"line":18318},116,[3383,18320,3408],{"emptyLinePlaceholder":3407},[3383,18322,18324,18326,18329,18331,18333,18335],{"class":3385,"line":18323},117,[3383,18325,18103],{"class":3780},[3383,18327,18328],{"class":5166}," PrintStatus",[3383,18330,5170],{"class":3637},[3383,18332,14606],{"class":5103},[3383,18334,14609],{"class":5132},[3383,18336,5287],{"class":3637},[3383,18338,18340],{"class":3385,"line":18339},118,[3383,18341,5292],{"class":3637},[3383,18343,18345,18348,18351,18354,18356,18358,18360,18362,18364],{"class":3385,"line":18344},119,[3383,18346,18347],{"class":3780},"    int",[3383,18349,18350],{"class":5132}," code",[3383,18352,18353],{"class":3637}," = (",[3383,18355,14773],{"class":3780},[3383,18357,4902],{"class":3637},[3383,18359,14637],{"class":5132},[3383,18361,4760],{"class":3637},[3383,18363,14642],{"class":5132},[3383,18365,5112],{"class":3637},[3383,18367,18369,18371,18373,18375,18377,18379],{"class":3385,"line":18368},120,[3383,18370,14673],{"class":5132},[3383,18372,4760],{"class":3637},[3383,18374,18262],{"class":5132},[3383,18376,4744],{"class":3637},[3383,18378,3380],{"class":5132},[3383,18380,18381],{"class":3634}," switch\n",[3383,18383,18385],{"class":3385,"line":18384},121,[3383,18386,15598],{"class":3637},[3383,18388,18390,18393,18396,18399,18402,18405,18408,18410,18412,18415],{"class":3385,"line":18389},122,[3383,18391,18392],{"class":3637},"        >= ",[3383,18394,18395],{"class":3786},"200",[3383,18397,18398],{"class":3780}," and",[3383,18400,18401],{"class":3637}," \u003C ",[3383,18403,18404],{"class":3786},"300",[3383,18406,18407],{"class":3637}," => ",[3383,18409,18267],{"class":5132},[3383,18411,4760],{"class":3637},[3383,18413,18414],{"class":5132},"Green",[3383,18416,5305],{"class":3637},[3383,18418,18420,18422,18424,18426,18428,18430,18432,18434,18436,18439],{"class":3385,"line":18419},123,[3383,18421,18392],{"class":3637},[3383,18423,18404],{"class":3786},[3383,18425,18398],{"class":3780},[3383,18427,18401],{"class":3637},[3383,18429,12135],{"class":3786},[3383,18431,18407],{"class":3637},[3383,18433,18267],{"class":5132},[3383,18435,4760],{"class":3637},[3383,18437,18438],{"class":5132},"Yellow",[3383,18440,5305],{"class":3637},[3383,18442,18444,18447,18450,18452,18454],{"class":3385,"line":18443},124,[3383,18445,18446],{"class":3780},"        _",[3383,18448,18449],{"class":3637},"                => ",[3383,18451,18267],{"class":5132},[3383,18453,4760],{"class":3637},[3383,18455,18456],{"class":5132},"Red\n",[3383,18458,18460],{"class":3385,"line":18459},125,[3383,18461,18462],{"class":3637},"    };\n",[3383,18464,18466,18468,18470,18473,18475,18478,18480,18482,18484,18487,18489,18491,18493,18495,18497],{"class":3385,"line":18465},126,[3383,18467,14673],{"class":5132},[3383,18469,4760],{"class":3637},[3383,18471,18472],{"class":5166},"Write",[3383,18474,5170],{"class":3637},[3383,18476,18477],{"class":3798},"$\"   HTTP ",[3383,18479,5466],{"class":5465},[3383,18481,3380],{"class":5132},[3383,18483,5583],{"class":5465},[3383,18485,18486],{"class":5465}," {",[3383,18488,14637],{"class":5132},[3383,18490,4760],{"class":5465},[3383,18492,14642],{"class":5132},[3383,18494,5583],{"class":5465},[3383,18496,5508],{"class":3798},[3383,18498,5176],{"class":3637},[3383,18500,18502,18504,18506,18508],{"class":3385,"line":18501},127,[3383,18503,14673],{"class":5132},[3383,18505,4760],{"class":3637},[3383,18507,18308],{"class":5166},[3383,18509,14716],{"class":3637},[3383,18511,18513,18515,18517,18519,18521,18524,18526,18528,18530,18533,18535,18537,18540,18542,18544,18546,18548,18550,18552,18554,18557,18559,18561,18564,18566,18568],{"class":3385,"line":18512},128,[3383,18514,14673],{"class":5132},[3383,18516,4760],{"class":3637},[3383,18518,5525],{"class":5166},[3383,18520,5170],{"class":3637},[3383,18522,18523],{"class":3798},"$\"  ← ",[3383,18525,5466],{"class":5465},[3383,18527,14637],{"class":5132},[3383,18529,4760],{"class":5465},[3383,18531,18532],{"class":5132},"RequestMessage",[3383,18534,4827],{"class":3637},[3383,18536,4760],{"class":5465},[3383,18538,18539],{"class":5132},"Method",[3383,18541,5583],{"class":5465},[3383,18543,18486],{"class":5465},[3383,18545,14637],{"class":5132},[3383,18547,4760],{"class":5465},[3383,18549,18532],{"class":5132},[3383,18551,4827],{"class":3637},[3383,18553,4760],{"class":5465},[3383,18555,18556],{"class":5132},"RequestUri",[3383,18558,4827],{"class":3637},[3383,18560,4760],{"class":5465},[3383,18562,18563],{"class":5132},"PathAndQuery",[3383,18565,5583],{"class":5465},[3383,18567,5508],{"class":3798},[3383,18569,5176],{"class":3637},[3383,18571,18573],{"class":3385,"line":18572},129,[3383,18574,4091],{"class":3637},[3383,18576,18578],{"class":3385,"line":18577},130,[3383,18579,3408],{"emptyLinePlaceholder":3407},[3383,18581,18583],{"class":3385,"line":18582},131,[3383,18584,18585],{"class":5030},"\u002F\u002F ── Моделі ────────────────────────────────────────────────────────────────────\n",[3383,18587,18589,18591,18593,18595,18597,18599,18601,18603,18605,18607,18609,18611,18613,18615,18617],{"class":3385,"line":18588},132,[3383,18590,14765],{"class":3780},[3383,18592,15060],{"class":5103},[3383,18594,5170],{"class":3637},[3383,18596,14773],{"class":3780},[3383,18598,14776],{"class":5132},[3383,18600,3731],{"class":3637},[3383,18602,14773],{"class":3780},[3383,18604,15051],{"class":5132},[3383,18606,3731],{"class":3637},[3383,18608,4709],{"class":3780},[3383,18610,14783],{"class":5132},[3383,18612,3731],{"class":3637},[3383,18614,4709],{"class":3780},[3383,18616,15044],{"class":5132},[3383,18618,5176],{"class":3637},[3383,18620,18622,18624,18626,18628,18630,18632,18634,18636,18638,18640,18642,18644],{"class":3385,"line":18621},133,[3383,18623,14765],{"class":3780},[3383,18625,17435],{"class":5103},[3383,18627,5170],{"class":3637},[3383,18629,4709],{"class":3780},[3383,18631,14783],{"class":5132},[3383,18633,3731],{"class":3637},[3383,18635,4709],{"class":3780},[3383,18637,15044],{"class":5132},[3383,18639,3731],{"class":3637},[3383,18641,14773],{"class":3780},[3383,18643,15051],{"class":5132},[3383,18645,5176],{"class":3637},[3599,18647,18649],{"id":18648},"вивід","Вивід",[18651,18652,18654,18658,18666,18673,18679,18682,18690,18700,18704,18708,18712,18716,18719,18726,18733,18737,18741,18744,18751,18760,18764,18767,18774,18782,18786,18790,18793,18800,18807,18811,18814,18821,18828,18832,18836,18839,18846,18853,18857,18860,18866,18873],"terminal-preview",{"title":18653},"dotnet run — PostsExplorer",[18655,18656],"div",{"className":18657},[3385],[18655,18659,18661],{"className":18660},[3385],[3383,18662,18665],{"className":18663},[18664],"text-yellow-400","════════════════════════════════════════════════",[18655,18667,18669],{"className":18668},[3385],[3383,18670,18672],{"className":18671},[18664],"  Posts Explorer — HTTP Demo",[18655,18674,18676],{"className":18675},[3385],[3383,18677,18665],{"className":18678},[18664],[18655,18680],{"className":18681},[3385],[18655,18683,18685],{"className":18684},[3385],[3383,18686,18689],{"className":18687},[18688],"text-cyan-400","▶ 1. GET \u002Fposts — список постів",[18655,18691,18693,18694,18699],{"className":18692},[3385],"   ",[3383,18695,18698],{"className":18696},[18697],"text-green-400","HTTP 200 OK","  ← GET \u002Fposts",[18655,18701,18703],{"className":18702},[3385],"   Отримано постів: 100. Перші 3:",[18655,18705,18707],{"className":18706},[3385],"   [  1] sunt aut facere repellat provident occaecati ex",[18655,18709,18711],{"className":18710},[3385],"   [  2] qui est esse",[18655,18713,18715],{"className":18714},[3385],"   [  3] ea molestias quasi exercitationem repellat qui ip",[18655,18717],{"className":18718},[3385],[18655,18720,18722],{"className":18721},[3385],[3383,18723,18725],{"className":18724},[18688],"▶ 2. GET \u002Fposts\u002F1 — один ресурс",[18655,18727,18693,18729,18732],{"className":18728},[3385],[3383,18730,18698],{"className":18731},[18697],"  ← GET \u002Fposts\u002F1",[18655,18734,18736],{"className":18735},[3385],"   Title: sunt aut facere repellat provident occaecati...",[18655,18738,18740],{"className":18739},[3385],"   Body:  quia et suscipit suscipit recusandae consequuntu",[18655,18742],{"className":18743},[3385],[18655,18745,18747],{"className":18746},[3385],[3383,18748,18750],{"className":18749},[18688],"▶ 3. GET \u002Fposts\u002F9999 — обробка 404",[18655,18752,18693,18754,18759],{"className":18753},[3385],[3383,18755,18758],{"className":18756},[18757],"text-red-400","HTTP 404 NotFound","  ← GET \u002Fposts\u002F9999",[18655,18761,18763],{"className":18762},[3385],"   → Ресурс не знайдено. 404 оброблено gracefully.",[18655,18765],{"className":18766},[3385],[18655,18768,18770],{"className":18769},[3385],[3383,18771,18773],{"className":18772},[18688],"▶ 4. POST \u002Fposts — створити пост",[18655,18775,18693,18777,18781],{"className":18776},[3385],[3383,18778,18780],{"className":18779},[18697],"HTTP 201 Created","  ← POST \u002Fposts",[18655,18783,18785],{"className":18784},[3385],"   Location: \u002Fposts\u002F101",[18655,18787,18789],{"className":18788},[3385],"   Новий ID: 101",[18655,18791],{"className":18792},[3385],[18655,18794,18796],{"className":18795},[3385],[3383,18797,18799],{"className":18798},[18688],"▶ 5. PUT \u002Fposts\u002F1 — повна заміна",[18655,18801,18693,18803,18806],{"className":18802},[3385],[3383,18804,18698],{"className":18805},[18697],"  ← PUT \u002Fposts\u002F1",[18655,18808,18810],{"className":18809},[3385],"   Title: Повністю замінений заголовок",[18655,18812],{"className":18813},[3385],[18655,18815,18817],{"className":18816},[3385],[3383,18818,18820],{"className":18819},[18688],"▶ 6. PATCH \u002Fposts\u002F1 — оновити лише title",[18655,18822,18693,18824,18827],{"className":18823},[3385],[3383,18825,18698],{"className":18826},[18697],"  ← PATCH \u002Fposts\u002F1",[18655,18829,18831],{"className":18830},[3385],"   Title: Оновлений через PATCH",[18655,18833,18835],{"className":18834},[3385],"   Body залишився: quia et suscipit suscipit recusandae c",[18655,18837],{"className":18838},[3385],[18655,18840,18842],{"className":18841},[3385],[3383,18843,18845],{"className":18844},[18688],"▶ 7. DELETE \u002Fposts\u002F1 — видалити",[18655,18847,18693,18849,18852],{"className":18848},[3385],[3383,18850,18698],{"className":18851},[18697],"  ← DELETE \u002Fposts\u002F1",[18655,18854,18856],{"className":18855},[3385],"   ✓ Видалено",[18655,18858],{"className":18859},[3385],[18655,18861,18863],{"className":18862},[3385],[3383,18864,18665],{"className":18865},[18664],[18655,18867,18869],{"className":18868},[3385],[3383,18870,18872],{"className":18871},[18664],"  Готово! Всі HTTP-методи виконано.",[18655,18874,18876],{"className":18875},[3385],[3383,18877,18665],{"className":18878},[18664],[3599,18880,18882],{"id":18881},"що-ви-щойно-побудували","Що ви щойно побудували",[7824,18884,18885,18921,18949],{},[7827,18886,18888],{"icon":1348,"title":18887},"HTTP-методи",[3719,18889,18890,18895,18906,18911,18916],{},[3722,18891,18892,18894],{},[3380,18893,3621],{}," — безпечний, ідемпотентний, без тіла",[3722,18896,18897,18899,18900,18902,18903,18905],{},[3380,18898,3746],{}," → ",[3380,18901,7150],{}," + ",[3380,18904,7191],{}," header",[3722,18907,18908,18910],{},[3380,18909,8412],{}," — ідемпотентний, повна заміна всіх полів",[3722,18912,18913,18915],{},[3380,18914,8428],{}," — лише поля, що змінились",[3722,18917,18918,18920],{},[3380,18919,7467],{}," — ідемпотентний",[7827,18922,18924],{"icon":18923,"title":3758},"i-lucide-hash",[3719,18925,18926,18931,18936,18941],{},[3722,18927,18928,18930],{},[3380,18929,6823],{}," — успішна операція",[3722,18932,18933,18935],{},[3380,18934,7150],{}," — ресурс створено",[3722,18937,18938,18940],{},[3380,18939,12464],{}," — обробка без виключень",[3722,18942,18943,18945,18946],{},[3380,18944,18055],{}," vs ",[3380,18947,18948],{},"EnsureSuccessStatusCode()",[7827,18950,18953],{"icon":18951,"title":18952},"i-lucide-code","HttpClient у C#",[3719,18954,18955,18958,18965,18971],{},[3722,18956,18957],{},"Один екземпляр для всіх запитів",[3722,18959,18960,4689,18962,18964],{},[3380,18961,14928],{},[3380,18963,14550],{}," — серіалізація автоматична",[3722,18966,18967,18970],{},[3380,18968,18969],{},"JsonContent.Create"," — для PATCH і кастомних запитів",[3722,18972,18973,18976],{},[3380,18974,18975],{},"Headers.Location"," — читання заголовків відповіді",[5854,18978,18979,18980,18983,18984,3731,18987,4775,18990,18993],{},"Спробуйте: змініть ",[3380,18981,18982],{},"posts"," на ",[3380,18985,18986],{},"users",[3380,18988,18989],{},"todos",[3380,18991,18992],{},"comments"," — JSONPlaceholder підтримує всі ці ресурси. Спробуйте навмисно надіслати некоректні дані і подивіться, яку відповідь повертає сервер.",[3360,18995],{},[3312,18997,18999],{"id":18998},"практика-та-закріплення","Практика та закріплення",[3317,19001,19002],{},"Теоретичний розбір HTTP легко створює оманливе відчуття зрозумілості — поки не спробуєш написати реальний клієнт. Наведені нижче завдання побудовані за принципом поступового ускладнення: від базового розуміння структури повідомлень до проектування власного HTTP-клієнта з підтримкою аутентифікації та повторних запитів.",[3599,19004,19006],{"id":19005},"рівень-1-базове-розуміння","Рівень 1. Базове розуміння",[19008,19009,19010,19018,19038],"ol",{},[3722,19011,19012,19013,3747,19015,19017],{},"Напишіть власними словами різницю між ",[3321,19014,8013],{},[3321,19016,8037],{}," HTTP-методом. Наведіть по два приклади для кожної категорії.",[3722,19019,19020,19021],{},"Яку HTTP-відповідь поверне сервер у кожному з цих сценаріїв? Обґрунтуйте вибір статус-коду:",[3719,19022,19023,19026,19029,19032,19035],{},[3722,19024,19025],{},"Клієнт запитує ресурс, який не існує",[3722,19027,19028],{},"Клієнт успішно створив новий об'єкт",[3722,19030,19031],{},"Клієнт надіслав JSON з пропущеним обов'язковим полем",[3722,19033,19034],{},"Клієнт намагається видалити об'єкт, що належить іншому користувачу",[3722,19036,19037],{},"Сервер впав через непередбачений виняток у коді",[3722,19039,19040,19041,3747,19044,19047],{},"Яка різниця між заголовками ",[3380,19042,19043],{},"Authorization: Basic ...",[3380,19045,19046],{},"Authorization: Bearer ...","? В яких сценаріях застосовується кожен?",[3599,19049,19051],{"id":19050},"рівень-2-робота-з-httpclient","Рівень 2. Робота з HttpClient",[19008,19053,19054,19083,19097],{},[3722,19055,19056,19057],{},"Напишіть консольний застосунок, що:",[3719,19058,19059,19065,19071,19080],{},[3722,19060,19061,19062],{},"Отримує список постів з ",[3380,19063,19064],{},"jsonplaceholder.typicode.com\u002Fposts",[3722,19066,19067,19068],{},"Фільтрує пости з ",[3380,19069,19070],{},"userId = 1",[3722,19072,19073,19074,19076,19077,19079],{},"Виводить ",[3380,19075,15015],{}," та перші 50 символів ",[3380,19078,14586],{}," кожного поста",[3722,19081,19082],{},"Виводить загальну кількість знайдених постів",[3722,19084,19085,19086,19088,19089,3747,19091,19093,19094,4760],{},"Реалізуйте ",[3380,19087,3750],{},"-запит для перевірки існування ресурсу без завантаження тіла. Порівняйте час виконання ",[3380,19090,3750],{},[3380,19092,3621],{}," для одного ресурсу за допомогою ",[3380,19095,19096],{},"Stopwatch",[3722,19098,19099,19100,19103,19104],{},"Напишіть метод ",[3380,19101,19102],{},"DownloadWithProgressAsync(string url, string filePath)",", що:",[3719,19105,19106,19111,19116],{},[3722,19107,19108,19109,4902],{},"Завантажує файл за URL з підтримкою великих файлів (потокове читання через ",[3380,19110,15797],{},[3722,19112,19113,19114,4902],{},"Виводить прогрес у відсотках (якщо сервер повертає ",[3380,19115,3734],{},[3722,19117,19118],{},"Не завантажує весь файл у RAM одночасно",[3599,19120,19122],{"id":19121},"рівень-3-архітектурне-мислення","Рівень 3. Архітектурне мислення",[19008,19124,19125,19149],{},[3722,19126,19085,19127,19103,19130],{},[3380,19128,19129],{},"CircuitBreakerHandler : DelegatingHandler",[3719,19131,19132,19137,19140,19143,19146],{},[3722,19133,19134,19135,4902],{},"Відстежує кількість поспіль невдалих запитів (5xx або ",[3380,19136,14424],{},[3722,19138,19139],{},"При 5 невдачах поспіль переходить у стан «Відкритий» (Open) — відхиляє нові запити без надсилання",[3722,19141,19142],{},"Через 30 секунд переходить у «Напіввідкритий» (Half-Open) — пропускає один тестовий запит",[3722,19144,19145],{},"При успішному тестовому запиті повертається у «Закритий» (Closed)",[3722,19147,19148],{},"Використайте PlantUML state diagram для документування станів",[3722,19150,19151,19152,19155,19156],{},"Спроектуйте типізований ",[3380,19153,19154],{},"GitHubApiClient"," із підтримкою:",[3719,19157,19158,19165,19168,19174],{},[3722,19159,19160,19161,3731,19163,4902],{},"Rate limiting (заголовки ",[3380,19162,13048],{},[3380,19164,13057],{},[3722,19166,19167],{},"Автоматичного очікування при вичерпанні ліміту",[3722,19169,19170,19171,18905],{},"Pagination через ",[3380,19172,19173],{},"Link",[3722,19175,19176,19177],{},"Bearer token аутентифікації через ",[3380,19178,19179],{},"IOptions\u003CGitHubOptions>",[5854,19181,19182,19183,19186],{},"Правильна відповідь у HTTP-програмуванні завжди починається зі ",[3321,19184,19185],{},"структури запиту",": перевірте метод, URL, заголовки та тіло — і лише потім шукайте проблему у коді клієнта.",[3360,19188],{},[3312,19190,19192],{"id":19191},"контрольні-питання","Контрольні питання",[3317,19194,19195],{},"Нижче подано набір запитань для самоперевірки. Якщо на будь-яке з них важко відповісти без повторного читання — це нормальний сигнал повернутись до відповідного розділу.",[19008,19197,19198,19201,19207,19210,19218,19228,19237,19244,19256,19262],{},[3722,19199,19200],{},"Чим відрізняється HTTP від TCP? Чому HTTP не може існувати без TCP (або QUIC)?",[3722,19202,19203,19204,19206],{},"Що таке ",[3380,19205,3596],{}," і як це фундаментально впливає на архітектуру вебзастосунків?",[3722,19208,19209],{},"Яку мінімальну кількість заголовків обов'язково містить валідний HTTP\u002F1.1 запит?",[3722,19211,19212,19213,3747,19215,19217],{},"В чому відмінність між ",[3380,19214,8412],{},[3380,19216,8428],{},"? Наведіть сценарій, де важливо вибрати правильно.",[3722,19219,19220,19221,19223,19224,3747,19226,4827],{},"Чому ",[3380,19222,12183],{}," — погана назва? Яка семантична різниця між ",[3380,19225,12306],{},[3380,19227,12440],{},[3722,19229,19230,19231,19233,19234,19236],{},"Що таке socket exhaustion у ",[3380,19232,7821],{}," і як ",[3380,19235,14348],{}," це вирішує?",[3722,19238,19239,19240,19243],{},"Навіщо потрібен ",[3380,19241,19242],{},"DelegatingHandler","? Наведіть три реальних сценарії його використання.",[3722,19245,19246,19247,19249,19250,19252,19253,4827],{},"Що відбудеться, якщо сервер поверне ",[3380,19248,11649],{}," у відповідь на ",[3380,19251,3746],{},"-запит? Що відбудеться при ",[3380,19254,19255],{},"308",[3722,19257,19258,19259,19261],{},"Для чого використовується ",[3380,19260,3750],{},"-метод? Наведіть два практичних прикладів.",[3722,19263,19264,19265,19267,19268,4827],{},"Що означає ",[3380,19266,6871],{}," і як він пов'язаний зі статус-кодом ",[3380,19269,11712],{},[3353,19271,19272,19273,19276],{},"Якщо ви впевнено відповідаєте на всі 10 питань, у вас є міцна база для переходу до наступного розділу: ",[3321,19274,19275],{},"cookies, сесії та аутентифікація в HTTP",". Там ми розберемо, як вирішується проблема stateless протоколу у реальних застосунках.",[19278,19279,19280],"style",{},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s8xlr, html code.shiki .s8xlr{--shiki-light:#AF00DB;--shiki-default:#C586C0;--shiki-dark:#C586C0}html pre.shiki code .sHH4Y, html code.shiki .sHH4Y{--shiki-light:#000000;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .s0P7L, html code.shiki .s0P7L{--shiki-light:#800000;--shiki-default:#808080;--shiki-dark:#808080}html pre.shiki code .sKtos, html code.shiki .sKtos{--shiki-light:#800000;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .su1O8, html code.shiki .su1O8{--shiki-light:#0000FF;--shiki-default:#569CD6;--shiki-dark:#569CD6}html pre.shiki code .sJj4R, html code.shiki .sJj4R{--shiki-light:#098658;--shiki-default:#B5CEA8;--shiki-dark:#B5CEA8}html pre.shiki code .sbdoH, html code.shiki .sbdoH{--shiki-light:#A31515;--shiki-default:#CE9178;--shiki-dark:#CE9178}html pre.shiki code .spJ8K, html code.shiki .spJ8K{--shiki-light:#008000;--shiki-default:#6A9955;--shiki-dark:#6A9955}html pre.shiki code .sN1BT, html code.shiki .sN1BT{--shiki-light:#267F99;--shiki-default:#4EC9B0;--shiki-dark:#4EC9B0}html pre.shiki code .siwwj, html code.shiki .siwwj{--shiki-light:#001080;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .s8Opu, html code.shiki .s8Opu{--shiki-light:#795E26;--shiki-default:#DCDCAA;--shiki-dark:#DCDCAA}html pre.shiki code .sD7JJ, html code.shiki .sD7JJ{--shiki-light:#000000FF;--shiki-default:#D4D4D4;--shiki-dark:#D4D4D4}html pre.shiki code .sjcCO, html code.shiki .sjcCO{--shiki-light:#EE0000;--shiki-default:#D7BA7D;--shiki-dark:#D7BA7D}html pre.shiki code .sLwNe, html code.shiki .sLwNe{--shiki-light:#0451A5;--shiki-default:#9CDCFE;--shiki-dark:#9CDCFE}html pre.shiki code .se1LK, html code.shiki .se1LK{--shiki-light:#CD3131;--shiki-default:#F44747;--shiki-dark:#F44747}",{"title":3378,"searchDepth":3392,"depth":3392,"links":19282},[19283,19284,19292,19300,19301,19305,19312,19316,19323,19327,19333,19343,19348],{"id":3314,"depth":3392,"text":3315},{"id":3364,"depth":3392,"text":3365,"children":19285},[19286,19287,19288,19289,19290,19291],{"id":3601,"depth":3398,"text":3602},{"id":3608,"depth":3398,"text":3609},{"id":3713,"depth":3398,"text":3714},{"id":3866,"depth":3398,"text":3867},{"id":4002,"depth":3398,"text":4003},{"id":4037,"depth":3398,"text":4038},{"id":4289,"depth":3392,"text":4290,"children":19293},[19294,19295,19296,19297,19298,19299],{"id":4293,"depth":3398,"text":4294},{"id":4303,"depth":3398,"text":4304},{"id":4652,"depth":3398,"text":4653},{"id":4920,"depth":3398,"text":4921},{"id":5019,"depth":3398,"text":5020},{"id":5086,"depth":3398,"text":5087},{"id":5614,"depth":3392,"text":5615},{"id":5864,"depth":3392,"text":5865,"children":19302},[19303,19304],{"id":5879,"depth":3398,"text":5880},{"id":6210,"depth":3398,"text":6211},{"id":6596,"depth":3392,"text":6597,"children":19306},[19307,19308,19309,19310,19311],{"id":6744,"depth":3398,"text":6745},{"id":7039,"depth":3398,"text":7040},{"id":7451,"depth":3398,"text":7452},{"id":7629,"depth":3398,"text":7630},{"id":7814,"depth":3398,"text":7815},{"id":7986,"depth":3392,"text":7987,"children":19313},[19314,19315],{"id":7997,"depth":3398,"text":7998},{"id":8490,"depth":3398,"text":8491},{"id":10757,"depth":3392,"text":10758,"children":19317},[19318,19319,19320,19321,19322],{"id":11042,"depth":3398,"text":11043},{"id":11242,"depth":3398,"text":11243},{"id":11642,"depth":3398,"text":11643},{"id":11998,"depth":3398,"text":11999},{"id":13122,"depth":3398,"text":13123},{"id":13516,"depth":3392,"text":13517,"children":19324},[19325,19326],{"id":13714,"depth":3398,"text":13715},{"id":13833,"depth":3398,"text":13834},{"id":13996,"depth":3392,"text":13997,"children":19328},[19329,19330,19331,19332],{"id":14000,"depth":3398,"text":14001},{"id":14332,"depth":3398,"text":14333},{"id":14432,"depth":3398,"text":14433},{"id":15809,"depth":3398,"text":15810},{"id":16449,"depth":3392,"text":16450,"children":19334},[19335,19336,19337,19338,19339,19340,19341,19342],{"id":16494,"depth":3398,"text":16495},{"id":16646,"depth":3398,"text":16647},{"id":16652,"depth":3398,"text":16653},{"id":16687,"depth":3398,"text":16688},{"id":16698,"depth":3398,"text":16699},{"id":16714,"depth":3398,"text":16694},{"id":18648,"depth":3398,"text":18649},{"id":18881,"depth":3398,"text":18882},{"id":18998,"depth":3392,"text":18999,"children":19344},[19345,19346,19347],{"id":19005,"depth":3398,"text":19006},{"id":19050,"depth":3398,"text":19051},{"id":19121,"depth":3398,"text":19122},{"id":19191,"depth":3392,"text":19192},"Глибоке вивчення HTTP — від структури повідомлень та методів до повноцінного REST API клієнта на C#. Академічний розбір RFC 7230–7235, анатомія запитів і відповідей, статус-коди, заголовки та HttpClient екосистема .NET.","md",null,{},{"title":1680,"description":19349},"Sg3DA7YAFL9P6nXmeunfcIOP5grq06oQYJBvZSMkHkI",[19356,19358],{"title":1676,"path":1677,"stem":1678,"description":19357,"children":-1},"Детальний розбір механізмів групової розсилки UDP — Broadcast та Multicast. Теорія, адресний простір, практичний приклад сервісу виявлення пристроїв у локальній мережі на C#.",{"title":1684,"path":1685,"stem":1686,"description":19359,"children":-1},"Детальний розгляд класу HttpListener — нативного HTTP-сервера .NET без ASP.NET Core. Архітектура, повний API, конфігурація, аутентифікація, обробка запитів та два практичні приклади — статичний файловий сервер та REST API.",1781795351113]