index.html 60 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. <!DOCTYPE html>
  2. <html lang="ja" data-base-path="&#x2F;cpp-httplib">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1">
  6. <title>Basic Server - cpp-httplib</title>
  7. <link rel="stylesheet" href="&#x2F;cpp-httplib/css/main.css">
  8. <script>
  9. (function() {
  10. var t = localStorage.getItem('preferred-theme');
  11. if (!t) t = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark';
  12. if (t === 'light') document.documentElement.setAttribute('data-theme', 'light');
  13. })();
  14. </script>
  15. </head>
  16. <body>
  17. <header class="header">
  18. <div class="header-inner">
  19. <a href="&#x2F;cpp-httplib/ja/" class="header-title">cpp-httplib <span style="font-size:0.75em;font-weight:normal;margin-left:4px">v0.35.0</span></a>
  20. <div class="header-spacer"></div>
  21. <nav class="header-nav">
  22. <a href="&#x2F;cpp-httplib/ja/">Home</a>
  23. <a href="&#x2F;cpp-httplib/ja/tour/">Tour</a>
  24. <a href="https://github.com/yhirose/cpp-httplib">GitHub</a>
  25. </nav>
  26. <div class="header-tools">
  27. <button class="theme-toggle" aria-label="Toggle theme"></button>
  28. <div class="lang-selector">
  29. <button class="lang-btn" aria-label="Language">JA</button>
  30. <ul class="lang-popup">
  31. <li><a href="#" data-lang="en">EN</a></li>
  32. <li><a href="#" data-lang="ja">JA</a></li>
  33. </ul>
  34. </div>
  35. </div>
  36. <button class="sidebar-toggle" aria-label="Menu">&#9776;</button>
  37. </div>
  38. </header>
  39. <div class="layout has-sidebar">
  40. <aside class="sidebar">
  41. <nav class="sidebar-nav">
  42. <div class="nav-section">
  43. <a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;" class="nav-section-title active">A Tour of cpp-httplib</a>
  44. <ul class="nav-list">
  45. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;01-getting-started&#x2F;" class="">Getting Started</a></li>
  46. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;02-basic-client&#x2F;" class="">Basic Client</a></li>
  47. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;03-basic-server&#x2F;" class="active">Basic Server</a></li>
  48. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;04-static-file-server&#x2F;" class="">Static File Server</a></li>
  49. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;05-tls-setup&#x2F;" class="">TLS Setup</a></li>
  50. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;06-https-client&#x2F;" class="">HTTPS Client</a></li>
  51. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;07-https-server&#x2F;" class="">HTTPS Server</a></li>
  52. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;08-websocket&#x2F;" class="">WebSocket</a></li>
  53. <li><a href="&#x2F;cpp-httplib&#x2F;ja&#x2F;tour&#x2F;09-whats-next&#x2F;" class="">What&#x27;s Next</a></li>
  54. </ul>
  55. </div>
  56. </nav>
  57. </aside>
  58. <main class="content">
  59. <article>
  60. <h1>Basic Server</h1>
  61. <p>前章ではクライアントからリクエストを送りました。そのとき、テスト用サーバーを用意しましたね。この章では、あのサーバーの仕組みをひとつずつ紐解いていきます。</p>
  62. <h2>サーバーの起動</h2>
  63. <p>ルーティングを登録したら、最後に <code>svr.listen()</code> を呼んでサーバーを起動します。</p>
  64. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  65. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">listen</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">0.0.0.0</span><span style="color:#d3d0c8;">&quot;, </span><span style="color:#f99157;">8080</span><span style="color:#d3d0c8;">);
  66. </span></pre>
  67. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  68. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">listen</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">0.0.0.0</span><span style="color:#4f5b66;">&quot;, </span><span style="color:#d08770;">8080</span><span style="color:#4f5b66;">);
  69. </span></pre>
  70. </div>
  71. <p>第1引数はホスト、第2引数はポート番号です。<code>"0.0.0.0"</code> を指定すると、すべてのネットワークインターフェースでリクエストを受け付けます。自分のマシンからのアクセスだけに限定したいときは <code>"127.0.0.1"</code> を使います。</p>
  72. <p><code>listen()</code> はブロッキング呼び出しです。サーバーが停止するまで、この行から先には進みません。ターミナルで <code>Ctrl+C</code> を押すか、別スレッドから <code>svr.stop()</code> を呼ぶまでサーバーは動き続けます。</p>
  73. <h2>ルーティング</h2>
  74. <p>サーバーの核になるのは「ルーティング」です。どのURLに、どのHTTPメソッドでアクセスされたら、何をするか。それを登録する仕組みです。</p>
  75. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  76. <span style="color:#d3d0c8;">httplib::Server svr;
  77. </span><span style="color:#d3d0c8;">
  78. </span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const</span><span style="color:#d3d0c8;"> httplib::Request &amp;req, httplib::Response &amp;res) {
  79. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  80. </span><span style="color:#d3d0c8;">});
  81. </span></pre>
  82. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  83. <span style="color:#4f5b66;">httplib::Server svr;
  84. </span><span style="color:#4f5b66;">
  85. </span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const</span><span style="color:#4f5b66;"> httplib::Request &amp;req, httplib::Response &amp;res) {
  86. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  87. </span><span style="color:#4f5b66;">});
  88. </span></pre>
  89. </div>
  90. <p><code>svr.Get()</code> は、GETリクエストに対するハンドラーを登録します。第1引数がパス、第2引数がハンドラー関数です。<code>/hi</code> にGETリクエストが来たら、このラムダが呼ばれます。</p>
  91. <p>HTTPメソッドごとにメソッドが用意されています。</p>
  92. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  93. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">&quot;, handler); </span><span style="color:#747369;">// GET
  94. </span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">&quot;, handler); </span><span style="color:#747369;">// POST
  95. </span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Put</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">&quot;, handler); </span><span style="color:#747369;">// PUT
  96. </span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Delete</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/path</span><span style="color:#d3d0c8;">&quot;, handler); </span><span style="color:#747369;">// DELETE
  97. </span></pre>
  98. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  99. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">&quot;, handler); </span><span style="color:#a7adba;">// GET
  100. </span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">&quot;, handler); </span><span style="color:#a7adba;">// POST
  101. </span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Put</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">&quot;, handler); </span><span style="color:#a7adba;">// PUT
  102. </span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Delete</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/path</span><span style="color:#4f5b66;">&quot;, handler); </span><span style="color:#a7adba;">// DELETE
  103. </span></pre>
  104. </div>
  105. <p>ハンドラーのシグネチャは <code>(const httplib::Request &amp;req, httplib::Response &amp;res)</code> です。<code>auto</code> を使って短く書くこともできます。</p>
  106. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  107. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  108. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  109. </span><span style="color:#d3d0c8;">});
  110. </span></pre>
  111. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  112. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  113. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  114. </span><span style="color:#4f5b66;">});
  115. </span></pre>
  116. </div>
  117. <p>パスが一致したときだけハンドラーが呼ばれます。登録されていないパスにアクセスすると、自動的に404が返ります。</p>
  118. <h2>リクエストオブジェクト</h2>
  119. <p>ハンドラーの第1引数 <code>req</code> から、クライアントが送ってきた情報を読み取れます。</p>
  120. <h3>ボディ</h3>
  121. <p><code>req.body</code> でリクエストボディを取得できます。型は <code>std::string</code> です。</p>
  122. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  123. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  124. </span><span style="color:#d3d0c8;"> </span><span style="color:#747369;">// クライアントが送ったボディをそのまま返す
  125. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  126. </span><span style="color:#d3d0c8;">});
  127. </span></pre>
  128. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  129. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  130. </span><span style="color:#4f5b66;"> </span><span style="color:#a7adba;">// クライアントが送ったボディをそのまま返す
  131. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  132. </span><span style="color:#4f5b66;">});
  133. </span></pre>
  134. </div>
  135. <h3>ヘッダー</h3>
  136. <p><code>req.get_header_value()</code> でリクエストヘッダーの値を取得できます。</p>
  137. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  138. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/check</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  139. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> auth = req.</span><span style="color:#6699cc;">get_header_value</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Authorization</span><span style="color:#d3d0c8;">&quot;);
  140. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Auth: </span><span style="color:#d3d0c8;">&quot; + auth, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  141. </span><span style="color:#d3d0c8;">});
  142. </span></pre>
  143. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  144. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/check</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  145. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> auth = req.</span><span style="color:#8fa1b3;">get_header_value</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Authorization</span><span style="color:#4f5b66;">&quot;);
  146. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Auth: </span><span style="color:#4f5b66;">&quot; + auth, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  147. </span><span style="color:#4f5b66;">});
  148. </span></pre>
  149. </div>
  150. <h3>クエリパラメーターとフォームデータ</h3>
  151. <p><code>req.get_param_value()</code> でパラメーターを取得できます。GETのクエリパラメーターと、POSTのフォームデータの両方に使えます。</p>
  152. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  153. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  154. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> q = req.</span><span style="color:#6699cc;">get_param_value</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">&quot;);
  155. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Query: </span><span style="color:#d3d0c8;">&quot; + q, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  156. </span><span style="color:#d3d0c8;">});
  157. </span></pre>
  158. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  159. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  160. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">&quot;);
  161. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Query: </span><span style="color:#4f5b66;">&quot; + q, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  162. </span><span style="color:#4f5b66;">});
  163. </span></pre>
  164. </div>
  165. <p><code>/search?q=cpp-httplib</code> にアクセスすると、<code>q</code> の値は <code>"cpp-httplib"</code> になります。</p>
  166. <p>すべてのパラメーターをループで処理したいときは、<code>req.params</code> を使います。</p>
  167. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  168. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  169. </span><span style="color:#d3d0c8;"> std::string result;
  170. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">for </span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;[key, val] : req.</span><span style="color:#f2777a;">params</span><span style="color:#d3d0c8;">) {
  171. </span><span style="color:#d3d0c8;"> result += key + &quot;</span><span style="color:#99cc99;"> = </span><span style="color:#d3d0c8;">&quot; + val + &quot;</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">&quot;;
  172. </span><span style="color:#d3d0c8;"> }
  173. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(result, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  174. </span><span style="color:#d3d0c8;">});
  175. </span></pre>
  176. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  177. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  178. </span><span style="color:#4f5b66;"> std::string result;
  179. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">for </span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#4f5b66;">) {
  180. </span><span style="color:#4f5b66;"> result += key + &quot;</span><span style="color:#a3be8c;"> = </span><span style="color:#4f5b66;">&quot; + val + &quot;</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">&quot;;
  181. </span><span style="color:#4f5b66;"> }
  182. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(result, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  183. </span><span style="color:#4f5b66;">});
  184. </span></pre>
  185. </div>
  186. <h3>ファイルアップロード</h3>
  187. <p>マルチパートフォームでアップロードされたファイルは、<code>req.form.get_file()</code> で取得します。</p>
  188. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  189. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  190. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> f = req.</span><span style="color:#f2777a;">form</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">get_file</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">&quot;);
  191. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> content = f.</span><span style="color:#f2777a;">filename </span><span style="color:#d3d0c8;">+ &quot;</span><span style="color:#99cc99;"> (</span><span style="color:#d3d0c8;">&quot; + </span><span style="color:#6699cc;">std::to_string</span><span style="color:#d3d0c8;">(f.</span><span style="color:#f2777a;">content</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()) + &quot;</span><span style="color:#99cc99;"> bytes)</span><span style="color:#d3d0c8;">&quot;;
  192. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(content, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  193. </span><span style="color:#d3d0c8;">});
  194. </span></pre>
  195. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  196. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  197. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">&quot;);
  198. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#4f5b66;">+ &quot;</span><span style="color:#a3be8c;"> (</span><span style="color:#4f5b66;">&quot; + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#4f5b66;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()) + &quot;</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#4f5b66;">&quot;;
  199. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(content, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  200. </span><span style="color:#4f5b66;">});
  201. </span></pre>
  202. </div>
  203. <p><code>f.filename</code> でファイル名、<code>f.content</code> でファイルの中身にアクセスできます。</p>
  204. <h2>パスパラメーター</h2>
  205. <p>URLの一部を変数として受け取りたいことがあります。たとえば <code>/users/42</code> の <code>42</code> を取得したい場合です。<code>:param</code> 記法を使うと、URLの一部をキャプチャできます。</p>
  206. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  207. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/users/:id</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  208. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">id</span><span style="color:#d3d0c8;">&quot;);
  209. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">User ID: </span><span style="color:#d3d0c8;">&quot; + id, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  210. </span><span style="color:#d3d0c8;">});
  211. </span></pre>
  212. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  213. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  214. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">id</span><span style="color:#4f5b66;">&quot;);
  215. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">User ID: </span><span style="color:#4f5b66;">&quot; + id, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  216. </span><span style="color:#4f5b66;">});
  217. </span></pre>
  218. </div>
  219. <p><code>/users/42</code> にアクセスすると、<code>req.path_params.at("id")</code> は <code>"42"</code> を返します。<code>/users/100</code> なら <code>"100"</code> です。</p>
  220. <p>複数のパスパラメーターも使えます。</p>
  221. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  222. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/users/:user_id/posts/:post_id</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  223. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> user_id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">user_id</span><span style="color:#d3d0c8;">&quot;);
  224. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> post_id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">post_id</span><span style="color:#d3d0c8;">&quot;);
  225. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">User: </span><span style="color:#d3d0c8;">&quot; + user_id + &quot;</span><span style="color:#99cc99;">, Post: </span><span style="color:#d3d0c8;">&quot; + post_id, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  226. </span><span style="color:#d3d0c8;">});
  227. </span></pre>
  228. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  229. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/users/:user_id/posts/:post_id</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  230. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> user_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">user_id</span><span style="color:#4f5b66;">&quot;);
  231. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> post_id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">post_id</span><span style="color:#4f5b66;">&quot;);
  232. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">User: </span><span style="color:#4f5b66;">&quot; + user_id + &quot;</span><span style="color:#a3be8c;">, Post: </span><span style="color:#4f5b66;">&quot; + post_id, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  233. </span><span style="color:#4f5b66;">});
  234. </span></pre>
  235. </div>
  236. <h3>正規表現パターン</h3>
  237. <p><code>:param</code> の代わりに正規表現をパスに書くこともできます。キャプチャグループの値は <code>req.matches</code> で取得します。型は <code>std::smatch</code> です。</p>
  238. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  239. <span style="color:#747369;">// 数字のみのIDを受け付ける
  240. </span><span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">&quot;(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  241. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">]; </span><span style="color:#747369;">// 最初のキャプチャグループ
  242. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">&quot; + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  243. </span><span style="color:#d3d0c8;">});
  244. </span></pre>
  245. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  246. <span style="color:#a7adba;">// 数字のみのIDを受け付ける
  247. </span><span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">&quot;(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#4f5b66;">)&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  248. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#4f5b66;">[</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">]; </span><span style="color:#a7adba;">// 最初のキャプチャグループ
  249. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">File ID: </span><span style="color:#4f5b66;">&quot; + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">(id), &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  250. </span><span style="color:#4f5b66;">});
  251. </span></pre>
  252. </div>
  253. <p><code>/files/42</code> にはマッチしますが、<code>/files/abc</code> にはマッチしません。入力値を絞り込みたいときに便利です。</p>
  254. <h2>レスポンスの組み立て</h2>
  255. <p>ハンドラーの第2引数 <code>res</code> を使って、クライアントに返すレスポンスを組み立てます。</p>
  256. <h3>ボディとContent-Type</h3>
  257. <p><code>res.set_content()</code> でボディとContent-Typeを設定します。これだけでステータスコード200のレスポンスが返ります。</p>
  258. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  259. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  260. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  261. </span><span style="color:#d3d0c8;">});
  262. </span></pre>
  263. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  264. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  265. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  266. </span><span style="color:#4f5b66;">});
  267. </span></pre>
  268. </div>
  269. <h3>ステータスコード</h3>
  270. <p>ステータスコードを変えたいときは、<code>res.status</code> に代入します。</p>
  271. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  272. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/not-found</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  273. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#f2777a;">status </span><span style="color:#d3d0c8;">= </span><span style="color:#f99157;">404</span><span style="color:#d3d0c8;">;
  274. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Not found</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  275. </span><span style="color:#d3d0c8;">});
  276. </span></pre>
  277. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  278. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/not-found</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  279. </span><span style="color:#4f5b66;"> res.</span><span style="color:#bf616a;">status </span><span style="color:#4f5b66;">= </span><span style="color:#d08770;">404</span><span style="color:#4f5b66;">;
  280. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Not found</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  281. </span><span style="color:#4f5b66;">});
  282. </span></pre>
  283. </div>
  284. <h3>レスポンスヘッダー</h3>
  285. <p><code>res.set_header()</code> でレスポンスヘッダーを追加できます。</p>
  286. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  287. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/with-header</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  288. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_header</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">X-Custom</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">my-value</span><span style="color:#d3d0c8;">&quot;);
  289. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  290. </span><span style="color:#d3d0c8;">});
  291. </span></pre>
  292. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  293. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/with-header</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  294. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_header</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">X-Custom</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">my-value</span><span style="color:#4f5b66;">&quot;);
  295. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  296. </span><span style="color:#4f5b66;">});
  297. </span></pre>
  298. </div>
  299. <h2>前章のサーバーを読み解く</h2>
  300. <p>ここまでの知識を使って、前章で用意したテスト用サーバーを改めて見てみましょう。</p>
  301. <h3>GET /hi</h3>
  302. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  303. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/hi</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  304. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Hello!</span><span style="color:#d3d0c8;">&quot;, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  305. </span><span style="color:#d3d0c8;">});
  306. </span></pre>
  307. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  308. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/hi</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  309. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Hello!</span><span style="color:#4f5b66;">&quot;, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  310. </span><span style="color:#4f5b66;">});
  311. </span></pre>
  312. </div>
  313. <p>最もシンプルなハンドラーです。リクエストの情報は使わないので、<code>req</code> の変数名を省略しています。<code>"Hello!"</code> というテキストをそのまま返します。</p>
  314. <h3>GET /search</h3>
  315. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  316. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/search</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  317. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> q = req.</span><span style="color:#6699cc;">get_param_value</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">q</span><span style="color:#d3d0c8;">&quot;);
  318. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">Query: </span><span style="color:#d3d0c8;">&quot; + q, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  319. </span><span style="color:#d3d0c8;">});
  320. </span></pre>
  321. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  322. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/search</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  323. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> q = req.</span><span style="color:#8fa1b3;">get_param_value</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">q</span><span style="color:#4f5b66;">&quot;);
  324. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">Query: </span><span style="color:#4f5b66;">&quot; + q, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  325. </span><span style="color:#4f5b66;">});
  326. </span></pre>
  327. </div>
  328. <p><code>req.get_param_value("q")</code> でクエリパラメーター <code>q</code> の値を取り出します。<code>/search?q=cpp-httplib</code> なら、レスポンスは <code>"Query: cpp-httplib"</code> になります。</p>
  329. <h3>POST /post</h3>
  330. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  331. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/post</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  332. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(req.</span><span style="color:#f2777a;">body</span><span style="color:#d3d0c8;">, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  333. </span><span style="color:#d3d0c8;">});
  334. </span></pre>
  335. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  336. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/post</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  337. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(req.</span><span style="color:#bf616a;">body</span><span style="color:#4f5b66;">, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  338. </span><span style="color:#4f5b66;">});
  339. </span></pre>
  340. </div>
  341. <p>クライアントが送ったリクエストボディを、そのままレスポンスとして返すエコーサーバーです。<code>req.body</code> にボディが丸ごと入っています。</p>
  342. <h3>POST /submit</h3>
  343. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  344. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/submit</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  345. </span><span style="color:#d3d0c8;"> std::string result;
  346. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">for </span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;[key, val] : req.</span><span style="color:#f2777a;">params</span><span style="color:#d3d0c8;">) {
  347. </span><span style="color:#d3d0c8;"> result += key + &quot;</span><span style="color:#99cc99;"> = </span><span style="color:#d3d0c8;">&quot; + val + &quot;</span><span style="color:#66cccc;">\n</span><span style="color:#d3d0c8;">&quot;;
  348. </span><span style="color:#d3d0c8;"> }
  349. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(result, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  350. </span><span style="color:#d3d0c8;">});
  351. </span></pre>
  352. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  353. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/submit</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  354. </span><span style="color:#4f5b66;"> std::string result;
  355. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">for </span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;[key, val] : req.</span><span style="color:#bf616a;">params</span><span style="color:#4f5b66;">) {
  356. </span><span style="color:#4f5b66;"> result += key + &quot;</span><span style="color:#a3be8c;"> = </span><span style="color:#4f5b66;">&quot; + val + &quot;</span><span style="color:#96b5b4;">\n</span><span style="color:#4f5b66;">&quot;;
  357. </span><span style="color:#4f5b66;"> }
  358. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(result, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  359. </span><span style="color:#4f5b66;">});
  360. </span></pre>
  361. </div>
  362. <p>フォームデータとして送られたキーと値のペアを、<code>req.params</code> でループ処理しています。構造化束縛 <code>auto &amp;[key, val]</code> を使って、各ペアを取り出しています。</p>
  363. <h3>POST /upload</h3>
  364. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  365. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Post</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/upload</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  366. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> f = req.</span><span style="color:#f2777a;">form</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">get_file</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">file</span><span style="color:#d3d0c8;">&quot;);
  367. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> content = f.</span><span style="color:#f2777a;">filename </span><span style="color:#d3d0c8;">+ &quot;</span><span style="color:#99cc99;"> (</span><span style="color:#d3d0c8;">&quot; + </span><span style="color:#6699cc;">std::to_string</span><span style="color:#d3d0c8;">(f.</span><span style="color:#f2777a;">content</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">size</span><span style="color:#d3d0c8;">()) + &quot;</span><span style="color:#99cc99;"> bytes)</span><span style="color:#d3d0c8;">&quot;;
  368. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(content, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  369. </span><span style="color:#d3d0c8;">});
  370. </span></pre>
  371. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  372. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Post</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/upload</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  373. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> f = req.</span><span style="color:#bf616a;">form</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">get_file</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">file</span><span style="color:#4f5b66;">&quot;);
  374. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> content = f.</span><span style="color:#bf616a;">filename </span><span style="color:#4f5b66;">+ &quot;</span><span style="color:#a3be8c;"> (</span><span style="color:#4f5b66;">&quot; + </span><span style="color:#8fa1b3;">std::to_string</span><span style="color:#4f5b66;">(f.</span><span style="color:#bf616a;">content</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">size</span><span style="color:#4f5b66;">()) + &quot;</span><span style="color:#a3be8c;"> bytes)</span><span style="color:#4f5b66;">&quot;;
  375. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(content, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  376. </span><span style="color:#4f5b66;">});
  377. </span></pre>
  378. </div>
  379. <p>マルチパートフォームで送られたファイルを受け取ります。<code>req.form.get_file("file")</code> で <code>"file"</code> という名前のフィールドを取得し、<code>f.filename</code> と <code>f.content.size()</code> でファイル名とサイズを返しています。</p>
  380. <h3>GET /users/:id</h3>
  381. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  382. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">/users/:id</span><span style="color:#d3d0c8;">&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  383. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">path_params</span><span style="color:#d3d0c8;">.</span><span style="color:#6699cc;">at</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">id</span><span style="color:#d3d0c8;">&quot;);
  384. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">User ID: </span><span style="color:#d3d0c8;">&quot; + id, &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  385. </span><span style="color:#d3d0c8;">});
  386. </span></pre>
  387. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  388. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">/users/:id</span><span style="color:#4f5b66;">&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  389. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">path_params</span><span style="color:#4f5b66;">.</span><span style="color:#8fa1b3;">at</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">id</span><span style="color:#4f5b66;">&quot;);
  390. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">User ID: </span><span style="color:#4f5b66;">&quot; + id, &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  391. </span><span style="color:#4f5b66;">});
  392. </span></pre>
  393. </div>
  394. <p><code>:id</code> の部分がパスパラメーターです。<code>req.path_params.at("id")</code> で値を取り出しています。<code>/users/42</code> なら <code>"42"</code>、<code>/users/alice</code> なら <code>"alice"</code> が得られます。</p>
  395. <h3>GET /files/(\d+)</h3>
  396. <div class="code-dark"><pre style="background-color:#2d2d2d;">
  397. <span style="color:#d3d0c8;">svr.</span><span style="color:#6699cc;">Get</span><span style="color:#d3d0c8;">(</span><span style="color:#cc99cc;">R</span><span style="color:#d3d0c8;">&quot;(</span><span style="color:#99cc99;">/files/(\d+)</span><span style="color:#d3d0c8;">)&quot;, [](</span><span style="color:#cc99cc;">const auto </span><span style="color:#d3d0c8;">&amp;req, </span><span style="color:#cc99cc;">auto </span><span style="color:#d3d0c8;">&amp;res) {
  398. </span><span style="color:#d3d0c8;"> </span><span style="color:#cc99cc;">auto</span><span style="color:#d3d0c8;"> id = req.</span><span style="color:#f2777a;">matches</span><span style="color:#d3d0c8;">[</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">];
  399. </span><span style="color:#d3d0c8;"> res.</span><span style="color:#6699cc;">set_content</span><span style="color:#d3d0c8;">(&quot;</span><span style="color:#99cc99;">File ID: </span><span style="color:#d3d0c8;">&quot; + </span><span style="color:#6699cc;">std::string</span><span style="color:#d3d0c8;">(id), &quot;</span><span style="color:#99cc99;">text/plain</span><span style="color:#d3d0c8;">&quot;);
  400. </span><span style="color:#d3d0c8;">});
  401. </span></pre>
  402. </div><div class="code-light"><pre style="background-color:#eff1f5;">
  403. <span style="color:#4f5b66;">svr.</span><span style="color:#8fa1b3;">Get</span><span style="color:#4f5b66;">(</span><span style="color:#b48ead;">R</span><span style="color:#4f5b66;">&quot;(</span><span style="color:#a3be8c;">/files/(\d+)</span><span style="color:#4f5b66;">)&quot;, [](</span><span style="color:#b48ead;">const auto </span><span style="color:#4f5b66;">&amp;req, </span><span style="color:#b48ead;">auto </span><span style="color:#4f5b66;">&amp;res) {
  404. </span><span style="color:#4f5b66;"> </span><span style="color:#b48ead;">auto</span><span style="color:#4f5b66;"> id = req.</span><span style="color:#bf616a;">matches</span><span style="color:#4f5b66;">[</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">];
  405. </span><span style="color:#4f5b66;"> res.</span><span style="color:#8fa1b3;">set_content</span><span style="color:#4f5b66;">(&quot;</span><span style="color:#a3be8c;">File ID: </span><span style="color:#4f5b66;">&quot; + </span><span style="color:#8fa1b3;">std::string</span><span style="color:#4f5b66;">(id), &quot;</span><span style="color:#a3be8c;">text/plain</span><span style="color:#4f5b66;">&quot;);
  406. </span><span style="color:#4f5b66;">});
  407. </span></pre>
  408. </div>
  409. <p>正規表現 <code>(\d+)</code> で数字だけのIDにマッチします。<code>/files/42</code> にはマッチしますが、<code>/files/abc</code> は404になります。<code>req.matches[1]</code> で最初のキャプチャグループの値を取得しています。</p>
  410. <h2>次のステップ</h2>
  411. <p>サーバーの基本がわかりましたね。ルーティング、リクエストの読み取り、レスポンスの組み立て。これだけで、十分に実用的なAPIサーバーが作れます。</p>
  412. <p>次は、静的ファイルの配信を見てみましょう。HTMLやCSSを配信するサーバーを作ります。</p>
  413. <p><strong>次:</strong> <a href="../04-static-file-server">Static File Server</a></p>
  414. </article>
  415. </main>
  416. </div>
  417. <footer class="footer">
  418. &copy; 2026 yhirose. All rights reserved.
  419. </footer>
  420. <script src="&#x2F;cpp-httplib/js/main.js"></script>
  421. </body>
  422. </html>