[Network] CORS, HTTP, REST API

Updated:

Categories:

Tags: , ,

๐Ÿ“Œ ๊ฐœ์ธ์ ์ธ ๊ณต๊ฐ„์œผ๋กœ ๊ณต๋ถ€๋ฅผ ๊ธฐ๋กํ•˜๊ณ  ๋ณต์Šตํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
์ •ํ™•ํ•˜์ง€ ์•Š์€ ์ •๋ณด๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ๋ฐ”๋ž๋‹ˆ๋‹ค :๐Ÿ˜ธ
[ํ‹€๋ฆฐ ๋‚ด์šฉ์€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๋ณต๋ฐ›์œผ์‹ค๊ฑฐ์—์š”]

SSR, CSR

  1. SSR (Server Side Rendering)
    1. Javascript ๊ฐ€ ์›น ํŽ˜์ด์ง€๋ฅผ ์„œ๋ฒ„์—์„œ ๋ Œ๋”๋ง (=์กฐ๋ฆฝ ์™„๋ฃŒ๋œ ๊ฐ€๊ตฌ๊ฐ€ ๋ฐฐ์†ก๋˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šท)
    2. ๋„ค์ด๋ฒ„ ๋ธ”๋กœ๊ทธ- 2020๋…„์— ๋„์ž…, ๊ฒ€์ƒ‰์—”์ง„ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ์ „์ฒด๋ฅผ SSR๋กœ ๋ณ€๊ฒฝ
  2. CSR (Client Side Rendering)
    1. โ†” SSR
    2. SSR์ด ์„œ๋ฒ„ ์ธก์—์„œ Javascript ๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋งํ•œ๋‹ค๋ฉด, CSR์€ ํด๋ผ์ด์–ธํŠธ์—์„œ Javascript ๊ฐ€ ํŽ˜์ด์ง€๋ฅผ ๋ Œ๋”๋ง (=๊ฐ€๊ตฌ์˜ ๋ถ€ํ’ˆ์ด ๋‚˜๋ˆ ์„œ ์šด์†ก์ด ์‰ฝ๊ฒŒ ๋ฐฐ์†ก๋˜๋Š” ๊ฒƒ๊ณผ ๋น„์Šท)
    3. ์›น ํŽ˜์ด์ง€์˜ ๊ณจ๊ฒฉ์ด ๋  ๋‹จ์ผ ํŽ˜์ด์ง€๋ฅผ ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋ณด๋ƒ„ ์ด๋•Œ ์„œ๋ฒ„๋Š” ์›น ํŽ˜์ด์ง€์™€ ํ•จ๊ป˜ JavaScript ํŒŒ์ผ์„ ๋ณด๋ƒ„
    4. ๊ฒ€์ƒ‰์—”์ง„ ์ตœ์ ํ™” - 0์ 
    5. CSR์—์„œ๋Š” SSR๊ณผ ๋‹ค๋ฅด๊ฒŒ, ์„œ๋ฒ„๊ฐ€ ์›น ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ๋ณด๋‚ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค
    6. ์—์ด์ ์Šค ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์ ์ด ์žˆ์Œ. โ‡’ ์‚ฌ์šฉ์ž์˜ ํŽธ๋ฆฌ์„ฑ.
    7. ์˜ˆ์ œ
      1. Agoda - ๊ฒ€์ƒ‰์—”์ง„ ๋…ธ์ถœ ๋Œ€์‹ ์— ๋งˆ์ผ€ํŒ…์œผ๋กœ ๋…ธ์ถœ

CORS

  • Cross-Origin Resource Sharing, ๊ต์ฐจ ์ถœ์ฒ˜ ๋ฆฌ์†Œ์Šค ๊ณต์œ 
  • ์„œ๋กœ ๋‹ค๋ฅธ Origin์„ ๊ฐ€์ง„ Application์ด ์„œ๋กœ์˜ Resource์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์คŒ

โ€‹

์„œ๋กœ ๋‹ค๋ฅธ Origin์„ ๊ฐ€์ง„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์ž์›์„ ๊ณต์œ ํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ์ƒ๊น€ โ‡’ ๋งŒ์•ฝ์— ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ๋‚ด ์‚ฌ์ดํŠธ์˜ ์ด๋ฏธ์ง€๋ฅผ ๋งํฌ๋กœ ์ ‘๊ทผ - ๋‹ค๋ฅธ๋ฐ์„œ ์‚ฌ์šฉ ์‹œ ํ•  ๋•Œ๋งˆ๋‹ค ๋ฆฌ์†Œ์Šค๊ฐ€ ๋“ค๊ฒŒ ๋จ โ‡’ ํด๋ผ์ด์–ธํŠธ(๋ธŒ๋ผ์šฐ์ €)์™€ ์„œ๋ฒ„ ๊ฐ„์— HTTP๋ฅผ ์š”์ฒญ ์‹œ ์„œ๋ฒ„๊ฐ€ HTTP์™€ ๋„ˆ๋Š” ํ—ˆ์šฉ ๊ฐ™์€ ๊ฑธ ๋‹ด์•„์„œ ๊ฐ™์ด ๋ณด๋‚ด๋Š”๋ฐ ๋งŒ์•ฝ์— Origin์ด ๋‹ค๋ฅผ ๊ฒฝ์šฐ CORS ์˜ค๋ฅ˜ ๋ฐœ์ƒ

  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋‘˜ ๋‹ค naver.com ์ผ ๊ฒฝ์šฐ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  naver.com ๊ฐ€ kakao.com ์— ์š”์ฒญํ•  ๊ฒฝ์šฐ ๋ฐœ์ƒ
  • CORS๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ฐœ์ƒ, ํŠน์ • ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  CORS๊ฐ€ ์‚ฌ๋ผ์ง€์ง€ ์•Š์Œ.
  • CORS ์„ค์ •์€ ์„œ๋ฒ„์—์„œ ํ•จ.
  • CORS ์ „์ฒด ํ—ˆ์šฉํ•˜๋ฉด ์•ˆ๋จ โ‡’ ์™œ? โ‡’ ๋ณด์•ˆ์ทจ์•ฝ์ ์„ ๋…ธ๋ฆฐ ๊ณต๊ฒฉ

์ถœ์ฒ˜(Origin)๋ž€?

  • ์ถœ์ฒ˜(Origin)๋ž€ URL ๊ตฌ์กฐ์—์„œ ์‚ดํŽด๋ณธ Protocal, Host, Port๋ฅผ ํ•ฉ์นœ ๊ฒƒ

  • ์ถœ์ฒ˜๋ฅผ ์•Œ๊ณ  ์‹ถ์€ ์‚ฌ์ดํŠธ์—์„œ F12 ๋ˆ„๋ฅด๊ณ  ์ฝ˜์†” ์ฐฝ์—ย location.origin๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ถœ์ฒ˜๋ฅผ ํ™•์ธ

  • ๊ฐ™์€ ์ถœ์ฒ˜ vs ๋‹ค๋ฅธ ์ถœ์ฒ˜

ํ˜„์žฌ ์›นํŽ˜์ด์ง€์˜ ์ฃผ์†Œ๊ฐ€ https://quokkavely.github.io/tech/ ์ผ๋•Œ

URL ๊ฒฐ๊ณผ ์ด์œ 
https://quokkavely.github.io/about ๊ฐ™์€ ์ถœ์ฒ˜ Protocol, Host, Port ๋™์ผ
https://quokkavely.github.io/about?q=work ๊ฐ™์€ ์ถœ์ฒ˜ Protocol, Host, Port ๋™์ผ
https://quokkavely.github.io/about#work ๊ฐ™์€ ์ถœ์ฒ˜ Protocol, Host, Port ๋™์ผ
http://quokkavely.github.io ๋‹ค๋ฅธ ์ถœ์ฒ˜ Protocol ๋‹ค๋ฆ„
https://quokkavely.github.io:81/about ๋‹ค๋ฅธ ์ถœ์ฒ˜ Port ๋‹ค๋ฆ„
https://quokkavely.heroku.com ๋‹ค๋ฅธ ์ถœ์ฒ˜ Host ๋‹ค๋ฆ„

๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same-Origin Policy)

  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋™์ผ ์ถœ์ฒ˜ ์ •์ฑ…(Same-Origin Policy, SOP)๋ฅผ ์ง€์ผœ์„œ ๋‹ค๋ฅธ ์ถœ์ฒ˜์˜ ๋ฆฌ์†Œ์Šค ์ ‘๊ทผ์„ ๊ธˆ์ง€ํ•จ

์•„๊ณ ๋‹ค์—์„œ ๊ฐœ๋ฐœ์ž๋ชจ๋“œ์— ๋“ค์–ด๊ฐ€๋ฉด cors์„ค์ • ๋ณผ ์ˆ˜ ์žˆ์Œ

  • ์žฅ์ 

  • XSS๋‚˜ย XSRFย ๋“ฑ์˜ ๋ณด์•ˆ ์ทจ์•ฝ์ ์„ ๋…ธ๋ฆฐ ๊ณต๊ฒฉ์„ ๋ฐฉ์–ด
  • ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ SOP์˜ ์˜ˆ์™ธ ์กฐํ•ญ์ด CORS

CORS ๋™์ž‘์›๋ฆฌ

Simple request

โ€‹

  • ๋ฐ”๋กœ ์š”์ฒญํ•ด์„œ ๋ฐ”๋กœ ์‘๋‹ต์„ ๋ฐ›๋Š” ๊ฒƒ

์•„๋ž˜ ์กฐ๊ฑด์— ํ•ด๋‹น๋˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•จ. - 1~3 ๋ฒˆ์˜ ์กฐ๊ฑด์„ ๋ชจ๋‘ ์ถฉ์กฑํ•ด์•ผ ํ•จ

  1. ์š”์ฒญ ๋ฉ”์„œ๋“œ(method) : 3๊ฐœ ์ค‘ ํ•˜๋‚˜์— ํ•ด๋‹น ๋˜์–ด์•ผ ํ•จ,
    1. GET
    2. HEAD
    3. POST
  2. ํ—ค๋”
    1. Accept, Accept-Language, Content-Language, Content-Type, DPR, Downlink, Save-Data, Viewport-Width, Width ๋ฅผ ์ œ์™ธํ•œ ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์•ˆ ๋จ
  3. Content-Type ํ—ค๋”
    1. application/x-www-form-urlencoded, multipart/form-data, text/plain ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉ
    2. ์•„๋งˆ JSON ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ Simple request๋Š” ์‚ฌ์šฉ ๋ชปํ•จ

Preflight request

  • Preflight ์š”์ฒญ์€ ์‹ค์ œ ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๊ธฐ ์ „์—ย OPTIONS๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์‹ค์ œ ์š”์ฒญ์„ ์ „์†กํ• ์ง€ ํŒ๋‹จ
  • OPTIONSย ๋ฉ”์„œ๋“œ๋กœ ์„œ๋ฒ„์— ์˜ˆ๋น„ ์š”์ฒญ์„ ๋จผ์ € ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„๋Š” ์ด ์˜ˆ๋น„ ์š”์ฒญ์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœย Access-Control-Allow-Originย ํ—ค๋”๋ฅผ ํฌํ•จํ•œ ์‘๋‹ต์„ ๋ธŒ๋ผ์šฐ์ €์— ๋ณด๋ƒ„
  • ๋ธŒ๋ผ์šฐ์ €๋Š” ๋‹จ์ˆœ ์š”์ฒญ๊ณผ ๋™์ผํ•˜๊ฒŒย Access-Control-Allow-Originย ํ—ค๋”๋ฅผ ํ™•์ธํ•ด์„œ CORS ๋™์ž‘์„ ์ˆ˜ํ–‰ํ• ์ง€ ํŒ๋‹จ

CORS ์—๋Ÿฌ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • ์•ž์—์„œ ์ด์•ผ๊ธฐ ํ•œ CORS ๋™์ž‘ ์›๋ฆฌ๋ฅผ ๋ณด๋ฉด, ์„œ๋ฒ„์—์„œย Access-Control-Allow-Originย ํ—ค๋”๋ฅผ ํฌํ•จํ•œ ์‘๋‹ต์„ ๋ธŒ๋ผ์šฐ์ €์— ๋ณด๋‚ด๋Š” ๋ฐฉ์‹์œผ๋กœ CORS ์—๋Ÿฌ๋ฅผ ํ•ด๊ฒฐ๊ฐ€๋Šฅ.
  • ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ CORS ์—๋Ÿฌ๋ฅผ ํ™•์ธํ–ˆ๋‹ค๋ฉด, ์„œ๋ฒ„์—ย Access-Control-Allow-Originย ๋“ฑ CORS๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์‘๋‹ต ํ—ค๋”๋ฅผ ํฌํ•จํ•ด ๋‹ฌ๋ผ๊ณ  ์š”์ฒญํ•ด์•ผ ํ•จ.

HTTP ์š”์ฒญ ํ—ค๋”

  • CORS๋ฅผ ์œ„ํ•ด์„œ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์„œ๋ฒ„๋กœ ์š”์ฒญํ•˜๋Š” ํ—ค๋”

  • ์š”์ฒญ ํ—ค๋”๋“ค์€ ๋ณ„๋„๋กœ ๋ช…์‹œํ•ด ์ฃผ์ง€ ์•Š์•„๋„ ๋ธŒ๋ผ์šฐ์ €์—์„œย OPTIONSย ์š”์ฒญ์— ์ถ”๊ฐ€

  • OPTIONSโ†’ ์ ˆ๋Œ€ ๊นŒ๋จน์œผ๋ฉด ์•ˆ๋จ.

    1. Origin: <origin>
      1. Originย ํ—ค๋”๋Š” ์š”์ฒญํ•˜๋Š” ๋Œ€์ƒ์˜ ์ถœ์ฒ˜๋ฅผ ๋‚˜ํƒ€๋ƒ„
      2. API๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํŽ˜์ด์ง€์˜ ์ถœ์ฒ˜ ๊ฐ’์ด ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
    2. Access-Control-Request-Method: <method>
      1. Access-Control-Request-Methodย ํ—ค๋”๋Š” ์‹ค์ œ ์š”์ฒญ์ด ์–ด๋–ค HTTP ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”์ง€ ์„œ๋ฒ„์— ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
    3. Access-Control-Request-Headers: <field-name>[, <field-name>]
      1. Access-Control-Request-Headersย ํ—ค๋”๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด๋‚ด๋Š” ์ปค์Šคํ…€ ํ—ค๋” ์ด๋ฆ„์„ ์„œ๋ฒ„์— ์•Œ๋ ค์ฃผ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

HTTP ์‘๋‹ตํ—ค๋”

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ CORS๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์Œ

์‘๋‹ตํ—ค๋” ์ข…๋ฅ˜

HTTP ์‘๋‹ต ํ—ค๋” description Syntax ๋น„๊ณ 
Access-Control-Allow-Origin: <origin>|* ํ—ค๋”์— ์ž‘์„ฑ๋œ ์ถœ์ฒ˜๋งŒ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: <origin>
Access-Control-Allow-Origin: null
ย 
Access-Control-Allow-Methods: <method>[, <method>]* ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•  ๋•Œ ํ—ˆ์šฉ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ • Access-Control-Allow-Methods:,
POST, GET, OPTIONS,<br/ >Access-Control-Allow-Methods: *
preflight request ๋Œ€ํ•œ ์‘๋‹ต(Access-Control-Request-Method)
Access-Control-Expose-Headers cross-origin request์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ ์ค‘์ธ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์‘๋‹ต ํ—ค๋”๋ฅผ ์ง€์ • ๊ฐ€๋Šฅ Access-Control-Expose-Headers: [<header-name>[, <header-name>]*] ,
Access-Control-Expose-Headers: *
cross-origin request์— ๋Œ€ํ•œ ์‘๋‹ต
Access-Control-Allow-Headers ์‹ค์ œ ์š”์ฒญ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” HTTP ํ—ค๋”์˜ ๋ชฉ๋ก์„ ๋‚˜์—ด Access-Control-Allow-Headers: <header-name>[, <header-name>]*
Access-Control-Allow-Headers: *
preflight request์˜ ์‘๋‹ต์— ์‚ฌ์šฉ๋˜๋Š” ํ—ค๋”,
ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญํ•  ๋•Œ ์–ด๋–ค ํ—ค๋”๋“ค์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์„œ๋ฒ„๊ฐ€ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ.
Access-Control-Max-Age preflight request์˜ ๊ฒฐ๊ณผ๋ฅผ ์–ผ๋งˆ๋‚˜ ์˜ค๋ž˜ ์บ์‹œํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ„ Access-Control-Max-Age: <delta-seconds> preflight request์˜ ๊ฒฐ๊ณผ(์ฆ‰, Access-Control-Allow-Methods ๋ฐ Access-Control-Allow-Headers ํ—ค๋”์— ํฌํ•จ๋œ ์ •๋ณด)
Access-Control-Allow-Credentials:true Request.credentials๊ฐ€ include์ผ๋•Œ, ๋ธŒ๋ผ์šฐ์ €๋“ค์ด ์‘๋‹ต์„ ํ”„๋กœํŠธ์—”๋“œ ์ž๋ฐ”์ŠคํŠธ๋ฆฝํŠธ ์ฝ”๋“œ์— ๋…ธ์ถœํ• ์ง€์— ๋Œ€ํ•ด ์•Œ๋ ค Access-Control-Allow-Credentials: true, false์ผ ๊ฒฝ์šฐ ํ—ค๋” ์ƒ๋žต Access-Control-Allow-Credentials ๊ฐ’์ด true ์ผ ๊ฒฝ์šฐ์—๋งŒ ๋ธŒ๋ผ์šฐ์ €๋“ค์€ ํ”„๋กœํŠธ์—”๋“œ ์ž๋ฐ”์ŠคํŠธ๋ฆฝํŠธ์— ์‘๋‹ต์„ ๋…ธ์ถœํ•จ
  1. Access-Control-Allow-Origin: <origin> |*

    1.1 ํ—ค๋”์— ์ž‘์„ฑ๋œ ์ถœ์ฒ˜๋งŒ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉ

    1.2 ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

    • Access-Control-Allow-Origin: https://quokkavely.github.io
    • https://quokkavely.github.ioย ํŽ˜์ด์ง€์—์„œ ๋ธŒ๋ผ์šฐ์ €๋Š” ์„œ๋ฒ„ ์‘๋‹ต์œผ๋กœ ์˜จ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Œ
    • Access-Control-Allow-Origin: * : *(์™€์ผ๋“œ์นด๋“œ)๊ฐ€ ์ž‘์„ฑ๋˜์—ˆ๋‹ค๋ฉด ๋ธŒ๋ผ์šฐ์ €๋Š” ์ถœ์ฒ˜์— ์ƒ๊ด€์—†์ด ๋ชจ๋“  ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผ ๊ฐ€๋Šฅ

    1.3 ์˜ˆ์ œ

    1
    2
    3
    4
    5
    
       fetch('http://localhost:3001/cors', {
         method: 'PUT',
       }).then(function(response) {
       }).catch(function(error) {
       })
    
    • Access-Control-Allow-Originย ํ—ค๋”๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์€ ์„œ๋ฒ„์— API ํ˜ธ์ถœ ์‹œ ์—๋Ÿฌ ๋ฐœ์ƒ ํ•จ.
  2. Access-Control-Allow-Methods: <method>[, <method>]

    2.1 ๋ฆฌ์†Œ์Šค ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜๋Š” HTTP ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•ด ์ฃผ๋Š” ํ—ค๋”

    2.2 Access-Control-Allow-Methodsย ํ—ค๋”์—ย GET,ย PUT,ย POST,ย DELETEย ๋“ฑ์˜ HTTP ๋ฉ”์„œ๋“œ๋ฅผย ,๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ๋„˜๊ฒจ์คŒ

    Ex) Access-Control-Allow-Methods: GET, PUT

    2.3 ์˜ˆ์ œ

    1
    2
    3
    4
    5
    
       fetch('http://localhost:3001/cors', {
         method: 'PUT',
       }).then(function(response) {
       }).catch(function(error) {
       })
    

    2.4 Access-Control-Allow-Methodsย ํ—ค๋”๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์€ ์„œ๋ฒ„์— API๋ฅผ ํ˜ธ์ถœโ‡’ ์—๋Ÿฌ ๋ฐœ์ƒ,

    ์‘๋‹ต ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•จ.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
       @RestController
       public class CorsController {
          
           @CrossOrigin(origins = "*", methods = {RequestMethod.OPTIONS, RequestMethod.PUT})
           @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS)
           public ResponseEntity<?> handleOptionsRequest() {
               return ResponseEntity.ok().build();
           }
          
           @CrossOrigin(origins = "*", methods = {RequestMethod.OPTIONS, RequestMethod.PUT})
           @RequestMapping(value = "/cors", method = RequestMethod.PUT)
           public ResponseEntity<?> handlePutRequest() {
               return ResponseEntity.ok().build();
           }
       }
    

    Access-Control-Allow-Origin๋Š”ย *๋กœ ๋ชจ๋“  ์ถœ์ฒ˜๋ฅผ ํ—ˆ์šฉํ•œ ์ƒํƒœ์ด๊ณ , ๋ธŒ๋ผ์šฐ์ €์˜ ์š”์ฒญ ํ—ค๋”์— ํฌํ•จ๋œย Access-Control-Request-Methodย ํ—ค๋” ๊ฐ’์„ ๊ทธ๋Œ€๋กœย Access-Control-Allow-Methodsย ํ—ค๋”์— ์ถ”๊ฐ€

  3. Access-Control-Expose-Headers: [, ]*

    3.1 Access-Control-Allow-Headers ํ—ค๋”๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹ค์ œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์ „์— ์„œ๋ฒ„์— ๋ณด๋‚ด๋Š” ์‚ฌ์ „ ์š”์ฒญ(preflight request)์—์„œ ์‚ฌ์šฉ

    3.2 ์ด ํ—ค๋”๋Š” ์„œ๋ฒ„๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ์š”์ฒญ ํ—ค๋”์˜ ๋ชฉ๋ก์„ ์ง€์ • = ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ์š”์ฒญํ•  ๋•Œ ์–ด๋–ค ํ—ค๋”๋“ค์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์„œ๋ฒ„๊ฐ€ ๋ช…์‹œ

    3.3 ์‚ฌ์šฉ๋ฐฉ๋ฒ• : Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

    3.4 ์˜ˆ์ œ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
       @RestController
       public class CorsController {
          
           @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS)
           public ResponseEntity<?> handleOptionsRequest(@RequestHeader("Access-Control-Request-Method") String requestMethod) {
               HttpHeaders headers = new HttpHeaders();
               headers.set("Access-Control-Allow-Origin", "*");
               headers.set("Access-Control-Allow-Methods", requestMethod);
               return ResponseEntity.ok().headers(headers).build();
           }
          
           @RequestMapping(value = "/cors", method = RequestMethod.PUT)
           public ResponseEntity<?> handlePutRequest() {
               HttpHeaders headers = new HttpHeaders();
               headers.set("Access-Control-Allow-Origin", "*");
               headers.set("Access-Control-Expose-Headers", "X-Custom-Beomy");
               headers.set("X-Custom-Beomy", "Bemoy");
               return ResponseEntity.ok().headers(headers).build();
           }
       }
    

    3.4.1. ์„œ๋ฒ„์—์„œ Access-Control-Expose-Headersย ํ—ค๋”์—ย X-Custom-Beomy๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ๊ณ ,ย X-Custom-Beomyย ํ—ค๋”์— ๊ฐ’์„ ๋‹ด์•„ ์‘๋‹ต์„ ํ•˜๋ฉด

    3.4.2 ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์•„๋ž˜์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•ด์„œ X-Custom-Beomyย ํ—ค๋” ๊ฐ’์„ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋จ

    1
    2
    3
    4
    5
    6
    7
    8
    
      ```java
      fetch('http://localhost:3001/cors', {
        method: 'PUT',
      }).then(function(response) {
        console.log(response.headers.get('X-Custom-Beomy')) // Beomy
      }).catch(function(error) {
      })
      ```
    

    3.4.3. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ ‘๊ทผํ•  ํ—ค๋”๋ฅผ ๋ช…์‹œํ•ด ์ฃผ์ง€ ์•Š์œผ๋ฉด, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œย X-Custom-Beomyย ํ—ค๋” ๊ฐ’์€ย undefined

  4. Access-Control-Allow-Headers: [, ]*

    4.1 ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณด๋‚ด๋Š” ์š”์ฒญ ํ—ค๋”์— ํฌํ•จ๋œย Access-Control-Request-Headersย ํ—ค๋”์— ๋Œ€ํ•œ ์‘๋‹ต ๊ฒฐ๊ณผ

    4.2 ์ด ํ—ค๋”๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์„œ๋ฒ„๋Š” ์ถ”๊ฐ€ ํ—ค๋”๋ฅผ ํด๋ผ์ด์–ธํŠธ์— ๋…ธ์ถœ๊ฐ€๋Šฅ

    4.3 ์‚ฌ์šฉ๋ฐฉ๋ฒ•

    4.4 ์˜ˆ์‹œ

    1. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๊ฒŒ ๋˜๋ฉด,ย OPTIONSย ์š”์ฒญ ํ—ค๋”์˜ย Access-Control-Request-Headersย ํ—ค๋”์— ์ปค์Šคํ…€ ํ—ค๋” ์ด๋ฆ„์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„์—์„œ๋Š”ย Access-Control-Request-Headers์— ์ž‘์„ฑ๋œ ๊ฐ’์„ ๋ณด๊ณ ย Access-Control-Allow-Headersย ์‘๋‹ต ํ—ค๋”์— ์ปค์Šคํ…€ ํ—ค๋” ์ด๋ฆ„์„ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

    2. Access-Control-Allow-Headers: X-Custom-Request

    3. ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹คํ–‰ํ•˜์—ฌ,ย Access-Control-Allow-Headersย ์ฒ˜๋ฆฌ๋˜์ง€ ์•Š์€ API๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด,

      1
      2
      3
      4
      5
      6
      7
      8
      
      fetch('http://localhost:3001/cors', {
        method: 'PUT',
        headers: {
          'X-Custom-Request': 'Beomy',
        }
      }).then(function(response) {
      }).catch(function(error) {
      })
      
    4. ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ

    5. ์‘๋‹ตํ—ค๋” ์ถ”๊ฐ€ ํ•ด์ค˜์•ผํ•จ

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      
      @RestController
      public class CorsController {
               
          @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS)
          public ResponseEntity<?> handleOptionsRequest(
                  @RequestHeader("Access-Control-Request-Method") String requestMethod,
                  @RequestHeader("Access-Control-Request-Headers") String requestHeaders) {
              HttpHeaders headers = new HttpHeaders();
              headers.set("Access-Control-Allow-Origin", "*");
              headers.set("Access-Control-Allow-Methods", requestMethod);
              headers.set("Access-Control-Allow-Headers", requestHeaders);
              return ResponseEntity.ok().headers(headers).build();
          }
               
          @RequestMapping(value = "/cors", method = RequestMethod.PUT)
          public ResponseEntity<?> handlePutRequest(@RequestHeader("X-Custom-Request") String customRequest) {
              System.out.println(customRequest); // Beomy
              HttpHeaders headers = new HttpHeaders();
              headers.set("Access-Control-Allow-Origin", "*");
              return ResponseEntity.ok().headers(headers).build();
          }
      }
      
      • ๋ธŒ๋ผ์šฐ์ €์˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œย X-Custom-Requestย ํ—ค๋”์—ย Beomyย ๊ฐ’์„ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜์˜€๊ณ , ์„œ๋ฒ„์—์„œ๋Š”ย Access-Control-Allow-Headersย ํ—ค๋”์—ย Access-Control-Request-Headersย ํ—ค๋” ๊ฐ’์„ ์ €์žฅํ•˜์—ฌ ์„œ๋ฒ„์—์„œย X-Custom-Requestย ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ ์ฝ”๋“œ
  5. Access-Control-Max-Age: - ์–ธ์ œ๊นŒ์ง€ ์‚ด์•„๋‚จ์„ ์ˆ˜ ์žˆ๋Š”์ง€

    1. ์‚ฌ์šฉ๋ฐฉ๋ฒ• : ์•„๋ž˜์™€ ๊ฐ™์ด ์ดˆ ๋‹จ์œ„๋กœ ์บ์‹œ ์‹œ๊ฐ„์„ ์„ค์ •

      1. Access-Control-Max-Age: 60
        • ์œ„์˜ ์ฝ”๋“œ๋Š” 60์ดˆ ๋™์•ˆ preflight ์š”์ฒญ์„ ์บ์‹œ ํ•˜๋Š” ์ฝ”๋“œ.
        • 60์ดˆ ๋™์•ˆย OPTIONSย ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ๋น„ ์š”์ฒญ์„ ๋ณด๋‚ด์ง€ ์•Š์Œ
    2. ์˜ˆ์ œ

      1
      2
      3
      4
      5
      
      fetch('http://localhost:3001/cors', {
        method: 'PUT'
      }).then(function(response) {
      }).catch(function(error) {
      })
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      @RestController
      public class CorsController {
            
          @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS)
          public ResponseEntity<?> handleOptionsRequest(
                  @RequestHeader("Access-Control-Request-Method") String requestMethod) {
              HttpHeaders headers = new HttpHeaders();
              headers.set("Access-Control-Allow-Origin", "*");
              headers.set("Access-Control-Allow-Methods", requestMethod);
              headers.set("Access-Control-Max-Age", "60");
              return ResponseEntity.ok().headers(headers).build();
          }
            
          @RequestMapping(value = "/cors", method = RequestMethod.PUT)
          public ResponseEntity<?> handlePutRequest() {
              HttpHeaders headers = new HttpHeaders();
              headers.set("Access-Control-Allow-Origin", "*");
              return ResponseEntity.ok().headers(headers).build();
          }
      }
      
  6. Access-Control-Allow-Credentials: true

    1. ์ธ์ฆ์ •๋ณด๋ฅผ ๋‹ด์•„์„œ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š”์ง€ ์˜ค๋ฅ˜๊ฐ€๋‚˜๋ฉด true๋กœ ๋ณด๋‚ด๋ฉด ํ•ด๊ฒฐํ•  ์ˆ˜ ์ž‡์Œ. (Credential: ์ž๊ฒฉ์ฆ๋ช…)

    2. ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฟ ํ‚ค๊ฐ™์€ ๊ฑธ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ํ—ˆ์šฉํ•˜๋Š”์ง€๋ฅผ ๋‹ด๋Š” ๊ฒƒ.

      • ๊ฐœ๋ฐœ์ž๋„๊ตฌ์—์„œ ์ฟ ํ‚คํ™•์ธ ๊ฐ€๋Šฅ. ์ฟ ํ‚ค๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๊ด€๋ฆฌ

    3. ์‚ฌ์šฉ๋ฐฉ๋ฒ•

      Access-Control-Allow-Credentials: true

    4. ์˜ˆ์ œ

      1
      2
      3
      4
      5
      6
      
      fetch('http://localhost:3001/cors', {
        method: 'PUT',
        credentials: 'include'
      }).then(function(response) {
      }).catch(function(error) {
      })
      
      1. ์•„๋ž˜์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒ

      2. ์„œ๋ฒ„์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์‘๋‹ต ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•ด ์ฃผ์–ด์•ผ ํ•จ

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        
        @RestController
        public class CorsController {
                 
            @RequestMapping(value = "/cors", method = RequestMethod.OPTIONS)
            public ResponseEntity<?> handleOptionsRequest(
                    @RequestHeader("Access-Control-Request-Method") String requestMethod) {
                HttpHeaders headers = new HttpHeaders();
                headers.set("Access-Control-Allow-Origin", "https://www.google.com");
                headers.set("Access-Control-Allow-Methods", requestMethod);
                headers.set("Access-Control-Allow-Credentials", "true");
                return ResponseEntity.ok().headers(headers).build();
            }
                 
            @RequestMapping(value = "/cors", method = RequestMethod.PUT)
            public ResponseEntity<?> handlePutRequest() {
                HttpHeaders headers = new HttpHeaders();
                headers.set("Access-Control-Allow-Origin", "https://www.google.com");
                headers.set("Access-Control-Allow-Credentials", "true");
                return ResponseEntity.ok().headers(headers).build();
            }
        }
        
      3. Access-Control-Allow-Credentials: trueย ์ถ”๊ฐ€ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ,ย Access-Control-Allow-Originย ํ—ค๋”๋„ย *(์™€์ผ๋“œ์นด๋“œ)๊ฐ€ ์•„๋‹Œ ์ถœ์ฒ˜๋ฅผ ๋ช…์‹œํ•ด ์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

HTTP (HyperText Transfer Protocol)

  • HTML๊ณผ ๊ฐ™์€ ๋ฌธ์„œ๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ Application Layer ํ”„๋กœํ† ์ฝœ

  • HTTP๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์›น ์„œ๋ฒ„์˜ ์†Œํ†ต์„ ์œ„ํ•ด ๋””์ž์ธ ๋จ.

  • ์ „ํ†ต์ ์ธ ํด๋ผ์ด์–ธํŠธ-์„œ๋ฒ„ ๋ชจ๋ธ์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ HTTP messages ์–‘์‹์— ๋งž์ถฐ ์š”์ฒญ์„ ๋ณด๋‚ด๋ฉด, ์„œ๋ฒ„๋„ HTTP messages ์–‘์‹์— ๋งž์ถฐ ์‘๋‹ตํ•จ

  • HTTP๋Š” ํŠน์ • ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜์ง€ ์•Š๋Š” ํŠน์ง•์ด ์žˆ์Œ , Stateless(๋ฌด์ƒํƒœ์„ฑ)

HTTP Message

  1. ํด๋ผ์ด์–ธํŠธ์™€ ์„œ๋ฒ„ ์‚ฌ์ด์—์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ตํ™˜๋˜๋Š” ๋ฐฉ์‹

  2. ๋‘๊ฐ€์ง€ ์œ ํ˜•

    1. ์š”์ฒญ(Requests)
    2. ์‘๋‹ต(Responses)
  3. ๊ตฌ์กฐ

    • ๋ช‡ ์ค„์˜ ํ…์ŠคํŠธ ์ •๋ณด๋กœ ๊ตฌ์„ฑ
    • ์ง์ ‘ ์ž‘์„ฑ ํ•„์š” ์—†์Œ โ‡’ ๊ตฌ์„ฑํŒŒ์ผ, API, ๊ธฐํƒ€ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ ์ž๋™์œผ๋กœ ์™„์„ฑํ•จ
    • ์š”์ฒญ๊ณผ ์‘๋‹ต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์œ ์‚ฌํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง
      1. start line
        1. ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์˜ ์ƒํƒœ๋ฅผ ๋‚˜ํƒ€๋ƒ„
        2. ํ•ญ์ƒ ์ฒซ ๋ฒˆ์งธ ์ค„์— ์œ„์น˜
        3. ์‘๋‹ต์—์„œ๋Š” status line์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
      2. empty line - ํ—ค๋”์™€ ๋ณธ๋ฌธ์„ ๊ตฌ๋ถ„ํ•˜๋Š” ์—ญํ• .
      3. body
        1. ์š”์ฒญ๊ณผ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ๋‚˜ ์‘๋‹ต๊ณผ ๊ด€๋ จ๋œ ๋ฐ์ดํ„ฐ ๋˜๋Š” ๋ฌธ์„œ๋ฅผ ํฌํ•จ
        2. ์š”์ฒญ๊ณผ ์‘๋‹ต์˜ ์œ ํ˜•์— ๋”ฐ๋ผ ์„ ํƒ์ ์œผ๋กœ ์‚ฌ์šฉ
      4. ์ด ์ค‘ start line๊ณผ HTTP headers๋ฅผ ๋ฌถ์–ด ์š”์ฒญ์ด๋‚˜ ์‘๋‹ต์˜ ํ—ค๋“œ(head)๋ผ๊ณ  ํ•˜๊ณ , payload๋Š” body๋ผ๊ณ  ์ด์•ผ๊ธฐ ํ•จ

์š”์ฒญ

HTTP ์š”์ฒญ์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์„œ๋ฒ„์— ๋ณด๋‚ด๋Š” ๋ฉ”์‹œ์ง€

1. start line

  • 3๊ฐ€์ง€ ์š”์†Œ๊ฐ€ ์žˆ์Œ
    1. Mehtod = HTTP METHOD โ‡’ ์ˆ˜ํ–‰ํ•  ์ž‘์—…์ด๋‚˜ ๋ฐฉ์‹์„ ์„ค๋ช…
      1. GET, POST, DELETE, PUT = CRUD
      2. HEAD or OPTIONS
    2. ์ž์› = ์š”์ฒญํ•˜๋Š” ์ฃผ์†Œ
      1. ์ผ๋ฐ˜์ ์œผ๋กœ (URL์ด๋‚˜ URI) ๋˜๋Š” ํ”„๋กœํ† ์ฝœ, ํฌํŠธ, ๋„๋ฉ”์ธ์˜ ์ ˆ๋Œ€ ๊ฒฝ๋กœ
      2. ์˜ˆ์ œ
        1. origin ํ˜•์‹
          • ? ์™€ ์ฟผ๋ฆฌ ๋ฌธ์ž์—ด์ด ๋ถ™๋Š” ์ ˆ๋Œ€ ๊ฒฝ๋กœ
          • POST, GET, HEAD, OPTIONS ๋“ฑ์˜ method์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
          • POST / HTTP 1.1 GET /background.png HTTP/1.0 HEAD /test.html?query=alibaba HTTP/1.1 OPTIONS /anypage.html HTTP/1.0
        2. absolute ํ˜•์‹
          • ์™„์ „ํ•œ URL ํ˜•์‹์œผ๋กœ, ํ”„๋ก์‹œ์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒฝ์šฐ ๋Œ€๋ถ€๋ถ„ GET method์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ
          • GET <http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages> HTTP/1.1
        3. authority ํ˜•์‹
          • ๋„๋ฉ”์ธ ์ด๋ฆ„๊ณผ ํฌํŠธ ๋ฒˆํ˜ธ๋กœ ์ด๋ฃจ์–ด์ง„ URL์˜ authority component
          • HTTP ํ„ฐ๋„์„ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒฝ์šฐ, CONNECT์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๊ฐ€๋Šฅ CONNECT developer.mozilla.org:80 HTTP/1.1
    3. start line์— HTTP ๋ฒ„์ „์„ ํ•จ๊ป˜ ์ž…๋ ฅ
      1. HTTP ๋ฒ„์ „์— ๋”ฐ๋ผ HTTP message์˜ ๊ตฌ์กฐ๊ฐ€ ๋‹ฌ๋ผ์ง

2. Header

  • ๊ธฐ๋ณธ๊ตฌ์กฐ์— ๋”ฐ๋ฆ„

  • ํ—ค๋” ์ด๋ฆ„(๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„์ด ์—†๋Š” ๋ฌธ์ž์—ด), ์ฝœ๋ก ( : ), ๊ฐ’์„ ์ž…๋ ฅ

  • ๊ฐ’์€ ํ—ค๋”์— ๋”ฐ๋ผ ๋‹ค๋ฆ„ โ†’ ์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ํ—ค๋”๊ฐ€ ์žˆ๊ณ , ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ทธ๋ฃน์„ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ

  1. General headers
    1. ๋ฉ”์‹œ์ง€ ์ „์ฒด์— ์ ์šฉ๋˜๋Š” ํ—ค๋”, body๋ฅผ ํ†ตํ•ด ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ์™€๋Š” ๊ด€๋ จ์ด ์—†๋Š” ํ—ค๋”
  2. Request headers
    1. fetch๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ฌ ๋ฆฌ์†Œ์Šค๋‚˜ ํด๋ผ์ด์–ธํŠธ ์ž์ฒด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ํ—ค๋”๋ฅผ ์˜๋ฏธ
    2. User-Agent, Accept-Type, Accept-Language๊ณผ ๊ฐ™์€ ํ—ค๋”๋Š” ์š”์ฒญ์„ ๋ณด๋‹ค ๊ตฌ์ฒดํ™” ํ•จ.
    3. Referer์ฒ˜๋Ÿผ ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๊ฑฐ๋‚˜ If-None๊ณผ ๊ฐ™์ด ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ œ์•ฝ์„ ์ถ”๊ฐ€๊ฐ€๋Šฅ
  3. Representation headers (=์ด์ „์— Entity headers๋ผ ๋ถˆ๋ฆผ)
    1. body์— ๋‹ด๊ธด ๋ฆฌ์†Œ์Šค์˜ ์ •๋ณด(์ฝ˜ํ…์ธ  ๊ธธ์ด, MIME ํƒ€์ž… ๋“ฑ)๋ฅผ ํฌํ•จํ•˜๋Š” ํ—ค๋”

3. Body

  • HTTP messages ๊ตฌ์กฐ์˜ ๋งˆ์ง€๋ง‰์— ์œ„์น˜,
  • ๋ชจ๋“  ์š”์ฒญ์— body๊ฐ€ ํ•„์š”ํ•˜์ง„ ์•Š์Œ.(GET, HEAD, DELETE, OPTIONS์ฒ˜๋Ÿผ ์„œ๋ฒ„์— ๋ฆฌ์†Œ์Šค๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ•„์š”์—†์Œ) โ‡’ Request์ผ ๋•Œ get ์š”์ฒญ์€ ๋ฐ”๋””์— ์–ด๋–ค ์ •๋ณด๋ฅผ ๋‹ด์„ ์ˆ˜ ์—†์Œ (get์€ ์กฐํšŒ์ด๊ธฐ ๋•Œ๋ฌธ์—)
  • POST๋‚˜ PUT๊ณผ ๊ฐ™์€ ์ผ๋ถ€ ์š”์ฒญ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
  • ๋ณดํŽธ์ ์œผ๋กœ JSON ์œผ๋กœ ๋ณด๋ƒ„
  • ๋‘ ์ข…๋ฅ˜๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ
    1. Single-resource bodies(๋‹จ์ผ-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ):
      1. ํ—ค๋” ๋‘ ๊ฐœ(Content-Type๊ณผ Content-Length)๋กœ ์ •์˜๋œ ๋‹จ์ผ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ
    2. Multiple-resource bodies(๋‹ค์ค‘-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ) :
      1. ์—ฌ๋Ÿฌ ํŒŒํŠธ๋กœ ๊ตฌ์„ฑ๋œ ๋ณธ๋ฌธ์—์„œ๋Š” ๊ฐ ํŒŒํŠธ๋งˆ๋‹ค ๋‹ค๋ฅธ ์ •๋ณด๋ฅผ ์ง€๋‹˜
      2. ๋ณดํ†ต HTML form๊ณผ ๊ด€๋ จ์ด ์žˆ์Šต๋‹ˆ๋‹ค. - form์€ ์ด์ œ ์•ˆ์”€.

์‘๋‹ต

1. Status line

์‘๋‹ต์˜ ์ฒซ ์ค„์€ Status line์ด๋ผ๊ณ  ๋ถ€๋ฅด๋ฉฐ, ๋‹ค์Œ์˜ ์ •๋ณด๋ฅผ ํฌํ•จ

  1. ํ˜„์žฌ ํ”„๋กœํ† ์ฝœ์˜ ๋ฒ„์ „(HTTP/1.1)
  2. ์ƒํƒœ ์ฝ”๋“œ - ์š”์ฒญ์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. (200, 302, 404 ๋“ฑ)
  3. ์ƒํƒœ ํ…์ŠคํŠธ - ์ƒํƒœ ์ฝ”๋“œ์— ๋Œ€ํ•œ ์„ค๋ช…

Status line์€ HTTP/1.1 404 Not Found.์ฒ˜๋Ÿผ ์ƒ๊ฒผ์Šต๋‹ˆ๋‹ค.

2. Headers

์‘๋‹ต์— ๋“ค์–ด๊ฐ€๋Š” HTTP headers๋Š” ์š”์ฒญ ํ—ค๋”์™€ ๋™์ผํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง

๊ทธ๋ฃน์œผ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์Œ

โ€‹

  1. General headers
    1. ๋ฉ”์‹œ์ง€ ์ „์ฒด์— ์ ์šฉ๋˜๋Š” ํ—ค๋”๋กœ, body๋ฅผ ํ†ตํ•ด ์ „์†ก๋˜๋Š” ๋ฐ์ดํ„ฐ์™€๋Š” ๊ด€๋ จ์ด ์—†๋Š” ํ—ค๋”
  2. Response headers
    1. ์œ„์น˜ ๋˜๋Š” ์„œ๋ฒ„ ์ž์ฒด์— ๋Œ€ํ•œ ์ •๋ณด(์ด๋ฆ„, ๋ฒ„์ „ ๋“ฑ)์™€ ๊ฐ™์ด ์‘๋‹ต์— ๋Œ€ํ•œ ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ๊ฐ–๋Š” ํ—ค๋”๋กœ, Vary, Accept-Ranges์™€ ๊ฐ™์ด ์ƒํƒœ ์ค„์— ๋„ฃ๊ธฐ์—๋Š” ๊ณต๊ฐ„์ด ๋ถ€์กฑํ–ˆ๋˜ ์ถ”๊ฐ€ ์ •๋ณด๋ฅผ ์ œ๊ณต
  3. Representation headers
    1. body์— ๋‹ด๊ธด ๋ฆฌ์†Œ์Šค์˜ ์ •๋ณด(์ฝ˜ํ…์ธ  ๊ธธ์ด, MIME ํƒ€์ž… ๋“ฑ)๋ฅผ ํฌํ•จํ•˜๋Š” ํ—ค๋”

3. Body

201, 204์™€ ๊ฐ™์€ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ง€๋Š” ์‘๋‹ต์—๋Š” ๋ณธ๋ฌธ์ด ํ•„์š”์—†์Œ.

์‘๋‹ต์˜ body๋Š” ๋‘ ์ข…๋ฅ˜

  1. Single-resource bodies(๋‹จ์ผ-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ)
    • ๊ธธ์ด๊ฐ€ ์•Œ๋ ค์ง„ ๋‹จ์ผ-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ์€ ๋‘ ๊ฐœ์˜ ํ—ค๋”(Content-Type, Content-Length)๋กœ ์ •์˜
    • ๊ธธ์ด๋ฅผ ๋ชจ๋ฅด๋Š” ๋‹จ์ผ ํŒŒ์ผ๋กœ ๊ตฌ์„ฑ๋œ ๋‹จ์ผ-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ์€ Transfer-Encoding์ด chunked๋กœ ์„ค์ •๋˜์–ด ์žˆ์œผ๋ฉฐ, ํŒŒ์ผ์€ chunk๋กœ ๋‚˜๋‰˜์–ด ์ธ์ฝ”๋”ฉ๋˜์–ด ์žˆ์Œ
  2. Multiple-resource bodies(๋‹ค์ค‘-๋ฆฌ์†Œ์Šค ๋ณธ๋ฌธ)
    • ์„œ๋กœ ๋‹ค๋ฅธ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋Š” body

HTTP ์ƒํƒœ ์ฝ”๋“œ - ์™ธ์šฐ๊ธฐ

์˜ค๋ฅ˜๋ฉ”์„ธ์ง€๋Š” ์Šคํ”„๋ง์—์„œ ENUM Class ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉ [๋” ๋งŽ์€ HTTP ์ƒํƒœ์ฝ”๋“œ๋Š” ๋งํฌ์ฐธ์กฐ๐Ÿšฉ] (https://developer.mozilla.org/ko/docs/Web/HTTP/Status)

โœ”๏ธโœจํ•˜๊ธฐ ํ‘œ๋Š” ๊ผญ ์™ธ์›Œ์•ผํ•˜๋Š” ์ƒํƒœ์ฝ”๋“œ!

HTTP ์ƒํƒœ์ฝ”๋“œ ย  ย  name description
100๋ฒˆ๋Œ€ ์–ด๋–ค ์ •๋ณด๋ฅผ ํ‘œ์‹œํ•  ๋•Œ ์‚ฌ์šฉ ย  ย  ย 
200๋ฒˆ๋Œ€ ์„ฑ๊ณตํ–ˆ์„๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ 200 OK ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ย  ย  201 Created ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ย  ย  202 Accepted ์š”์ฒญ์ด ์ ‘์ˆ˜๋˜์—ˆ๋Š”๋ฐ, ์™„์ „ํžˆ ์ฒ˜๋ฆฌ๋˜์ง„ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
ย  ย  204 No Content ์š”์ฒญ์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์—ˆ์œผ๋‚˜, ์‘๋‹ตํ•  ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
300๋ฒˆ๋Œ€ Redirection 301 Moved Permanently ๋ฆฌ์†Œ์Šค์˜ ์œ„์น˜๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์Œ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค์˜ ์œ„์น˜๋ฅผ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
ย  ย  302 Found ๋ฆฌ์†Œ์Šค์˜ ์œ„์น˜๊ฐ€ ์ž„์‹œ๋กœ ๋ณ€๊ฒฝ๋˜์–ด์„œ, ์ž„์‹œ ์ฃผ์†Œ๋กœ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
400๋ฒˆ๋Œ€ ํด๋ผ์ด์–ธํŠธ ์˜ค๋ฅ˜ 400 Bad Request ์š”์ฒญ์ด ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
ย  ย  401 Unauthorized ์ธ์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์ธ์ฆ ์ •๋ณด๋ฅผ ํฌํ•จํ•ด์„œ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
ย  ย  403 Forbidden ๊ถŒํ•œ์ด ์—†์Šต๋‹ˆ๋‹ค.
ย  ย  404 Not Found ์š”์ฒญํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
ย  ย  405 Method Not Allowed ์ด ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
500๋ฒˆ๋Œ€ ์„œ๋ฒ„์˜ค๋ฅ˜ 500 Server Error ์„œ๋ฒ„์—์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
ย  ย  501 Not Implemented ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ย  ย  502 Bad Gateway ์„œ๋ฒ„๊ฐ€ ๊ฒŒ์ดํŠธ์›จ์ด ํ˜น์€ ํ”„๋ก์‹œ๋กœ๋ถ€ํ„ฐ ์ž˜๋ชป๋œ ์‘๋‹ต์„ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
ย  ย  503 Service Unavailable ์„œ๋ฒ„๊ฐ€ ํ˜„์žฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์„œ๋ฒ„๊ฐ€ ๊ณผ๋ถ€ํ•˜์ผ ๊ฒฝ์šฐ)
ย  ย  504 Gateway Timeout ์„œ๋ฒ„๊ฐ€ ๊ฒŒ์ดํŠธ์›จ์ด ํ˜น์€ ํ”„๋ก์‹œ๋กœ๋ถ€ํ„ฐ ๋Œ€๊ธฐ ์‹œ๊ฐ„๋™์•ˆ ์‘๋‹ต์„ ๋ฐ›์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค.

REST API

  • ๋ฐ์ดํ„ฐ๋‚˜ ์ž์›(Resource)์„ HTTP URI๋กœ ํ‘œํ˜„ํ•˜๊ณ , HTTP ํ”„๋กœํ† ์ฝœ์„ ํ†ตํ•ด ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์ •์˜ํ•˜๋Š” ๋ฐฉ์‹
  • REST API์—์„œ REST๋Š” โ€œRepresentational State Transferโ€์˜ ์•ฝ์ž
  • API ์•ˆ ์ง€ํ‚ค๋ฉด ์•ˆํ•ด๋ณธ ํ‹ฐ๊ฐ€ ๋‚จ - ๋ˆ„๊ตฌ๋‚˜ ๊ฐœ๋ฐœ์ž๋ผ๋ฉด ์•Œ์•„์•ผํ•˜๋Š” ๊ฒƒ.

Method

  1. GET : ์กฐํšŒํ•  ๋•Œ ์‚ฌ์šฉ

    1. ์„œ๋ฒ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค์ง€ ์•Š๋Š” ์š”์ฒญ์— ์‚ฌ์šฉ
    2. 1๋ฒˆ ํšŒ์›์˜ ์ •๋ณด๋ฅผ ์ฃผ์„ธ์š” ํ•˜๋ฉด ์‘๋‹ต์ด ๋‹ฌ๋ผ์ง€๋ฉด ์•ˆ๋จ.
    3. body์— ๋ฐ์ดํ„ฐ ๋‹ด์„ ์ˆ˜ ์—†์Œ. โ‡’ query parameter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ „๋‹ฌ
  2. POST : ์ƒ์„ฑ ๋ฐ ์ฒ˜๋ฆฌ

    1. get ๋ณด๋‹ค๋Š” ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์‚ฌ์šฉ

    2. ์ƒ์„ฑํ•  ๋•Œ ์‚ฌ์šฉ, body์— ๋ฐ์ดํ„ฐ ๋‹ด์„ ์ˆ˜ ์žˆ์Œ.

      ์ค‘๊ด„ํ˜ธ๊ฐ€ body๋ฅผ ๋œปํ•˜๊ณ , json type

    3. ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑ

  3. PUT, PATCH

    1. PATCH : ๋ฐ์ดํ„ฐ๋ฅผ ์ผ๋ถ€๋ถ„๋งŒ ์ˆ˜์ •ํ•  ๋•Œ
    2. PUT : ์ •๋ณด๋ฅผ ์ „์ฒด ๋ณ€๊ฒฝ ์‹œ , ๋ณ€๊ฒฝํ•˜๊ณ ์ž ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ ์ƒ์„ฑ๋„ ํ•จ.
      1. PUT์€ ์š”์ฒญ๋งˆ๋‹ค ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜ํ™˜ = ๋ฉฑ๋“ฑ์„ฑ.
    3. body์— data๋ฅผ ๋‹ด์„ ์ˆ˜ ์žˆ์Œ.
  4. DELETE

    1. ํ”ผ๋“œ ๊ธ€, ๋ฐ์ดํ„ฐ, ํšŒ์› ๋“ฑ ์‚ญ์ œ ํ•  ๋•Œ
  5. HEAD

    1. Resource์— Head ์ •๋ณด ์š”์ฒญํ•  ๋•Œ
    2. ์ง€๊ธˆ์€ ์‚ฌ์šฉํ•  ์ผ ์ž์ฃผ ์—†์Œ

    ๋งํฌ์ฐธ์กฐ

ํ”„๋กœ์ ํŠธ์‹œ API ์„ค๊ณ„ํ•  ๋•Œ ์˜ˆ์•ฝ๋˜๋ฉด body์— ๊ตณ์ด ์˜ˆ์•ฝ๋˜์—ˆ๋‹ค๊ณ  ๋ฌธ๊ตฌ ๋ณด๋‚ด๋Š”๋ฐ ํ•„์š” ์—†์Œ.

200์ด๋ผ๋Š” ์ฝ”๋“œ๋งŒ ๋ณด๋‚ด๋ฉด ์˜ˆ์•ฝ์ด ๋œ ๊ฒƒ์ž„ ์ด๊ฒƒ์œผ๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—

REST API๋ฅผ ์ž˜ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•œ 4๋‹จ๊ณ„

๋ฆฌ์ฒ˜๋“œ์Šจ์˜ REST ์„ฑ์ˆ™๋„ ๋ชจ๋ธ์„ ๊ตฌ์กฐํ™”

3๋‹จ๊ณ„ ๊นŒ์ง€ ์ง€ํ‚ค๊ธฐ ์–ด๋ ค์›€

1,2 ๋‹จ๊ณ„ ์ค‘์š” - ์™ธ์›Œ์•ผํ•จ!

0 ๋‹จ๊ณ„

  1. ๋‹จ์ˆœํžˆ HTTP ํ”„๋กœํ† ์ฝœ์„ ์‚ฌ์šฉํ•˜๊ธฐ๋งŒ ํ•ด๋„ ๋จ

  2. ๋ฌผ๋ก  ์ด ๊ฒฝ์šฐ, ํ•ด๋‹น API๋ฅผ REST API๋ผ๊ณ  ํ•  ์ˆ˜๋Š” ์—†์œผ๋ฉฐ, 0๋‹จ๊ณ„๋Š” ์ข‹์€ REST API๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ณธ ๋‹จ๊ณ„

  3. ํ—ˆ์ค€์ด๋ผ๋Š” ์ด๋ฆ„์˜ ์ฃผ์น˜์˜์˜ ์˜ˆ์•ฝ ๊ฐ€๋Šฅํ•œ ์‹œ๊ฐ„์„ ํ™•์ธํ•˜๊ณ , ์–ด๋–ค ํŠน์ • ์‹œ๊ฐ„์— ์˜ˆ์•ฝํ•˜๋Š” ์ƒํ™ฉ์„ ์˜ˆ๋กœ ๋“ค์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

    1. ์œ„ ํ‘œ์—์„œ ์ž˜๋ชป ๋œ ๊ฒƒ
      • ์กฐํšŒ์ธ๋ฐ POST ์‚ฌ์šฉ์€ ๋ถˆ๊ฐ€๋Šฅ ํ•œ ๊ฒƒ, ๊ทธ๋ฆฌ๊ณ  body์— ๋ฐ์ดํ„ฐ ๋„ฃ์€ ๊ฒƒ์€ ์ž˜๋ชป ๋œ ๊ฒƒ์ž„.
    2. ์‹œ๊ฐ„์— ํฌ์ธํŠธ๋ฅผ ์žก์ง€์•Š๊ณ  ํ—ˆ์ค€์ด๋ผ๋Š” ์ž์›์— ํฌ์ธํŠธ๋ฅผ ์žก์•„์•ผ ํ•จ.
    3. slot์— ์‘๋‹ต์ด ์™”๊ธฐ ๋•Œ๋ฌธ์— slot์— ๋“ค์–ด๊ฐ€์•ผ ํ•จ. ๊ทธ๋ฆฌ๊ณ  slot์˜ ์‹๋ณ„์ž๊ฐ€ ํ•„์š”

1๋‹จ๊ณ„

  1. 1๋‹จ๊ณ„์—์„œ๋Š” ๊ฐœ๋ณ„ ๋ฆฌ์†Œ์Šค์™€์˜ ํ†ต์‹ ์„ ์ค€์ˆ˜ํ•ด์•ผ ํ•จ

  2. ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋‚˜ ์ž์›(Resource)์„ HTTP URI๋กœ ํ‘œํ˜„

  3. ๋ชจ๋“  ์ž์›์€ ๊ฐœ๋ณ„ ๋ฆฌ์†Œ์Šค์— ๋งž๋Š” ์—”๋“œํฌ์ธํŠธ(Endpoint)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ๊ณผ ์š”์ฒญํ•˜๊ณ  ๋ฐ›์€ ์ž์›์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์‘๋‹ต์œผ๋กœ ์ „๋‹ฌ

    1. doctors๋กœ ๋ณ€๊ฒฝ๋˜์—ˆ๊ณ 
    2. slot์— ๋ฐฐ์—ด๋กœ ๋‹ด๊ฒจ์žˆ์Œ. jsonํ˜•ํƒœ๋ผ์„œ
    3. id : 123์œผ๋กœ ๋ณ€๊ฒฝ ๋จ
  4. ์˜ˆ์•ฝ์„ ์‹คํŒจํ–ˆ๋‹ค๋Š” ์ด์œ ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐ€์ง€์ผ ๊ฒฝ์šฐ์—๋Š” response๋ฅผ ๋„ฃ์–ด ์ค„ ์ˆ˜ ์žˆ์Œ (์ด์œ ๊ฐ€ ์ถฉ๋ถ„ํ• ๋•Œ)

  5. ์‹คํŒจํ•  ๊ฒฝ์šฐ ๋‹ค์‹œ ํ˜ธ์ถœ

  6. ๋‹ค์‹œ ํ˜ธ์ถœํ• ๋•Œ๋Š” ๋ถˆ๊ฐ€๋Šฅ ํ•œ ๋ฐ์ดํ„ฐ๋Š” ๋ณด์ด์ง€ ์•Š์•„์•ผ ํ•จ.

2๋‹จ๊ณ„

  1. 2๋‹จ๊ณ„์—์„œ๋Š” CRUD์— ๋งž๊ฒŒ ์ ์ ˆํ•œ HTTP ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์— ์ค‘์ 

  2. POSTโ†’ GET

    1. ํŠน์ • ์‹œ๊ฐ„์— ์˜ˆ์•ฝํ•œ๋‹ค๋Š” ๊ฒƒ์€ GET ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ์ด๋•Œ GET ๋ฉ”์„œ๋“œ๋Š” body๋ฅผ ๊ฐ€์ง€์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— query parameter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ „๋‹ฌ
  3. POST์™€ PUT์€ ๊ตฌ๋ถ„ํ•ด์„œ ์‚ฌ์šฉ

    1. POST๋Š” ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑ
    2. PUT์€ ์š”์ฒญ๋งˆ๋‹ค ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋ฅผ ๋ฐ˜ํ™˜ = ๋ฉฑ๋“ฑ์„ฑ.
  4. PUT๊ณผ PATCH ๋„ ๊ตฌ๋ถ„ํ•˜์—ฌ ์‚ฌ์šฉ

    1. PUT์€ ๊ต์ฒด, PATCH๋Š” ์ˆ˜์ •์˜ ์šฉ๋„๋กœ ์‚ฌ์šฉ
  5. 201 Created๋กœ ๋ช…ํ™•ํ•˜๊ฒŒ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋ฉฐ, ๊ด€๋ จ ๋ฆฌ์†Œ์Šค๋ฅผ ํด๋ผ์ด์–ธํŠธ๊ฐ€ Location ํ—ค๋”์— ์ž‘์„ฑ๋œ URI๋ฅผ ํ†ตํ•ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก. ๊ทผ๋ฐ ์‹ค์ œ๋กœ ์‚ฌ์šฉ ์ž˜ ์•ˆํ•จ

  6. ๋ฐ์ดํ„ฐ ์กฐํšŒํ•˜๊ณ  (GET) ์žฌ์กฐํšŒ ํ•  ๊ฒฝ์šฐ ๋ฉฑ๋“ฑ์„ฑ์„ ํ—ค์น˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊น€

3๋‹จ๊ณ„

  1. HATEOAS(Hypertext As The Engine Of Application State)๋ผ๋Š”ย ์•ฝ์–ด๋กœ ํ‘œํ˜„๋˜๋Š” ํ•˜์ดํผ๋ฏธ๋””์–ด ์ปจํŠธ๋กค์„ ์ ์šฉ

  2. ์‘๋‹ต์—๋Š” ๋ฆฌ์†Œ์Šค์˜ URI๋ฅผ ํฌํ•จํ•œ ๋งํฌ ์š”์†Œ๋ฅผ ์‚ฝ์ž…ํ•˜์—ฌ ์ž‘์„ฑํ•œ๋‹ค

    1. ์‘๋‹ตย ๋‚ด์—ย ์ƒˆ๋กœ์šดย ๋งํฌ๋ฅผย ๋„ฃ์–ดย ์ƒˆ๋กœ์šดย ๊ธฐ๋Šฅ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด 3๋‹จ๊ณ„์˜ ์ค‘์š” ํฌ์ธํŠธ

์ˆ˜์ •์ด ์•„๋‹Œ ์• ๋ฉ”ํ•œ ๊ฒƒ์€ POST ์‚ฌ์šฉํ•˜๊ธฐ. +์ฝ”๋“œ ์ž˜์จ์•ผ ํ•จ

Open API์™€ API Key

  1. Open API
    1. ์ •๋ถ€์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ณต๊ณต๋ฐ์ดํ„ฐ : ๊ณต๊ณต๋ฐ์ดํ„ฐ ํฌํ„ธ
    2. Open Weather Map : ์›น ์‚ฌ์ดํŠธ์—์„œ ์ œ๊ณตํ•˜๋Š” ๋‚ ์”จ API
      • ๋ฐ์ดํ„ฐ๋ฅผ JSON ํ˜•ํƒœ๋กœ ์‘๋‹ต
  2. API Key
    1. API key๋Š” ์„œ๋ฒ„์˜ ๋ฌธ์„ ์—ฌ๋Š” ์—ด์‡ 
    2. ํด๋ผ์ด์–ธํŠธ์˜ ์š”์ฒญ์— ๋”ฐ๋ผ ์„œ๋ฒ„์—์„œ ์‘๋‹ตํ•œ๋‹ค๋Š” ๋ง์€ ๊ฒฐ๊ตญ ์„œ๋ฒ„๋ฅผ ์šด์šฉํ•˜๋Š” ๋ฐ์— ๋น„์šฉ์ด ๋ฐœ์ƒ
    3. ๊ทธ๋ž˜์„œ ๋กœ๊ทธ์ธ๋œ ์ด์šฉ์ž์—๊ฒŒ๋งŒ ์ž์›์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ API Key์˜ ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญํ•  ๋•Œ API key๋ฅผ ๊ฐ™์ด ์ „๋‹ฌํ•ด์•ผ๋งŒ ์›ํ•˜๋Š” ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜ ์žˆ์Œ.

REST API ์‹ค์Šต

API ์„ค๊ณ„

  • ์ด๋ฆ„์€ ๋™์‚ฌ ์‚ฌ์šฉ ์•ˆ๋จ, endpoint์˜ ๊ธฐ๋ณธ์€ ๋ณต์ˆ˜ํ˜•์ž„.
  • ๋Œ€๋ฌธ์ž์™€ ๋Œ€์‰ฌ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ.
  • ์‚ฌ์šฉ์ž๊ฐ€ ๊ธฐ๋ณธํ‚ค ์•Œ ์ˆ˜ ์—†์Œ - ๊ธฐ๋ณธํ‚ค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์„ค์ •ํ•˜๊ฒŒ ํ•จ.
  • ๊ธฐ์กด ์„œ๋น„์Šค์—์„œ ์–ด๋–ป๊ฒŒ ์‹๋ณ„ํ•˜๋Š”์ง€ ์ž์ฃผ ๋ณด๊ธฐ

โœ”๏ธ ์‹ค์Šต

  1. ๋„์„œ ์ถ”๊ฐ€ (Create a Book)

    POST/books

    {โ€nameโ€ : โ€œsleepโ€,

    โ€œregisterdateโ€ : โ€œ2024-05-31โ€,
    โ€œauthorโ€ : โ€œjerryโ€}

  2. ๋„์„œ ๋ชฉ๋ก ์กฐํšŒ (Get All Books)

    GET/books

  3. ํŠน์ • ๋„์„œ ์กฐํšŒ (Get a Single Book)

    GET/books/id

    ๊ธฐ๋ณธ ํ‚ค๋กœ ์กฐํšŒํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ id๊ฐ€ ์•„๋‹Œ ์ฐพ๊ณ ์ž ํ•˜๋Š” ์ด๋ฆ„์ด๋‚˜ ์ €์ž ๋“ฑ์œผ๋กœ ์กฐํšŒํ•ด์•ผ ํ•จ.

  4. ๋„์„œ ์ •๋ณด ์ˆ˜์ • (Update a Book)

    PATCH/books

  5. ๋„์„œ ์‚ญ์ œ (Delete a Book)

    Delete/books/id

  6. ๋„์„œ ๋Œ€์ถœ (Borrow a Book)

    GET/books/name=sleepy?

    POST/loanbooks/book/id

    ๋‚ด ์ƒ๊ฐ์—๋Š” ์กฐํšŒ๋ฅผ ํ•˜๊ณ  ๋Œ€์ถœ ๋ชฉ๋ก์„ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Œ
    ํ•˜์ง€๋งŒ ๋ฐ”๋กœ ๋Œ€์ถœ๋ชฉ๋ก์—์„œ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆ
    POST โ†’ /loanrecords
    {
    โ€œbookIdโ€: 3,
    โ€œuserIdโ€: 11,
    โ€œloanDateโ€ โ€œ2024-05-30โ€

  7. ๋„์„œ ๋ฐ˜๋‚ฉ (Return a Book)

    GET/loanbooks/id

    POST/loanbooks/id

    ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ฑ… ๋ฐ”์ฝ”๋“œ๋กœ ์กฐํšŒ ํ›„ ๋Œ€์ถœ ๋ชฉ๋ก์ด ์ผ๋ถ€๋ถ„ ์ˆ˜์ •๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•จ.
    ๊ทธ๋Ÿฌ๋‚˜ ๋Œ€์ถœ๋ชฉ๋ก๋งŒ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ์ ์ ˆ
    ex) PATCH โ†’ /loanrecords/3
    res ->
    {
    โ€œloanIdโ€: 3,
    โ€œuserIdโ€: 2,
    โ€œbookIdโ€: 7,~~~
    }

  8. ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ (Get Loan Records)

    Get/loanbooks/username=โ€™jerryโ€™

    userId โ†’ GET /loanrecoreds?userId={id} โ†’ ํŠน์ • ์œ ์ €์˜ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ
    bookId โ†’ GET /loanrecoreds?bookId ={id} โ†’ ํŠน์ • ๋„์„œ์˜ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ
    loanDate โ†’ GET /loanrecoreds?loanDate ={id} โ†’ ํŠน์ • ๋Œ€์ถœ์ผ ๊ธฐ์ค€ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ
    returnDate โ†’ GET /loanrecoreds?returnDate ={id} โ†’ ํŠน์ • ๋ฐ˜๋‚ฉ์ผ ๊ธฐ์ค€ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ
    isReturned โ†’ GET /loanrecoreds?isReturned={id} โ†’ ๋ฐ˜๋‚ฉ์—ฌ๋ถ€ ๊ธฐ์ค€ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ
    ex)
    GET โ†’ /loanrecords?userId=3?bookId=7 โ†’ 3๋ฒˆ ์œ ์ €๊ฐ€ 7๋ฒˆ ์ฑ…์„ ๋นŒ๋ฆฐ ๋Œ€์ถœ ๊ธฐ๋ก ์กฐํšŒ

Comment

  • ๋ฐฐ์šด๋‚ด์šฉ : CORS, HTTP, REST API, REST API ์‹ค์Šต
  • CORS๋Š” ์ฒ˜์Œ์— ์–ด๋ ค์›Œ์„œ ์ดํ•ดํ•˜๋Š”๋ฐ ์˜ค๋ž˜๊ฑธ๋ฆผ, ๋” ๋” ๋” ๋งŽ์ด ๋ด์•ผํ•  ๊ฒƒ ๊ฐ™์Œ.
  • ๐Ÿ’ Network ๋ถ€๋ถ„์€ ๋‹จ์ˆœํžˆ ์ดํ•ดํ•˜๊ณ  ๋„˜์–ด๊ฐ€๊ธฐ์—๋Š” ๋‚˜์ค‘์— ๋งž๋‹ฅ๋œจ๋ ธ์„ ๋•Œ ์–ด์–ด์–ด ์ด๊ฒŒ๋ญ์•ผ ํ•  ๊ฒƒ ๊ฐ™์€ ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
    ํŠนํžˆ CORS ๋ถ€๋ถ„, ์ˆ˜์—…๋“ค์„ ๋•Œ ์•„~~ ํ•˜๊ณ  ๋ณ„๊ฑฐ์•„๋‹ˆ๋„ค ํ–ˆ๋Š”๋ฐ ๋‹ค์‹œ ๋ณต์Šตํ•˜๋Š”๋ฐ ์™œ ์ฒ˜์Œ๋ณด๋Š” ๊ฒƒ ๊ฐ™์ง€ ์ด๊ฑฐ..? ๋ฐฐ์› ์—ˆ๋‚˜ ์‹ถ์—ˆ๋‹ค.
    ์‚ฌ์‹ค simple๊ณผ Preflight์˜ ์ฐจ์ด์™€ ์ด๋Ÿฐ์‹์œผ๋กœ๋งŒ ์ดํ•ดํ–ˆ๊ณ  ๊นŠ๊ฒŒ๋Š” ์ดํ•ดํ•˜์ง€ ๋ชปํ–ˆ๋˜ ๊ฒƒ์ด์—ˆ๋‹ค.
    ์ง€๊ธˆ ๊นŠ๊ฒŒ๋ณด๊ธฐ ๋ณด๋‹ค ๋‚˜์ค‘์— ํ”„๋กœ์ ํŠธํ•  ๋•Œ ์˜ค๋ฅ˜๋‚˜๋ฉด ๊ทธ ๋•Œ ๋‹ค์‹œ ๋Œ์•„์™€์„œ ๋ณด๋ผ๊ณ  ํ•˜์…จ๋Š”๋ฐ
    ํŒŒ์›Œ ์ œ์ด์ธ ๋‚˜๋Š” ๊ทธ๋Ÿฐ ๋‹นํ™ฉ์Šค๋Ÿฌ์šด ์ƒํ™ฉ์ด ์ƒ๊ธฐ๊ธฐ ์ „์— ์–ด์„œ ๋ณต์Šต ๋งŽ์ด ํ•ด์•ผ๊ฒ ๋‹คโ€ฆ!

Network ์นดํ…Œ๊ณ ๋ฆฌ ๋‚ด ๋‹ค๋ฅธ ๊ธ€ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ

Leave a comment