{"id":2906,"date":"2025-01-09T21:17:35","date_gmt":"2025-01-09T12:17:35","guid":{"rendered":"http:\/\/batmask.dothome.co.kr\/?p=2906"},"modified":"2025-01-09T21:17:35","modified_gmt":"2025-01-09T12:17:35","slug":"ktor-client-%ea%b8%b0%eb%b3%b8-%ec%82%ac%ec%9a%a9-%ec%a0%95%eb%a6%ac","status":"publish","type":"post","link":"http:\/\/batmask.net\/index.php\/2025\/01\/09\/2906\/","title":{"rendered":"KTor Client \uae30\ubcf8 \uc0ac\uc6a9 \uc815\ub9ac"},"content":{"rendered":"\n<p> \uac8c\uc784\uc73c\ub85c \ub118\uc5b4\uac00\uae30\uc804\uc5d0 \uc815\ub9ac\ud560\uac74 \uc815\ub9ac\ud558\uace0 \uac00\uc57c\uc9c0. Ktor Client \uc0ac\uc6a9\ubc95 \uacf5\ubd80\ud558\ub2e4\uac00 \uc694\ub85c\uacb0\uc11d \uac78\ub824\uc11c 1\uc8fc\uc77c \ub118\uac8c \ubb34\ub825\ud654 \ub418\uc5b4 \uc788\uc5c8\ub2e4. \uc554\ud2bc&#8230; \uc55e\uc5d0\uc11c \ub2e4\ub918\ub358 SQLDelight, Koin\uacfc \ud568\uaed8 Ktor\uae4c\uc9c0 \uc0ac\uc2e4 \uc804\ubd80 Kotlin Multi-Platform\uc744 \uc704\ud55c \uac83\ub4e4\uc774\uae30\ub3c4 \ud558\ub2e4. \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Room, Hilt, Retrofit\uc774 \uac01\uac01 DB, DI, Network\ub97c \uc704\ud55c \ub77c\uc774\ube0c\ub7ec\ub9ac\ub85c \uc8fc\ub85c \uc0ac\uc6a9\ub418\ub294\ub370, \uc790\ubc14\uae30\ubc18\uc774\ub77c\uc11c KMP\uc5d0\uc11c\ub294 1:1\ub85c \ub300\uccb4 \uac00\ub2a5\ud55c \uc21c\uc218 Kotlin \uae30\ubc18 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc744 \uc0ac\uc6a9 \ud558\ub294 \uac83\uc774\ub2e4. \ud558\uc9c0\ub9cc, KMP\uac00 \uc544\ub2c8\ub354\ub77c\ub3c4 \ucda9\ubd84\ud788 \uc0ac\uc6a9\ud560\ub9cc \ud558\uae30 \ub54c\ubb38\uc5d0, \uc88b\uc740 \uc120\ud0dd\uc9c0\ub77c\uace0 \uc0dd\uac01\ud55c\ub2e4. \uc55e\uc5d0\uc11c SQLDelight, Koin\uc744 \ub2e4\ub918\uc73c\ub2c8 \ub9c8\uc9c0\ub9c9\uc73c\ub85c Ktor\ub9cc \uc815\ub9ac\ud558\uba74 \uae30\ubcf8\uc740 \uc5b4\uca0c\ub4e0 \ud558\ub294\uac70.<\/p>\n\n\n\n<p>\uba3c\uc800, IntelliJ Idea\uc5d0\uc11c \ucf54\ud2c0\ub9b0\uc744 \uc774\uc6a9\ud55c \ubc29\ubc95\uc744 \uc54c\uc544\ubcf4\uc790. build.gradle.kts\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc774 ktor\ub97c \ucd94\uac00\ud55c\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"val ktorVersion = &quot;3.0.2&quot;\n...\ndependencies {\n...\n    implementation(&quot;io.ktor:ktor-client-core:$ktorVersion&quot;)\n    implementation(&quot;io.ktor:ktor-client-cio:$ktorVersion&quot;)\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> ktorVersion <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;3.0.2&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">..<\/span><span style=\"color: #ADBAC7\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCBDFB\">dependencies<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">..<\/span><span style=\"color: #ADBAC7\">.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;io.ktor:ktor-client-core:<\/span><span style=\"color: #6CB6FF\">$ktorVersion<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;io.ktor:ktor-client-cio:<\/span><span style=\"color: #6CB6FF\">$ktorVersion<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>ktor-client-core \ub294 \uae30\ubcf8\uc801\uc778 ktor core\ub85c \ubc18\ub4dc\uc2dc \ud3ec\ud568\ub418\uc5b4\uc57c \ud558\uace0, ktor-client-cio\ub294 \ub124\ud2b8\uc6cc\ud06c \ub9ac\ud018\uc2a4\ud2b8\ub97c \ucc98\ub9ac\ud558\ub294 \uc5d4\uc9c4\uc73c\ub85c \ud50c\ub7ab\ud3fc\uc5d0 \ub530\ub77c \uc6d0\ud558\ub294 \uac83\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4. \uac01 \uc5d4\uc9c4\ub4e4\uc774 \uc9c0\uc6d0\ud558\ub294 \ud50c\ub7ab\ud3fc\uacfc \ud2b9\uc9d5\uc740 <a href=\"https:\/\/ktor.io\/docs\/client-engines.html#platforms\">Engines<\/a> \uc5d0\uc11c \ud655\uc778 \uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<p> \uae30\ubcf8\uc801\uc778 \uc0ac\uc6a9\uc740 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"suspend fun main() {\n    val client = HttpClient(CIO)\n    val response: HttpResponse = client.get(&quot;https:\/\/ktor.io\/&quot;)\n    println(response.status)\n    client.close()\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">suspend<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">fun<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">main<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> client <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">HttpClient<\/span><span style=\"color: #ADBAC7\">(CIO)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> response: <\/span><span style=\"color: #F69D50\">HttpResponse<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> client.<\/span><span style=\"color: #DCBDFB\">get<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;https:\/\/ktor.io\/&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(response.status)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    client.<\/span><span style=\"color: #DCBDFB\">close<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc77c\ub2e8, main()\ud568\uc218\uac00 suspend\ub85c \uc120\uc5b8\ub418\uc5b4 \uc788\ub2e4. \uc774\ub294 KTor Client\uac00 coroutine\uc744 \uc774\uc6a9\ud558\uace0 \uc788\uae30 \ub54c\ubb38\uc778\ub370, \ucf54\ub8e8\ud2f4 \uc0ac\uc6a9\uc744 \uc704\ud574 \uadf8\ub807\uac8c \ud574\uc900\ub2e4. \ub2e4\uc74c \uccab \uc904\uc5d0 HttpClient \ub97c \ub9cc\ub4e4\uc5b4\uc8fc\uace0 \uc788\ub2e4. \uc778\uc790\ub85c CIO\ub97c \uba85\uc2dc\ud588\ub294\ub370, \uc0ac\uc6a9\ud560 \uc5d4\uc9c4\uc744 \uc778\uc790\ub85c \ub118\uaca8\uc8fc\uac8c \ub41c\ub2e4. \ucd08\uae30\ud654\uc5d0 \ub300\ud55c \ub0b4\uc6a9\uc774 \uaf64 \uc788\ub294\ub370 \uc77c\ub2e8, \uc774\ub807\uac8c \uc0ac\uc6a9\uc774 \uac00\ub2a5\ud558\ub2e4\ub294\uac78 \uc54c\uace0 \ub118\uc5b4\uac00\uc790. \ub2e4\uc74c\uc5d0 client.get()\uc744 \uc774\uc6a9\ud558\uace0 \uc788\ub294\ub370, HTTP\uc758 get\uc744 \uc774\uc6a9\ud574 \uc778\uc790\uc758 URL\ub85c HTTPRequest\ub97c \ubcf4\ub0b4\uac8c \ub41c\ub2e4. \uadf8 \uc751\ub2f5\uc744 \uc704\uc5d0\uc120 \ucd9c\ub825\ud574\uc8fc\uace0 client\ub97c close()\ud558\uc5ec \ub2eb\uc544\uc8fc\uace0 \uc788\ub2e4. <\/p>\n\n\n\n<p> \uc704 \ucf54\ub4dc\uc758 \uacb0\uacfc\ubb3c\uc740 \uc815\uc0c1\uc774\ub77c\uba74 200 OK\uac00 \ub5a8\uc5b4\uc9c8 \uac83\uc774\ub2e4. <\/p>\n\n\n\n<p>\uc704 \ucf54\ub4dc\ub97c \ubcf4\uba74 \uc608\uc0c1\ud558\uaca0\uc9c0\ub9cc, \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c\ub3c4 \uc704 \ub0b4\uc6a9\uc744 \ucc38\uace0\ud558\uc5ec \ucd94\uac00\ud574\uc8fc\uba74 \ub41c\ub2e4. \ub530\ub85c \uc124\uba85\ud560\uae4c \ud558\ub2e4\uac00, \uadf8\ub0e5 \ub77c\uc774\ube0c\ub7ec\ub9ac \ucd94\uac00\uac00 \ub05d\uc778\ub370 \uad73\uc774 \ubd88\ud544\uc694\ud574 \ubcf4\uc778\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Config KTor<\/h2>\n\n\n\n<p> Ktor\ub294 \uc55e\uc5d0\uc11c \ud50c\ub7ab\ud3fc\uc5d0 \ub9de\ub294 \uc5d4\uc9c4\uc774 \ud544\uc694\ud558\ub2e4\uace0 \ud588\ub2e4. KTor\uc758 \uad6c\uc131\uc740 \uc774 Engine\uc5d0 \ub354\ud574\uc11c Plugin \uc2dc\uc2a4\ud15c\uc73c\ub85c \uad6c\uc131\ub41c\ub2e4. \ud50c\ub7ec\uadf8\uc778\uc740 \ub9d0 \uadf8\ub300\ub85c, \ucd94\uac00 \uae30\ub2a5\ub4e4\uc744 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc5d0 \ucd94\uac00\ud558\uace0 HttpClient()\ub97c \uc815\uc758\ud560 \ub54c, install()\uc744 \uc774\uc6a9\ud574\uc11c \ucd94\uac00\ud558\uace0 \uc124\uc815 \ud560 \uc218 \uc788\ub2e4. \uc608\ub97c\ub4e4\uc5b4 Logging\uc774\ub098 JSON, XML \ub4f1\uc744 \ud30c\uc2f1\ud574\uc11c Serialization \uc2dc\ucf1c\uc8fc\ub294 \uae30\ub2a5\ub4e4\uc744 \uc774\ub7f0\uc2dd\uc73c\ub85c \ucd94\uac00\uac00 \uac00\ub2a5\ud558\ub2e4. <\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Engines<\/h3>\n\n\n\n<p> \uba3c\uc800 Engine\uc758 \uc124\uc815\uc744 \uc0b4\ud3b4\ubcf4\uc790. \uc5d4\uc9c4\ub9c8\ub2e4 \uc124\uc815\ubc29\ubc95\uc774 \uc880 \ub2e4\ub974\ub2e4. <a href=\"https:\/\/ktor.io\/docs\/client-engines.html#android\">\uacf5\uc2dd \uc0ac\uc774\ud2b8\ub97c \ucc38\uc870<\/a>\ud558\uc5ec \uba87 \uac1c \uc608\ub97c\ub4e4\uc5b4\ubcf4\uc790. \ub2e4\uc74c\uc740 \uc548\ub4dc\ub85c\uc774\ub4dc \uc5d4\uc9c4\uc758 \uc608\uc774\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"implementation(&quot;io.ktor:ktor-client-android:$ktor_version&quot;)\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;io.ktor:ktor-client-android:<\/span><span style=\"color: #6CB6FF\">$ktor_version<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p> \uba3c\uc800 \uc704\uc640\uac19\uc774 \ud574\ub2f9 \uc5d4\uc9c4 \ub77c\uc774\ube0c\ub7ec\ub9ac\uc758 \ucd94\uac00\uac00 \ud544\uc694\ud558\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"val client = HttpClient(Android) {\n    engine {\n        \/\/ this: AndroidEngineConfig\n        connectTimeout = 100_000\n        socketTimeout = 100_000\n        proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress(&quot;localhost&quot;, 8080))\n    }\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> client <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">HttpClient<\/span><span style=\"color: #ADBAC7\">(Android) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">engine<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #768390\">\/\/ this: AndroidEngineConfig<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        connectTimeout <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">100_000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        socketTimeout <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">100_000<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        proxy <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">Proxy<\/span><span style=\"color: #ADBAC7\">(Proxy.Type.HTTP, <\/span><span style=\"color: #DCBDFB\">InetSocketAddress<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;localhost&quot;<\/span><span style=\"color: #ADBAC7\">, <\/span><span style=\"color: #6CB6FF\">8080<\/span><span style=\"color: #ADBAC7\">))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc5d4\uc9c4\ub3c4 \uadf8\ub807\uace0 \ub098\uc911\uc5d0 \ub098\uc624\ub294 \ud50c\ub7ec\uadf8\uc778\ub3c4 \uadf8\ub807\uace0 HttpClient()\uc758 \ud568\uc218 \ud30c\ub77c\ubbf8\ud130\ub97c \uc774\uc6a9\ud558\uc5ec \uc124\uc815\ud55c\ub2e4. \uc704 \uc548\ub4dc\ub85c\uc774\ub4dc\uc758 \uc608\ub97c \ubcf4\uba74, connect timeout\uacfc socket timeout, proxy\ub4f1\uc744 \uc124\uc815\ud558\uace0 \uc788\ub2e4. \uc124\uc815\uac12\ub4e4\uc740 <a href=\"https:\/\/api.ktor.io\/ktor-client\/ktor-client-android\/io.ktor.client.engine.android\/-android-engine-config\/index.html?_gl=1*h5so11*_ga*NDM1Nzg3OTU4LjE3MzU0NjI3NTc.*_ga_9J976DJZ68*MTczNjQyMDkxMC4xMy4xLjE3MzY0MjE5MDcuMC4wLjA.\">\uac01 \uc5d4\uc9c4\uc5d0 \ub300\ud55c \ubb38\uc11c<\/a>\ub97c \ubcf4\uba74 \uc54c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Plugins<\/h3>\n\n\n\n<p> \ud50c\ub7ec\uadf8\uc778\uc740 \ub85c\uae45\uc5d0 \ub300\ud574 \uc0b4\ud3b4\ubcf4\uc790. KTor\uc758 \ub85c\uae45\uc5d0 \ub300\ud574 \uba3c\uc800 \ub9d0\ud574\ubcf4\uc790\uba74, JVM\uc704\uc5d0\uc11c <a href=\"https:\/\/www.slf4j.org\/\">SLF4J(Simple Logging Facade for Java)<\/a> \ub77c\ub294 \ucd94\uc0c1 \ub808\uc774\uc5b4\ub97c \uc0ac\uc6a9\ud55c\ub2e4\uace0 \ud55c\ub2e4. \uc774\uac74 \uc77c\uc885\uc758 \uc778\ud130\ud398\uc774\uc2a4\ub85c \uc791\ub3d9\ud574\uc11c \uc2e4\uc81c \uad6c\ud604\uacfc API\ub97c \ubd84\ub9ac\uc2dc\ucf1c\uc900\ub2e4. \uadf8\ub807\ub2e4\ub294\uac74 \uc5ec\uae30\uc5d0 \ub9de\ub294 \ub85c\uae45 \ud504\ub808\uc784\uc6cc\ud06c\ub77c\uba74 \uc5b4\ub5a4 \uac83\uc774\ub4e0 \uc0ac\uc6a9\uc774 \uac00\ub2a5\ud574\uc9c4\ub2e4\ub294 \uc598\uae30. \uc5ec\uae30\uc11c\ub294 <a href=\"https:\/\/logback.qos.ch\/\">Logback<\/a>\uc744 \ud55c \ubc88 \uc801\uc6a9\ud574\ubcf4\uc790.<\/p>\n\n\n\n<p>\uba3c\uc800 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \ucd94\uac00\ud574\uc900\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"implementation(&quot;ch.qos.logback:logback-classic:$logback_version&quot;)\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;ch.qos.logback:logback-classic:<\/span><span style=\"color: #6CB6FF\">$logback_version<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ub9cc\uc57d \uc548\ub4dc\ub85c\uc774\ub4dc\ub77c\uba74, SLF4J \uc548\ub4dc\ub85c\uc774\ub4dc \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud558\uae38 \uad8c\uc7a5\ud55c\ub2e4\uace0 \ud55c\ub2e4. <\/p>\n\n\n\n<p>\ub85c\uae45 \ud50c\ub7ec\uadf8\uc778\uc758 \uc124\uce58\ub294 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"val client = HttpClient(CIO) {\n    install(Logging)\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> client <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">HttpClient<\/span><span style=\"color: #ADBAC7\">(CIO) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">install<\/span><span style=\"color: #ADBAC7\">(Logging)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ubc14\ub85c, HttpClient\uc758 \ud568\uc218 \ud30c\ub77c\ubbf8\ud130\uc5d0\uc11c install()\uc744 \uc774\uc6a9\ud558\uba74 \ub41c\ub2e4. <a href=\"https:\/\/api.ktor.io\/ktor-client\/ktor-client-plugins\/ktor-client-logging\/io.ktor.client.plugins.logging\/-logging-config\/?_gl=1*1kj59za*_ga*NDM1Nzg3OTU4LjE3MzU0NjI3NTc.*_ga_9J976DJZ68*MTczNjQyMDkxMC4xMy4xLjE3MzY0MjI0ODguMC4wLjA.\">\ub85c\uae45\uc758 config \ub294 LoggingConfig \ubb38\uc11c<\/a>\ub97c \ucc3e\uc544\ubcf4\uba74 \uc54c \uc218 \uc788\ub2e4. \uc0ac\uc6a9 \uc608\uc81c\ub97c \uc0b4\ud3b4\ubcf4\uc790\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"val client = HttpClient(CIO) {\n    install(Logging) {\n        logger = Logger.DEFAULT\n        level = LogLevel.HEADERS\n        filter { request -&gt;\n            request.url.host.contains(&quot;ktor.io&quot;)\n        }\n        sanitizeHeader { header -&gt; header == HttpHeaders.Authorization }\n    }\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> client <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">HttpClient<\/span><span style=\"color: #ADBAC7\">(CIO) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">install<\/span><span style=\"color: #ADBAC7\">(Logging) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        logger <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> Logger.DEFAULT<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        level <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> LogLevel.HEADERS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">filter<\/span><span style=\"color: #ADBAC7\"> { request <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            request.url.host.<\/span><span style=\"color: #DCBDFB\">contains<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;ktor.io&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">sanitizeHeader<\/span><span style=\"color: #ADBAC7\"> { header <\/span><span style=\"color: #F47067\">-&gt;<\/span><span style=\"color: #ADBAC7\"> header <\/span><span style=\"color: #F47067\">==<\/span><span style=\"color: #ADBAC7\"> HttpHeaders.Authorization }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>HttpClient\uc640 \uc720\uc0ac\ud558\uac8c install()\uc5d0\uc11c\ub3c4 \ud568\uc218 \ud30c\ub77c\ubbf8\ud130\ub97c \uc774\uc6a9\ud558\uace0 \uc788\ub2e4. logger\ub294 SLF4J\ub97c \uc0ac\uc6a9\ud560\uc9c0, Native\ub97c \uc0ac\uc6a9\ud560\uc9c0\ub4f1\uc744 \uc815\ud55c\ub2e4. Logger.DEFAULT \ub294 SLF4J\ub97c \uc0ac\uc6a9\ud55c\ub2e4\ub294 \uc758\ubbf8\uc774\ub2e4. level\uc740 \ub85c\uae45\ud560 level\uc744 \uc9c0\uc815\ud558\ub294 \uac83\uc778\ub370, LogLevel.HEADERS\ub294 request\/response header\ub9cc \ud45c\uc2dc\ud55c\ub2e4\ub294 \uc758\ubbf8\uc774\ub2e4. filter\ub294 \ub85c\uadf8\uc790\uccb4\uc758 \ud544\ud130\ub9c1 \uc124\uc815\uc778\ub370, \uc704 \uc608\uc81c\ub294 request\uc5d0\uc11c &#8220;ktor.io&#8221;\uac00 \ud3ec\ud568\ub41c \ud638\uc2a4\ud2b8\uc5d0 \ub300\ud574\uc11c\ub9cc \ud45c\uc2dc\ud55c\ub2e4\ub294 \uc758\ubbf8\uc774\ub2e4. \ub9c8\uc9c0\ub9c9\uc73c\ub85c, sanitizeHeader\ub294 \ud45c\uc2dc\ub418\uba74 \uc548\ub418\ub294 \ub0b4\uc6a9\uc744 \ub85c\uadf8\uc5d0\uc11c &#8216;***&#8217;\ub85c \ud45c\uc2dc\ud558\ub294 \ubd80\ubd84\uc774\ub2e4. \uc608\uc81c\uc5d0\uc120 Authorization \ubd80\ubd84\uc744 \uadf8\ub807\uac8c \ud45c\uc2dc\ud588\ub2e4. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Content negotiation and serialization ( REST API \uc0ac\uc6a9\uc608 ) <\/h2>\n\n\n\n<p>Rest API\ub97c \uc0ac\uc6a9\ud558\uace0 \uc2f6\ub2e4\uba74, Content negotiation \ud50c\ub7ec\uadf8\uc778\uc744 \ud544\uc694\ub85c \ud55c\ub2e4. \uc774 \ud50c\ub7ec\uadf8\uc778\uc758 \uc5ed\ud560\uc740 \uc11c\ubc84\uc640  \ud074\ub77c\uc774\uc5b8\ud2b8\uac04 \uc8fc\uace0\ubc1b\ub294 \ubbf8\ub514\uc5b4 \ud0c0\uc785\uc5d0 \ub300\ud574 \ucc98\ub9ac\ud574\uc900\ub2e4. \uc774 Content negotiation \ud50c\ub7ec\uadf8\uc778 \uc548\uc5d0\uc11c \ucee8\ud150\uce20\uac00 JSON\uc774\ub098 XML\ub4f1\uacfc \uac19\uc740 \uacbd\uc6b0, \ucf54\ud2c0\ub9b0\uc5d0\uc11c \uc0ac\uc6a9\ud558\ub294 Serialization \ud50c\ub7ec\uadf8\uc778\ub4f1\uc744 \ub530\ub85c \ucd94\uac00\ud574\uc900\ub2e4. <\/p>\n\n\n\n<p>Rest API \uc608\uc81c\ub85c \ub0b4\uc6a9\uc744 \ud655\uc778\ud574\ubcf4\uc790. \uba3c\uc800 Content negotiaion\uacfc Kotlin\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 Serializer\ub97c \ucd94\uac00\ud574\ubcf4\uc790.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"implementation(&quot;io.ktor:ktor-client-content-negotiation:$ktorVersion&quot;)\nimplementation(&quot;io.ktor:ktor-serialization-kotlinx-json:$ktorVersion&quot;)\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;io.ktor:ktor-client-content-negotiation:<\/span><span style=\"color: #6CB6FF\">$ktorVersion<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCBDFB\">implementation<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;io.ktor:ktor-serialization-kotlinx-json:<\/span><span style=\"color: #6CB6FF\">$ktorVersion<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\ub2e4\uc74c\uc73c\ub85c, Logging\uc5d0\uc11c \ud588\ub4ef\uc774 Content Negotiation\ud50c\ub7ec\uadf8\uc778\uc744 HttpClient\uc5d0 \ucd94\uac00\ud55c\ub2e4. \ub2e4\uc74c\uc740 openweathermap\uc744 \uc0ac\uc6a9\ud558\ub294 \uc608\uc81c\uc774\ub2e4.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"val client = HttpClient(Apache5) {\n    install(ContentNegotiation) {\n        json(Json {\n            isLenient = false\n        })\n    }\n\n    install(Logging)\n    defaultRequest {\n        url {\n            protocol = URLProtocol.HTTPS\n            host = &quot;api.openweathermap.org\/data\/2.5&quot;\n        }\n    }\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> client <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">HttpClient<\/span><span style=\"color: #ADBAC7\">(Apache5) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">install<\/span><span style=\"color: #ADBAC7\">(ContentNegotiation) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">json<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #DCBDFB\">Json<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            isLenient <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        })<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">install<\/span><span style=\"color: #ADBAC7\">(Logging)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">defaultRequest<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">url<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            protocol <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> URLProtocol.HTTPS<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            host <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #96D0FF\">&quot;api.openweathermap.org\/data\/2.5&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p> defaultRequest\ub294 \ucc28\ud6c4 request\ub97c \uac04\ud3b8\ud558\uac8c \ud558\uae30 \uc704\ud574 default\uac12\uc744 \uc124\uc815\ud558\ub294 \ubd80\ubd84\uc774\ub2e4. \uc774\uac78 \uc774\uc6a9\ud574 request\ub97c \ubcf4\ub0b4\ub294 \ud568\uc218\ub97c \ub9cc\ub4e4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"data class CurrentWeatherReqeust(\n    val latitude: Double,\n    val longitude: Double,\n    val mode: ResponseMode? = null,\n    val units: ResponseUnits? = null,\n    val language: String? = null\n)\n\/\/---- \nsuspend fun getCurrentWeather(client: HttpClient, currentWeatherRequest: CurrentWeatherReqeust) : CurrentWeather? {\n    return try {\n        val response: HttpResponse = client.get(&quot;\/weather&quot;) {\n            url {\n                parameters.append(&quot;lat&quot;, currentWeatherRequest.latitude.toString())\n                parameters.append(&quot;lon&quot;, currentWeatherRequest.longitude.toString())\n                parameters.append(&quot;appid&quot;, APP_ID)\n                if(currentWeatherRequest.mode != null) parameters.append(\n                    &quot;mode&quot;,\n                    currentWeatherRequest.mode.name\n                )\n                if(currentWeatherRequest.units != null) parameters.append(\n                    &quot;units&quot;,\n                    currentWeatherRequest.units.name\n                )\n                if(currentWeatherRequest.language != null) parameters.append(\n                    &quot;lang&quot;,\n                    currentWeatherRequest.language\n                )\n            }\n        }\n\n        if (response.status == HttpStatusCode.OK) {\n            response.body&lt;CurrentWeather&gt;()\n        } else {\n            println(&quot;Failed to retrieve current weather. Status: ${response.status}&quot;)\n            null\n        }\n    } catch (e: Exception) {\n        println(&quot;Error retrieving current weather: ${e.message}&quot;)\n        null\n    }\n}\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">data<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">CurrentWeatherReqeust<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> latitude: <\/span><span style=\"color: #F69D50\">Double<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> longitude: <\/span><span style=\"color: #F69D50\">Double<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> mode: <\/span><span style=\"color: #F69D50\">ResponseMode<\/span><span style=\"color: #ADBAC7\">? <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> units: <\/span><span style=\"color: #F69D50\">ResponseUnits<\/span><span style=\"color: #ADBAC7\">? <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> language: <\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">? <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #768390\">\/\/---- <\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">suspend<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">fun<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">getCurrentWeather<\/span><span style=\"color: #ADBAC7\">(client: <\/span><span style=\"color: #F69D50\">HttpClient<\/span><span style=\"color: #ADBAC7\">, currentWeatherRequest: <\/span><span style=\"color: #F69D50\">CurrentWeatherReqeust<\/span><span style=\"color: #ADBAC7\">) : <\/span><span style=\"color: #F69D50\">CurrentWeather<\/span><span style=\"color: #ADBAC7\">? {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">return<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">try<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> response: <\/span><span style=\"color: #F69D50\">HttpResponse<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> client.<\/span><span style=\"color: #DCBDFB\">get<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;\/weather&quot;<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">url<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;lat&quot;<\/span><span style=\"color: #ADBAC7\">, currentWeatherRequest.latitude.<\/span><span style=\"color: #DCBDFB\">toString<\/span><span style=\"color: #ADBAC7\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;lon&quot;<\/span><span style=\"color: #ADBAC7\">, currentWeatherRequest.longitude.<\/span><span style=\"color: #DCBDFB\">toString<\/span><span style=\"color: #ADBAC7\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;appid&quot;<\/span><span style=\"color: #ADBAC7\">, APP_ID)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #F47067\">if<\/span><span style=\"color: #ADBAC7\">(currentWeatherRequest.mode <\/span><span style=\"color: #F47067\">!=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">) parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    <\/span><span style=\"color: #96D0FF\">&quot;mode&quot;<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    currentWeatherRequest.mode.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #F47067\">if<\/span><span style=\"color: #ADBAC7\">(currentWeatherRequest.units <\/span><span style=\"color: #F47067\">!=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">) parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    <\/span><span style=\"color: #96D0FF\">&quot;units&quot;<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    currentWeatherRequest.units.name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #F47067\">if<\/span><span style=\"color: #ADBAC7\">(currentWeatherRequest.language <\/span><span style=\"color: #F47067\">!=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">) parameters.<\/span><span style=\"color: #DCBDFB\">append<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    <\/span><span style=\"color: #96D0FF\">&quot;lang&quot;<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    currentWeatherRequest.language<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #F47067\">if<\/span><span style=\"color: #ADBAC7\"> (response.status <\/span><span style=\"color: #F47067\">==<\/span><span style=\"color: #ADBAC7\"> HttpStatusCode.OK) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            response.<\/span><span style=\"color: #DCBDFB\">body<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">CurrentWeather<\/span><span style=\"color: #ADBAC7\">&gt;()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        } <\/span><span style=\"color: #F47067\">else<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;Failed to retrieve current weather. Status: ${response.status}&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #6CB6FF\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    } <\/span><span style=\"color: #F47067\">catch<\/span><span style=\"color: #ADBAC7\"> (e: <\/span><span style=\"color: #F69D50\">Exception<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;Error retrieving current weather: ${e.message}&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #6CB6FF\">null<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>CurrentWeatherRequest\ub294 request\ud3b8\uc758\uc0c1 \ub9cc\ub4e0 \ud074\ub798\uc2a4\uc774\ub2e4. \uc704\uc640\uac19\uc774 default\uac12\uc5d0 \uac12\uc744 \ucd94\uac00\ud574\uc11c get()\uc744 \uc774\uc6a9\ud574 request\ub97c \ubcf4\ub0b8\ub2e4. \uc774\ub807\uac8c \ubcf4\ub0b8 response\ub294 serialization\uc744 \uc774\uc6a9\ud574\uc11c data class\ub85c \ubc1b\uc544\ubcfc \uc218 \uc788\ub2e4. response\ub97c \ubc1b\ub294 data class\ub97c \uc77c\ubd80\ub9cc \ud45c\uc2dc\ud574\ubcf4\uba74 \ub2e4\uc74c\uacfc \uac19\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" data-code=\"@OptIn(ExperimentalSerializationApi::class)\n@Serializable\ndata class CurrentWeather(\n    @SerialName(&quot;coord&quot;) val coordinates: Coordinates,\n    @SerialName(&quot;weather&quot;) val weather: List&lt;Weather&gt;,\n    @SerialName(&quot;base&quot;) val base: String,\n    @SerialName(&quot;main&quot;) val main: Main,\n    @SerialName(&quot;visibility&quot;) val visibility: Int,\n    @SerialName(&quot;wind&quot;) val wind: Wind,\n    @SerialName(&quot;rain&quot;)\n    @EncodeDefault\n    val rain: Rain? = null,\n    @SerialName(&quot;snow&quot;)\n    @EncodeDefault\n    val snow: Snow? = null,\n    @SerialName(&quot;clouds&quot;) val clouds: Clouds,\n...\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F69D50\">@OptIn<\/span><span style=\"color: #ADBAC7\">(ExperimentalSerializationApi::<\/span><span style=\"color: #DCBDFB\">class<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F69D50\">@Serializable<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">data<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">CurrentWeather<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;coord&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> coordinates: <\/span><span style=\"color: #F69D50\">Coordinates<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;weather&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> weather: <\/span><span style=\"color: #F69D50\">List<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">Weather<\/span><span style=\"color: #ADBAC7\">&gt;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;base&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> base: <\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;main&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> main: <\/span><span style=\"color: #F69D50\">Main<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;visibility&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> visibility: <\/span><span style=\"color: #F69D50\">Int<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;wind&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> wind: <\/span><span style=\"color: #F69D50\">Wind<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;rain&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@EncodeDefault<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> rain: <\/span><span style=\"color: #F69D50\">Rain<\/span><span style=\"color: #ADBAC7\">? <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;snow&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@EncodeDefault<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> snow: <\/span><span style=\"color: #F69D50\">Snow<\/span><span style=\"color: #ADBAC7\">? <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">null<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">@SerialName<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;clouds&quot;<\/span><span style=\"color: #ADBAC7\">) <\/span><span style=\"color: #F47067\">val<\/span><span style=\"color: #ADBAC7\"> clouds: <\/span><span style=\"color: #F69D50\">Clouds<\/span><span style=\"color: #ADBAC7\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F47067\">..<\/span><span style=\"color: #ADBAC7\">.<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p> \uc5ec\uae30\uc11c \uc911\uc694\ud55c\uac74 \ubc14\ub85c @Serializable \uacfc @SerialName \uc5b4\ub178\ud14c\uc774\uc158\uc778\ub370, \uba3c\uc800 @Serializable \ub85c \uba85\uc2dc\ud574\uc57c Serialization\uc73c\ub85c \uc0ac\uc6a9\uc774 \uac00\ub2a5\ud558\uba70, @SerialName\uc740 \ud544\ub4dc\uc774\ub984 \ub300\uc2e0 Serialization\uc5d0\uc11c \uc0ac\uc6a9\ud560 \ub2e4\ub978 \uc774\ub984\uc744 \uc124\uc815\ud574\uc900\ub2e4. <\/p>\n\n\n\n<p> \uc774\uc640\uac19\uc774 \uc0ac\uc6a9\ud574\uc11c REST API\uac19\uc740 \uc694\uccad\uc744 \ud560 \uc218 \uc788\ub2e4. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\uc774 \uc678\uc5d0\ub3c4 http\uad00\ub828\ub41c \ub9ce\uc740 \uc791\uc5c5\uc774 \uc788\uc9c0\ub9cc, \uc694\uc815\ub3c4\ub9cc \ub2e4\ub8e8\uaca0\ub2e4. \ubb38\uc11c\ud654\uac00 \uaf64 \uc798\ub418\uc5b4 \uc788\uc73c\ubbc0\ub85c <a href=\"https:\/\/ktor.io\/\">\uacf5\uc2dd \uc0ac\uc774\ud2b8\uc778 Ktor.io<\/a> \uc5d0 \ubc29\ubb38\ud574\uc11c \ud544\uc694\ud55c \uc815\ubcf4\ub4e4\uc744 \uc5bb\uae30 \ubc14\ub780\ub2e4. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uac8c\uc784\uc73c\ub85c \ub118\uc5b4\uac00\uae30\uc804\uc5d0 \uc815\ub9ac\ud560\uac74 \uc815\ub9ac\ud558\uace0 \uac00\uc57c\uc9c0. Ktor Client \uc0ac\uc6a9\ubc95 \uacf5\ubd80\ud558\ub2e4\uac00 \uc694\ub85c\uacb0\uc11d \uac78\ub824\uc11c 1\uc8fc\uc77c \ub118\uac8c \ubb34\ub825\ud654 \ub418\uc5b4 \uc788\uc5c8\ub2e4. \uc554\ud2bc&#8230; \uc55e\uc5d0\uc11c \ub2e4\ub918\ub358 SQLDelight, Koin\uacfc \ud568\uaed8 Ktor\uae4c\uc9c0 \uc0ac\uc2e4 \uc804\ubd80 Kotlin Multi-Platform\uc744 \uc704\ud55c \uac83\ub4e4\uc774\uae30\ub3c4 \ud558\ub2e4. \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Room, Hilt, Retrofit\uc774 \uac01\uac01 DB, DI, Network\ub97c \uc704\ud55c \ub77c\uc774\ube0c\ub7ec\ub9ac\ub85c \uc8fc\ub85c \uc0ac\uc6a9\ub418\ub294\ub370, \uc790\ubc14\uae30\ubc18\uc774\ub77c\uc11c KMP\uc5d0\uc11c\ub294 1:1\ub85c \ub300\uccb4 \uac00\ub2a5\ud55c \uc21c\uc218 Kotlin \uae30\ubc18 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub4e4\uc744 \uc0ac\uc6a9 \ud558\ub294 \uac83\uc774\ub2e4. \ud558\uc9c0\ub9cc, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[34],"tags":[418,75,417,419],"class_list":["post-2906","post","type-post","status-publish","format-standard","hentry","category-kotlin","tag-client","tag-config","tag-ktor","tag-rest-api"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/2906","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/comments?post=2906"}],"version-history":[{"count":33,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/2906\/revisions"}],"predecessor-version":[{"id":2939,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/2906\/revisions\/2939"}],"wp:attachment":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/media?parent=2906"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/categories?post=2906"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/tags?post=2906"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}