자바칩

[Spring] API 설계 본문

Study

[Spring] API 설계

아기제이 2024. 5. 20. 18:45
728x90

API 설계의 중요성

API(Application Programming Interface, 응용 프로그래밍 인터페이스)는 소프트웨어 구성 요소가 서로 상호작용할 수 있게 하는 규칙 및 도구 모음이다. 잘 설계된 API는 다음과 같은 중요한 이점을 제공한다.

  1. 유지보수성: 명확하고 일관된 API는 코드의 이해와 수정이 용이하여 유지보수가 쉬워진다.
  2. 확장성: 잘 설계된 API는 새로운 기능을 추가하거나 기존 기능을 개선할 때 확장이 용이하다.
  3. 재사용성: 표준화된 API는 다양항 애플리케이션에서 쉽게 재사용될 수 있다.
  4. 협업 용이성: API는 개발 팀 간의 협업을 용이하게 하여, 분산된 팀이 동시에 작업할 수 있도록 지원한다.
  5. 사용자 경험 향상: 명확하고 직관적인 API는 개발자가 쉽게 이해하고 사용할 수 있어, 최종 사용자에게 더 나은 경험을 제공한다.

좋은 API를 설계하기 위한 기준

  1. 명확한 목적: API의 목적과 기능이 명확히 정의되어야 한다.
  2. 일관성: API의 모든 부분이 일관된 네이밍 규칙과 설계 원칙을 따른다.
  3. 직관성: 사용자가 쉽게 이해하고 사용할 수 있도록 직관적이어야 한다.
  4. 문서화: 상세하고 이해하기 쉬운 문서가 제공되어야 한다.
  5. 유연성: 다양한 사용 사례를 지원할 수 있도록 유연해야 한다.
  6. 버전 관리: 변경 사항이 기존 사용자에게 미치는 영향을 최소화할 수 있도록 버전 관리가 잘 되어야 한다.
  7. 보안: 안전한 데이터 처리 및 전송을 보장해야 한다.
  8. 성능: 효율적이고 빠르게 동작해야 한다.

API 버전 관리를 효율적으로 수행하기 위한 전략

  1. 명시적 버전 관리: URL 경로에 버전 번호를 포함시켜 명시적으로 관리한다. 예를 들어, '/api/v1/resource'.
  2. 호환성 유지: 가능한 한 하위 호환성을 유지하도록 한다. 새로운 버전의 API가 이전 버전의 기능을 지원하도록 한다.
  3. 적절한 변경 통보: API 변경 사항을 사용자에게 미리 통보하고, 충분한 마이그레이션 기간을 제공한다.
  4. 디프리케이션(deprecation) 정책: 구버전 API를 사용할 수 없는 시점까지 점진적으로 종료하는 정책을 마련한다.
  5. 테스트: 여러 버전의 API가 동시에 동작하도록 테스트 환경을 구성하고 철저히 테스트한다.

외부에 공개될 API와 내부 시스템용 API 설계의 차이점

  1. 외부 API
    • 보안: 외부 API는 더욱 강력한 보안 조치가 필요하다.
    • 문서화: 사용자를 위해 상세하고 이해하기 쉬운 문서가 필요하다.
    • 버전 관리: 버전 관리와 호환성에 특히 신경써야 한다.
    • 사용성: 다양한 사용자를 고려하여 직관적이고 사용하기 쉬워야 한다.
    • 성능: 높은 성능을 유지하면서도 안정적으로 동작해야 한다
  2. 내부 API
    • 최적화: 내부 시스템의 요구에 맞게 최적화된 설계가 가능하다.
    • 문서화: 외부 API만큼 상세하지 않아도 되지만, 내부 개발자가 이해할 수 있도록 문서화가 필요하다.
    • 보안: 내부 네트워크에서 동작하지만, 여전히 적절한 보안 조치가 필요하다.
    • 유연성: 빠른 변경과 배포가 가능하도록 유연하게 설계할 수 있다.

API 설계 시 보안을 고려하는 방법과 예시

  1. 인증 및 권한 부여
    • OAuth2: 토큰 기반 인증을 통해 안전하게 API에 접근한다.
    • API 키: API 키를 사용하여 접근을 제한한다.
  2. 데이터 암호화
    • HTTPS: 전송 중인 데이터를 보호하기 위해 HTTPS를 사용한다.
    • 암호화: 민감한 데이터는 저장 시 암호화한다.
  3. 입력 검증
    • 유효성 검사: 모든 입력 데이터를 검증하여 SQL 인젝션 및 XSS 공격을 방지한다.
    • 화이트리스트: 허용된 입력만 처리하도록 화이트리스트를 사용한다.
  4. 로깅 및 모니터링
    • 로그: 모든 API 요청과 응답을 로깅하여 이상 행동을 감지한다.
    • 모니터링: 실시간 모니터링을 통해 의심스러운 활동을 감지하고 대응한다.

예시

 
    // 인증 예시 (JWT 토큰 사용)
    @RequestMapping("/api/resource")
    public ResponseEntity<Resource> getResource(@RequestHeader("Authorization") String token) {
        if (!jwtService.isValid(token)) {
            return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
        }  
        Resource resource = resourceService.getResource();
        return new ResponseEntity<>(resource, HttpStatus.OK);
    }

    // 입력 검증 예시
    public void createUser(String username, String password) {
        if (!isValidUsername(username) || !isValidPassword(password)) {
            throw new IllegalArgumentException("Invalid input");
        }
        userRepository.save(new User(username, password));
    }
 

 

대규모 사용자를 대상으로 하는 서비스의 API를 설계할 때 고려해야 할 성능 최적화 전략

  1. 캐싱
    • HTTP 캐싱: 자주 요청되는 데이터를 클라이언트 또는 프록시 서버에 캐싱한다.
    • 메모리 캐싱: Redis, Memcached와 같은 인메모리 데이터 저장소를 사용하여 성능을 향상시킨다.
  2. 로드 밸런싱
    • 수평 확장: 여러 서버에 부하를 분산시켜 처리 능력을 향상시킨다.
  3. 데이터베이스 최적화
    • 쿼리 최적화: 효율적인 쿼리를 작성하고, 인덱스를 적절히 사용한다.
    • 데이터 분할: 데이터베이스 샤딩을 통해 큰 테이블을 분할하여 성능을 향상시킨다.
  4. 비동기 처리
    • 비동기 호출: 긴 작업은 비동기적으로 처리하여 응답 시간을 줄인다.
    • 메시지 큐: RabbitMQ, Kafka와 같은 메시지 큐를 사용하여 비동기 작업을 처리한다.
  5. 압축
    • 데이터 압축: JSON, XML과 같은 응답 데이터를 압축하여 전송한다.
  6. API 게이트웨이 사용
    • 게이트웨이: API 게이트웨이를 통해 요청을 관리하고, 보안, 로깅, 모니터링을 일원화한다.

예시

 
    // 캐싱 예시 (스프링 캐시 사용)
    @Cacheable("resource")
    public Resource getResource() {
        return resourceRepository.findById(1);
    }

    // 비동기 처리 예시 (스프링 비동기 호출)
    @Async
    public CompletableFuture<Resource> getResourceAsync() {
        Resource resource = resourceRepository.findById(1);
        return CompletableFuture.completedFuture(resource);
    }

    // 데이터 압축 예시
    @RequesetMapping(value = "/api/resource", produces = "application/json")
    public ResponseEntity<Resource> getResource() {
        Resource resource = resourceService.getResource();
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_ENCODING, "gzip")
                .body(resource);
    }
 

 

이러한 전략을 통해 대규모 사용자를 대상으로 하는 API의 성능을 최적화할 수 있다.

'Study' 카테고리의 다른 글

HTTP 메서드 측면에서 API 작업 정의  (0) 2024.06.30