여러 사이트가 하나의 서버에서 운영되고 있을 때, 사이트 간 데이터를 조회하거나 수정, 등록하려면 몇 가지 기본 원칙과 기술을 적용해야 합니다. 이를 구현하기 위해서는 API 통합, 보안 정책, 인증 및 권한 관리와 같은 요소들을 철저히 고려해야 합니다. 이번 글에서는 아래의 예제를 기반으로 구현 방법과 주요 고려사항을 상세히 설명합니다.
요구사항 분석
예시 상황
- 하나의 서버에서 여러 사이트를 운영 중:
- 각 사이트는 독립적으로 작동하지만, 데이터를 서로 조회하고 수정, 등록할 수 있어야 함.
- 예를 들어, aa.com에서 bb.com의 데이터를 수정하거나 cc.com에서 aa.com의 화면을 조회해야 함.
주요 고려사항
- 데이터 교환 방식
- 사이트 간 데이터를 안전하고 효율적으로 전달해야 함.
- 보안
- 인증 및 권한 관리를 통해 데이터 접근을 제한.
- 유지보수성
- 구조를 단순화하여 유지보수를 쉽게 해야 함.
- 확장성
- 추가 사이트가 생겨도 쉽게 확장 가능해야 함.
구현 방법
1. 데이터 교환 방식 선택
다음과 같은 방식 중 하나를 선택할 수 있습니다.
(1) RESTful API
- 각 사이트는 데이터를 공개할 API를 구축하여 서로 호출.
- 예를 들어, http://bb.com에 데이터 조회 API를 구현하면 http://aa.com에서 이를 호출하여 데이터를 얻음.
(2) GraphQL
- 데이터를 효율적으로 쿼리할 수 있는 방식.
- 단일 엔드포인트에서 필요한 데이터만 선택적으로 조회 가능.
(3) 서버 간 HTTP 요청
- 각 서버 간에 HTTP 요청을 직접 전송하여 데이터를 주고받음.
(4) 데이터베이스 공유
- 모든 사이트가 동일한 데이터베이스를 사용하도록 설정.
- 데이터 교환이 필요 없지만, 각 사이트에서 접근 권한 및 논리를 관리해야 함.
2. RESTful API 구현 예제
API 설계
각 사이트에서 데이터를 조회, 수정, 삭제하기 위한 API를 RESTful 방식으로 설계합니다.
1) API 엔드포인트 설계
다음은 http://bb.com에서 사용할 API 엔드포인트 예시입니다.
- 데이터 조회: GET /api/data
- 입력: id (선택)
- 출력: 데이터 리스트 또는 특정 데이터
- 데이터 등록: POST /api/data
- 입력: 데이터 내용
- 데이터 수정: PUT /api/data/{id}
- 입력: 수정할 데이터
- 데이터 삭제: DELETE /api/data/{id}
- 입력: 삭제할 데이터 ID
Spring Boot로 REST API 구현
다음은 Spring Boot로 구현한 간단한 REST API 예제입니다.
Controller 클래스
@RestController
@RequestMapping("/api/data")
public class DataController {
// 임시 데이터 저장소
private final Map<Integer, String> dataStore = new HashMap<>();
private int currentId = 1;
// 데이터 조회
@GetMapping
public ResponseEntity<List<String>> getData(@RequestParam(required = false) Integer id) {
if (id == null) {
return ResponseEntity.ok(new ArrayList<>(dataStore.values()));
} else {
String data = dataStore.get(id);
return data != null ? ResponseEntity.ok(Collections.singletonList(data))
: ResponseEntity.notFound().build();
}
}
// 데이터 등록
@PostMapping
public ResponseEntity<String> addData(@RequestBody String newData) {
dataStore.put(currentId++, newData);
return ResponseEntity.ok("Data added successfully");
}
// 데이터 수정
@PutMapping("/{id}")
public ResponseEntity<String> updateData(@PathVariable int id, @RequestBody String updatedData) {
if (dataStore.containsKey(id)) {
dataStore.put(id, updatedData);
return ResponseEntity.ok("Data updated successfully");
} else {
return ResponseEntity.notFound().build();
}
}
// 데이터 삭제
@DeleteMapping("/{id}")
public ResponseEntity<String> deleteData(@PathVariable int id) {
if (dataStore.remove(id) != null) {
return ResponseEntity.ok("Data deleted successfully");
} else {
return ResponseEntity.notFound().build();
}
}
}
3. 클라이언트에서 다른 사이트 호출하기
RestTemplate 사용 예제
Spring Boot의 RestTemplate을 사용하여 다른 사이트의 데이터를 호출할 수 있습니다.
클라이언트 코드 예제 (aa.com에서 bb.com 호출)
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class ApiClient {
private final RestTemplate restTemplate;
public ApiClient(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String getDataFromBbCom() {
String url = "http://bb.com/api/data";
ResponseEntity response = restTemplate.getForEntity(url, String.class);
return response.getBody();
}
}
4. 보안 및 인증 구현
JWT (JSON Web Token) 기반 인증
각 사이트 간 호출 시, JWT를 활용해 인증을 처리합니다.
JWT 토큰 생성
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
public static String generateToken(String subject) {
return Jwts.builder()
.setSubject(subject)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간 유효
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
}
JWT 검증
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
public class JwtValidator {
private static final String SECRET_KEY = "mySecretKey";
public static Claims validateToken(String token) {
return Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody();
}
}
5. 서버 간 호출 흐름 예제
- aa.com에서 bb.com 호출:
- aa.com이 JWT를 생성하여 요청 헤더에 포함.
- bb.com은 요청을 수신하여 JWT를 검증한 후 데이터 반환.
- 헤더에 토큰 추가
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + JwtUtil.generateToken("aa.com"));
HttpEntity entity = new HttpEntity<>(headers);
ResponseEntity response = restTemplate.exchange(
"http://bb.com/api/data",
HttpMethod.GET,
entity,
String.class
);
6. 데이터베이스 공유 방식
- 여러 사이트가 동일한 데이터베이스를 사용하는 경우, 단일 DB를 기반으로 필요한 데이터를 직접 조회하거나 변경합니다.
- 각 사이트는 논리적으로 다른 테이블이나 스키마를 사용하거나, 테이블에 사이트 구분 컬럼을 추가합니다.
예시: 사이트 구분 컬럼
CREATE TABLE site_data (
id INT PRIMARY KEY,
site_id VARCHAR(10),
data_content TEXT
);
-- 특정 사이트 데이터만 조회
SELECT * FROM site_data WHERE site_id = 'aa';
결론
사이트 간 데이터를 안전하고 효율적으로 공유하려면 RESTful API, 인증 체계, 데이터베이스 설계 등 다양한 기술을 통합적으로 고려해야 합니다.
이번 글에서는 API 중심의 구현 방법과 보안 방안을 설명했으며, 필요에 따라 GraphQL 또는 단일 데이터베이스 접근 방식을 적용할 수 있습니다.
이를 통해 여러 사이트를 통합적으로 관리하면서도 독립성을 유지할 수 있는 강력한 시스템을 설계할 수 있습니다.
'개발 > 기타' 카테고리의 다른 글
EL(Expression Language) 태그의 종류와 사용법 (0) | 2025.01.15 |
---|---|
JSTL 태그의 종류와 사용법 (1) | 2025.01.15 |
다양한 DB의 종류와 장점 및 단점 (0) | 2025.01.14 |
리눅스 명령어 총정리: 설명과 예제 (0) | 2025.01.14 |
파비콘(Favicon)의 정의와 역할, 활용 방법 (0) | 2025.01.13 |