[FastAPI] 10. Middleware๋ฅผ ์ด์šฉํ•œ ์ „ํ›„ ์ฒ˜๋ฆฌ

๋ฐ˜์‘ํ˜•

API๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์ด ์–ด๋Š ์ •๋„ ์†Œ๋ชจ๋˜๋Š”์ง€ ๊ถ๊ธˆํ•˜๋‹ค๊ฑฐ๋‚˜ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ์„ ๋ฐ›์•˜์„ ๋•Œ ๋ฐ›์€ EndPoint์™€ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ์š”?

 

 

 

Middleware

Spring์—์„œ๋Š” Intercepter, Filter์™€ ๊ฐ™์€ ์ค‘๊ฐ„ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค๋ฉด, Flask์—์„œ๋Š” App Context ์ค‘ after_request๋‚˜ before_request ๋“ฑ์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋“ฑ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

 

FastAPI์—๋Š” Middleware ํŒจํ„ด์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Middleware ํŒจํ„ด์€ API ํ˜ธ์ถœ ์ „ํ›„๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ํ•˜๋‚˜์˜ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ  ๋‚œ ๋’ค, API Router๋กœ ์š”์ฒญ์„ ๋„˜๊ธฐ๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

 

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด ์ด ์š”์ฒญ์€ ๋จผ์ € Middleware์—์„œ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  Middleware๋Š” ๋‹ค์‹œ ์ด๋ฅผ API Router๋กœ ๋„˜๊ธฐ๊ฒŒ ๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

 

 

 

BaseHTTPMiddleware

FastAPI์—์„œ ์ œ๊ณตํ•˜๋Š” Middleware ํŒจํ„ด์€ BaseHTTPMiddleware๋ฅผ ์ƒ์†ํ•œ ํด๋ž˜์Šค๋“ค๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋Š” ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ์š”์ฒญ์ด ์˜ค๋ฉด ๊ทธ ์š”์ฒญ์„ ๋ฐ›์€ ๋’ค dispatch ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ์šฐ๋ฆฌ๋Š” ์ด dispatch ํ•จ์ˆ˜์—์„œ ์ค‘๊ฐ„ ์ฒ˜๋ฆฌ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

dispatch ํ•จ์ˆ˜์—์„œ๋Š” BaseHTTPMiddleware๊ฐ€ ํด๋ผ์ด์–ธํŠธ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ ์š”์ฒญ๊ณผ EndPoint ํ•จ์ˆ˜๋ฅผ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ œ๊ณตํ•˜์—ฌ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

 

์ด๋ฅผ ํ™œ์šฉํ•ด์„œ API ์š”์ฒญ์‹œ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ Header์— ํฌํ•จํ•ด์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๋ฏธ๋“ค์›จ์–ด๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

Python์—์„œ ์ œ๊ณตํ•˜๋Š” time ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ฏธ๋“ค์›จ์–ด๋กœ๋ถ€ํ„ฐ ์š”์ฒญ๊ฐ’์„ ๋ฐ›์•„์˜จ ์‹œ๊ฐ„์„ start_time์œผ๋กœ ์ง€์ •ํ•ด์ค๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  call_next๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ EndPoint ์ง€์ ์œผ๋กœ ์š”์ฒญ๊ฐ’์„ ๋„˜๊ฒจ์ค๋‹ˆ๋‹ค.

 

๋งˆ์ง€๋ง‰์œผ๋กœ time ํ•จ์ˆ˜๋ฅผ ํ•œ ๋ฒˆ ๋” ํ˜ธ์ถœํ•œ ๋‹ค์Œ start_time์— ์ง€์ •๋œ ์‹œ๊ฐ„์„ ๋นผ์ฃผ๋ฉด ์ด API๊ฐ€ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์ด ๋‚˜์˜ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ call_next์—์„œ ๋ฐ˜ํ™˜ ๋ฐ›์€ response์˜ header ๊ฐ’์— ๋„ฃ์–ด์ฃผ๋ฉด ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ์ด ๊ฐ’๊ณผ ํ•จ๊ป˜ ์ „์†ก๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

 

 

 

RequireJSON

ํด๋ผ์ด์–ธํŠธ๊ฐ€ PUT, PATCH, POST ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ–ˆ์„ ๋•Œ JSON ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋งŒ์„ ๋ฐ›๋„๋ก ํ•  ๋•Œ๋„ ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ด์šฉํ•œ๋‹ค๋ฉด ๊ฐ„๋‹จํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

request์˜ ์ •๋ณด ์ค‘์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์š”์ฒญํ•œ ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ ธ์™€ ๋ฉ”์†Œ๋“œ๋ฅผ ํ™•์ธํ•˜๊ณ , Header์˜ content-type์ด application/json์ธ์ง€ ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค. ๋งŒ์•ฝ application/json์ด ์•„๋‹ˆ๋ผ๋ฉด 415 ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์ฃผ๊ณ , ๋งž๋‹ค๋ฉด ์š”์ฒญ์„ EndPoint์— ๋„˜๊ฒจ์ฃผ๋ฉด ๊ฐ„๋‹จํžˆ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

 

 

๋งˆ์น˜๋ฉฐ...

FastAPI์—์„œ๋„ Falcon, Nest.js์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Middleware๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ „ํ›„์ฒ˜๋ฆฌ๋ฅผ ์ด์šฉํ•˜๋ฉฐ ์ด๋Š” ์•„์ฃผ ์ ‘๊ทผ์„ฑ์ด ์šฉ์ดํ•˜์—ฌ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์ด ์žฅ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

 

ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ฏธ๋“ค์›จ์–ด์—์„œ๋„ ์ง€์›์ด ๋ฏธํกํ•œ ๋ถ€๋ถ„์ด ์žˆ๋Š”๋ฐ, ์ด ์ด์Šˆ๋Š” ๋‹ค์Œ ๊ธ€์—์„œ ๋‹ค๋ค„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

 

P.S: ํ•œ๋™์•ˆ ๋ธ”๋กœ๊ทธ ๋‚ด์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒจ ํฌ์ŠคํŒ…์„ ์ž ์ • ์ค‘๋‹จํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค. 2์ฐจ ๋„๋ฉ”์ธ๊ณผ ๊ตฌ๊ธ€ ํฌ๋กฌ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฌธ์ œ์ ์ด ์ ์  ์•…ํ™”๋˜๋ฉด์„œ 2์ฐจ ๋„๋ฉ”์ธ (https://blog.neonkid.xyz)๋ฅผ ์ž ์ • ํ์‡„ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ œ ๋ธ”๋กœ๊ทธ๋ฅผ ๊ตฌ๋…ํ•ด์ฃผ์‹œ๋Š” ๋ถ„๋“ค์ด๋ผ๋ฉด 1์ฐจ ๋„๋ฉ”์ธ (https://byneonkid.tistory.com)์„ ์ด์šฉํ•ด์ฃผ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•
TAGS.

Tistory Comments