React로 멀티 테넌시 UI 설계와 구현
React 기반 애플리케이션에서 테넌트별 UI 커스터마이징과 분리를 위한 설계 관점과 예제 코드 설명
목차
개요
멀티 테넌시 환경에서는 서로 다른 고객(테넌트)이 동일한 코드베이스를 사용하지만 UI와 설정은 달라야 한다. 이 글은 React 애플리케이션에서 테넌트별 UI 커스터마이징을 어떻게 설계하고 구현할지 단계별로 설명한다. 처음 접하는 개발자도 이해하기 쉽도록 핵심 개념과 예제를 중심으로 정리한다.
핵심 개념
테넌트 분리와 범위
테넌트 분리는 크게 데이터, 인증, UI 커스터마이징으로 나눌 수 있다. 이 글은 UI 커스터마이징에 집중한다. UI 커스터마이징은 색상, 로고, 레이아웃, 권한 기반 메뉴 등으로 구성된다.
설계 원칙
- 단일 책임: 테넌트별 설정을 관리하는 영역을 분리
- 확장성: 새로운 테넌트가 추가되어도 코드 변경 최소화
- 퍼포먼스: 런타임에 불필요한 렌더링을 줄임
- 보안: 테넌트 간 설정 누출 방지
아키텍처 패턴
1. 설정 주입(Provider) 패턴
앱 초기화 시 백엔드 또는 환경에서 테넌트 설정을 받아 Context나 전역 상태에 주입한다. 컴포넌트는 이 설정을 읽어 스타일과 콘텐츠를 렌더링한다.
2. 테마 매핑
테넌트별 색상, 폰트, 스페이싱 등의 값을 테마 객체로 관리한다. 스타일 컴포넌트 또는 CSS 변수로 주입하면 런타임 교체가 용이하다.
3. 컴포넌트 레벨 커스터마이징
공통 컴포넌트는 슬롯(slot)이나 렌더 프롭을 제공해 테넌트 특화 UI를 삽입할 수 있게 설계한다. 이렇게 하면 코드 중복을 줄이면서도 유연성을 확보한다.
구현 예제
아래 예제는 간단한 테넌트 설정 프로바이더와 테마 적용 방법을 보여준다. JSX의 불러오기와 렌더링 부분은 <pre><code> 블록으로 제공한다.
TenantContext와 Provider
import React, { createContext, useContext, useState, useEffect } from 'react'
const TenantContext = createContext(null)
export function TenantProvider({ children }) {
const [tenant, setTenant] = useState(null)
useEffect(() => {
// 실제로는 백엔드 호출이나 런타임 메타에서 추출
const t = {
id: 'tenant-a',
name: 'Tenant A',
theme: {
primary: '#1e90ff',
background: '#ffffff'
},
logoUrl: '/assets/tenant-a-logo.png'
}
setTenant(t)
}, [])
if (!tenant) return null
return (
<TenantContext.Provider value={tenant}>
{children}
</TenantContext.Provider>
)
}
export const useTenant = () => useContext(TenantContext)
테마 적용 컴포넌트
import React from 'react'
import { useTenant } from './TenantProvider'
export function Header() {
const tenant = useTenant()
return (
<header style={{ background: tenant.theme.primary, color: '#fff', padding: '12px' }}>
<img src={tenant.logoUrl} alt={tenant.name} style={{ height: 32 }} />
<span style={{ marginLeft: 12 }}>{tenant.name}</span>
</header>
)
}
컴포넌트 슬롯 예시
특정 테넌트에서만 다른 요소를 넣어야 할 때 슬롯 패턴을 사용한다.
export function Dashboard({ ExtraHeader }) {
return (
<div>
<h2>대시보드</h2>
{ExtraHeader && <ExtraHeader />}
<main>메인 콘텐츠</main>
</div>
)
}
라우팅과 권한
테넌트에 따라 접근 가능한 라우트가 달라지면 라우트 구성 시 테넌트 설정을 반영해야 한다. 서버에서 라우트 목록을 내려주거나 클라이언트에서 조건부 렌더링으로 제어한다.
배포와 운영 고려사항
- 빌드 단위: 테넌트별로 완전히 다른 빌드가 필요한지 판단
- 캐시: 테넌트별 정적 자원 캐시 전략 설계
- 테스트: 테넌트별 E2E 테스트 시나리오 유지
마무리
멀티 테넌시 UI는 설계와 작은 패턴들로 해결할 수 있다. 핵심은 테넌트 설정을 중앙에서 관리하고, 컴포넌트 수준에서 유연하게 커스터마이징 지점을 제공하는 것이다. 위 예제를 바탕으로 실제 서비스 요구에 맞춰 테마, 슬롯, 권한 모델을 확장하면 안정적인 다중 테넌트 UI 구성이 가능하다.