테마
마이크로프론트엔드를 위한 API 서버 구축
커리어 플랫폼의 마이크로앱들이 사용할 Mock API 서버를 json-server 기반으로 구축하고, CORS 및 인증 미들웨어를 설정한다.
학습 목표
- json-server를 활용한 Mock REST API 서버 구축 방법을 이해한다
- 마이크로앱별 API 엔드포인트를 체계적으로 설계할 수 있다
- CORS 설정과 인증 미들웨어를 통한 API 보안 기초를 익힌다
- Auth0 토큰을 활용한 API 인증 흐름을 구현할 수 있다
1. Mock API 서버의 역할과 아키텍처
마이크로프론트엔드에서 각 마이크로앱은 독립적으로 데이터를 관리하지만, 개발 단계에서는 통합된 Mock API 서버를 활용하면 빠르게 프로토타이핑할 수 있다. 커리어업 프로젝트에서는 json-server를 사용하여 REST API를 빠르게 구축한다.
2. 모노레포 워크스페이스에 서버 패키지 추가
json-server는 모노레포의 독립 워크스페이스로 설정한다. 별도의 빌드 과정 없이 Node.js로 직접 실행하는 방식이다.
yaml
# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
- "server" # API 서버 워크스페이스
- "fragments/*"json
// server/package.json
{
"name": "@career-up/server",
"version": "1.0.0",
"private": true,
"scripts": {
"start": "node index.js"
},
"dependencies": {
"json-server": "0.17.4"
}
}json-server 0.17.4(Stable)을 사용하는 이유: 최신 알파 버전은 API가 크게 변경되어 기존 문서와 호환되지 않는다. Stable 버전을 명시적으로 지정하여 안정적으로 사용한다.
3. db.json 데이터 설계
모든 마이크로앱이 사용할 데이터를 하나의 db.json 파일에 정의한다. json-server는 이 파일의 최상위 키를 REST 엔드포인트로 자동 매핑한다.
json
// server/db.json (구조 예시)
{
"posts": [
{
"id": 1,
"message": "마이크로프론트엔드 학습을 시작합니다.",
"createdAt": "2024-01-15T09:00:00.000Z",
"author": {
"name": "홍길동",
"email": "hong@example.com",
"picture": "https://example.com/avatar.png"
}
}
],
"courses": [
{
"id": 1,
"thumbnail": "/images/react-course.png",
"title": "React 심화",
"description": "React 고급 패턴을 학습합니다."
}
],
"courseContents": [
{
"id": 1,
"goals": ["컴포넌트 설계 패턴 이해", "성능 최적화 기법 습득"],
"summaries": ["HOC와 Render Props", "React.memo와 useMemo"]
}
],
"jobs": [
{
"id": 1,
"company": "테크 스타트업",
"position": "프론트엔드 개발자",
"location": "서울 강남구"
}
],
"connections": [
{
"id": 1,
"name": "김개발",
"picture": "https://example.com/dev.png",
"role": "백엔드 개발자",
"networkCount": 150
}
]
}json-server 자동 매핑 규칙:
| HTTP 메서드 | 경로 | 동작 |
|---|---|---|
GET | /posts | 전체 포스트 조회 |
GET | /posts/1 | id=1 포스트 조회 |
POST | /posts | 포스트 생성 |
PUT | /posts/1 | 포스트 전체 수정 |
PATCH | /posts/1 | 포스트 부분 수정 |
DELETE | /posts/1 | 포스트 삭제 |
GET | /posts?_sort=id&_order=desc | 정렬된 목록 조회 |
4. 서버 코드 작성과 CORS 설정
json-server의 기본 미들웨어(jsonServer.defaults())에 CORS 자유 설정이 포함되어 있다. 추가로 커스텀 인증 미들웨어를 등록한다.
javascript
// server/index.js
const jsonServer = require("json-server");
const server = jsonServer.create();
const router = jsonServer.router("db.json");
const middlewares = jsonServer.defaults();
const AUTH0_DOMAIN = "https://your-domain.auth0.com";
// 1) 기본 미들웨어: CORS, 정적 파일, 로깅
server.use(middlewares);
// 2) JSON body 파싱
server.use(jsonServer.bodyParser);
// 3) 인증 미들웨어
server.use(async (req, res, next) => {
const authorized = await isAuthenticated(req);
if (authorized) {
next();
} else {
res.sendStatus(401);
}
});
// 4) 커스텀 엔드포인트: 유저 정보
server.get("/user", (req, res) => {
res.jsonp({
...req.user,
viewCount: 249,
updateCount: 100,
courses: [
{ courseId: 1, done: true },
{ courseId: 4, done: false }
]
});
});
// 5) POST 요청 시 author 정보 자동 추가
server.post("/posts", (req, res, next) => {
req.body.createdAt = new Date().toISOString();
req.body.author = {
name: req.user.name,
email: req.user.email,
picture: req.user.picture
};
next();
});
// 6) db.json 라우터 등록
server.use(router);
// 7) 서버 시작
server.listen(4000, () => {
console.log("JSON Server is running on port 4000");
});
// Auth0 토큰 검증 함수
async function isAuthenticated(req) {
try {
const authorization = req.headers.authorization;
const response = await fetch(`${AUTH0_DOMAIN}/userinfo`, {
headers: { authorization }
});
const json = await response.json();
req.user = json;
return true;
} catch (e) {
return false;
}
}5. CORS 상세 설정
jsonServer.defaults()는 기본적으로 모든 출처(origin)의 요청을 허용한다. 프로덕션에서는 반드시 허용 출처를 제한해야 한다.
javascript
// 개발 환경 기본 CORS (json-server defaults에 포함)
// Access-Control-Allow-Origin: *
// Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE, OPTIONS
// Access-Control-Allow-Headers: Content-Type, Authorization
// 프로덕션 환경에서의 CORS 제한 예시
const corsOptions = {
origin: [
"http://localhost:3000", // Shell
"http://localhost:3001", // Posting
"http://localhost:3002", // Edu
"http://localhost:3003", // Network
"http://localhost:3004" // Job
],
credentials: true
};마이크로앱별 포트 매핑:
| 서비스 | 포트 | 역할 |
|---|---|---|
| Shell (Host) | 3000 | 전체 라우팅, 인증 관리 |
| Posting (Remote) | 3001 | 포스팅 CRUD |
| Education (Remote) | 3002 | 교육 콘텐츠 |
| Network (Remote) | 3003 | 인맥 관리 |
| Job (Remote) | 3004 | 채용 공고 |
| API Server | 4000 | Mock REST API |
6. API 엔드포인트 종합 설계
각 마이크로앱이 사용하는 엔드포인트를 정리한다.
| 마이크로앱 | 엔드포인트 | 메서드 | 설명 |
|---|---|---|---|
| 공통 | /user | GET | 현재 로그인 유저 정보 (커스텀) |
| Posting | /posts?_sort=id&_order=desc | GET | 포스트 목록 (최신순) |
| Posting | /posts | POST | 포스트 작성 |
| Posting | /posts/:id | DELETE | 포스트 삭제 |
| Education | /courses | GET | 교육 코스 목록 |
| Education | /courseContents/:id | GET | 코스 상세 내용 |
| Network | /myNetwork | GET | 내 네트워크 통계 (커스텀) |
| Network | /connections | GET | 인맥 목록 |
| Job | /jobs | GET | 채용 공고 목록 |
| Job | /applyStatus | GET | 지원 현황 (커스텀) |
핵심 정리
- json-server는 db.json 파일의 최상위 키를 REST 엔드포인트로 자동 매핑하여 빠르게 Mock API를 구축할 수 있다
jsonServer.defaults()미들웨어에 CORS 허용, 정적 파일 서비스, 요청 로깅이 포함되어 있다- 인증 미들웨어는
Authorization헤더의 Bearer 토큰을 Auth0/userinfo엔드포인트로 검증한다 server.get(),server.post()등으로 json-server 기본 라우팅 외에 커스텀 엔드포인트를 추가할 수 있다- POST 요청 시
next()를 호출하기 전에req.body를 수정하면 db.json에 수정된 데이터가 저장된다 - 프로덕션에서는 CORS 허용 출처를 반드시 제한하고, 실제 인증 서버를 사용해야 한다
다음 단계
- 02-포스팅-서비스.md: CSS Modules로 스타일링하고 포스팅 CRUD 기능을 구현하며, Module Federation으로 Remote 설정을 완성한다