π API Routes λ?
API Routes μ λ±μ₯ λ°°κ²½
React
μ ν리μΌμ΄μ
μ κ°λ°νλ€λ³΄λ©΄ backend API
κ° νμν μμ μ΄ μ€κ²λ©λλ€.
μλ₯Ό λ€μ΄ DB μ λ°μ΄ν°λ₯Ό μ‘°ννκ±°λ μ¬μ©μκ° μμ²ν λ°μ΄ν°λ₯Ό μ²λ¦¬νλ λ±μ μμ μ΄ μμ΅λλ€.
μ΄λ₯Ό μν΄ μ΄μ μλ Node.js
λ±μ νμ©ν custom server
νμ΄νλΌμΈμ ꡬμΆν΄μ
ν΄λΉ μμ
μ μμνλ λ°©μμ μ¬μ©νμ§λ§, μ΄ κ²½μ° Next.js
μ μ±λ₯ μ΅μ ν μ΄μ μ μκ² λλ λ¬Έμ μ
TypeScript
λ° ES6 λ°©μμ λͺ¨λ μμ€ν
μ μ¬μ©νμ§ λͺ»νλ λ¬Έμ κ° μμμ΅λλ€.
μ΄λ¬ν λ¬Έμ λ₯Ό ν΄κ²°νλ©° κ°λ°μ κ²½νμ ν₯μμν€κΈ° μν΄μ Next.js
λ Next 9
λ²μ λΆν°
API Routes
λΌλ κΈ°λ₯μ μ§μνκΈ° μμνμ΅λλ€.
μ΄λ₯Ό ν΅ν΄ Next.js
μμμ νμν serverless API Endpoint
λ₯Ό ꡬμΆν μ μκ² λμμ΅λλ€.
API Routes λ₯Ό νμ©ν REST API μμ
Next.js
λ Express
μ κ°μ Node.js
μλ²μ¬μ΄λ νλ μμν¬μ²λΌ
Node.js
μ μμ² λ° μλ΅κ°μ²΄λ₯Ό μ§μ μ κ·Όνμ§ μκ³ NextApiRequest
μ κ°μ΄
λνλ κ°μ²΄λ₯Ό μμ½κ² λ€λ£° μ μλ μΈν°νμ΄μ€λ₯Ό μ 곡ν©λλ€.
μ΄λ₯Ό ν΅ν΄ λΆνμν νμ± μ½λλ₯Ό μ€μ΄κ³ μνλ λΉμ¦λμ€ λ‘μ§ κ΅¬νμ μ§μ€ν μ μκ² λ©λλ€.
API Routes
λ pages/api
λλ ν 리 λ΄μ μ μνλ©° νμΌ μμ€ν
μ κΈ°λ°μΌλ‘ μ£Όμκ° κ²°μ λ©λλ€.
μ¬κΈ°μλ λκΈμ μ‘°ννλ κ°λ¨ν API μμλ₯Ό ν΅ν΄ μ¬μ© λ°©λ²μ μμλ³΄κ² μ΅λλ€.
νΈλ€λ¬λ μμ²(req) κ³Ό μλ΅(res) κ°μ²΄λ₯Ό μΈμλ‘ μ λ¬λ°μ΅λλ€.
// pages/api/comments
const comments = [
{ id: 1, text: 'comment 1' },
{ id: 2, text: 'comment 2' },
{ id: 3, text: 'comment 3' },
]
export default function handler(req, res) {
res.status(200).json(comments)
}
μ΄μ μμμ μ μν endpoint
λ‘ fetch
λ₯Ό ν΅ν΄ λ°μ΄ν°λ₯Ό μμ²ν©λλ€.
// Comments.tsx
export default function Comments() {
const fetchComments = async () => {
const response = await fetch('/api/comments')
if (response.ok) {
const comments = await response.json()
}
}
}
π API Routes μ μ μ© μ¬λ‘
API Proxy
API Routes
λ₯Ό μ΄μ©νλ©΄ μ€μ μΈλΆ API νΈμΆμ μ μμ² λ° μλ΅ κ°μ²΄μ μ κ·Όνμ¬
Authorization
, CORS
λ± μ¬λ¬ λͺ©μ μ μν νλ‘μ μν μ μνν μ μμ΅λλ€.
1οΈβ£ μ ν¨μ± κ²μ¬
λ€μμ HTTP Request μμ Authorization
ν€λλ₯Ό κ²μ¬ν΄
API μμ² μ‘°κ±΄μ λ§μ‘±νλμ§ νλ¨νλ κ°λ¨ν μμ μ½λμ λλ€.
import { NextApiRequest, NextApiResponse } from 'next'
export async function handler(req: NextApiRequest, res: NextApiResponse) {
const role = req.headers.get('authorization')
if (['user', 'admin'].includes(role)) {
return res.status(401).send('unauthorized')
}
// ...
}
2οΈβ£ μΈλΆ API μ£Όμ λ§μ€νΉ
λν API Routes
λ₯Ό μ΄μ©ν΄ νλ‘μ νΈμμ μ¬μ©νλ μΈλΆ API λ₯Ό μλν ν μ μμ΅λλ€.
λ§μ½ μ€μ μΈλΆ API μ£Όμκ° https://external-api.hub/comment
λΌλ©΄,
/api/external
μ΄λΌλ μμ²μΌλ‘ μ€μ μμ² μ£Όμλ₯Ό μ¨κΈΈ μ μμ΅λλ€.
// pages/api/external
import { NextApiRequest, NextApiResponse } from 'next'
const API_BASE_URL = process.env.API_BASE_URL
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
// ...
const requestUrl = `${API_BASE_URL}/${req.path}`
const response = await fetch(requestUrl)
}
π API Routes μ μμ¬ν
Live Connection μ΄ νμν κ²½μ° λΆμ ν©νλ€
Next.js
μμ μ 곡νλ API Routes
λ serverless function
μ΄κΈ° λλ¬Έμ
stateless
νμ¬ μ§μμ μΈ DB 컀λ₯μ
μ μ μ§νκ±°λ web socket
λ±μ μ΄μ©ν μ€μκ° ν΅μ λ±μ
live connection
μ΄ νμν κ²½μ°μλ μ ν©νμ§ μμ μ μμ΅λλ€.
μ€λ³΅λ API fetch μ‘°μ¬νκΈ°
API Routes
λ₯Ό getServerSideProps
λ getStaticProps
λ±μμ μ¬μ©νλ©΄
λΆνμνκ² API λ₯Ό λλ² νΈμΆνλ λ¬Έμ κ° λ°μν μ μμ΅λλ€.
/**
* lib/load-posts.js
*
* loadPosts λ lib/* μ κ°μ λλ ν 리μμ κ³΅ν΅ ν¨μλ‘ κ΄λ¦¬νλ©΄
* getStaticPropsμ API routesμμ λͺ¨λ μ κ·Όν μ μμ΅λλ€.
*/
export async function loadPosts() {
const res = await fetch('https://.../posts/')
const data = await res.json()
return data
}
/**
* api/post
*/
import { loadPosts } from '@lib/load-posts'
export default async function handler(req, res) {
// ...
const posts = await loadPosts()
res.status(200).json(posts)
}
/**
* pages/blog.js
*/
import { loadPosts } from '@lib/load-posts'
export async function getStaticProps() {
/**
* API Routes λ₯Ό μ¬μ©νλ λμ μ API λ₯Ό μ§μ μ‘°ννλ ν¨μλ₯Ό νΈμΆν΄μ
* λΆνμν API μ€λ³΅ νΈμΆμ λ°©μ§ν©λλ€.
*/
const posts = await loadPosts()
return { props: { posts } }
}
π Edge API Routes (π§ͺ experimental)
Edge API Routes
λ Next v12
μμ μΆκ°λ κΈ°λ₯μΌλ‘μ
κΈ°μ‘΄μ Node.js
κΈ°λ°μ λ°νμλ³΄λ€ κ°λ³κ³ λΉ λ₯Έ νκ²½μ μ 곡ν©λλ€.
νμ¬λ λ² ν λ²μ μΌλ‘ λ€μκ³Ό κ°μ΄ edge runtime
μ νμ±ν μν€κ³ μΆμ λΌμ°νΈμμ
runtime config
λ₯Ό export
νλ©΄ μ€μ ν μ μμ΅λλ€.
import type { NextRequest } from 'next/server';
export default (req: NextRequest) => {
return new Response(`Hello, from ${req.url} I'm now an Edge API Route!`);
};
export const config = {
runtime: 'experimental-edge',
};
Edge API Routes
λ νμ€ WEB API λ₯Ό κΈ°λ°μΌλ‘ λ§λ€μ΄μ‘κΈ° λλ¬Έμ μ¬μ© μ λͺκ°μ§ μ μ½μ¬ν μ΄ μμ΅λλ€.
λμ stream response
λ₯Ό ν΅ν΄ λ³΄λ€ λΉ λ₯Έ TTFB(Time To First Byte)
λ‘
μ±λ₯ν₯μμ κΎν μ μλ€λ μ₯μ μ΄ μμ΅λλ€.
π μ°Έκ³ μλ£
'π¨βπ» web.dev > fe' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
React μ΄λ²€νΈ μ²λ¦¬λ°©μκ³Ό SyntheticEvent (0) | 2022.10.17 |
---|---|
File API λ₯Ό μ΄μ©ν Input μ»΄ν¬λνΈ λ§λ€κΈ° (2) | 2022.08.13 |
React μ»΄ν¬λνΈ(children) νμ΄ννκΈ° (0) | 2022.07.23 |
React μ€λλ ν΄λ‘μ (Stale Closure) μ΄μ ν΄κ²°νκΈ° (0) | 2022.05.11 |
React μ μ΄ μ»΄ν¬λνΈ vs λΉμ μ΄ μ»΄ν¬λνΈ (0) | 2022.04.10 |
π¬ λκΈ