[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)์ ์ด์ฉํด์ฃผ๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.