💻 프로그래밍

SDK

Software Development Kit

소프트웨어 개발 도구 모음. 라이브러리, 문서, 샘플 코드 포함. 플랫폼별 제공.

📖 상세 설명

SDK(Software Development Kit)는 특정 플랫폼이나 서비스를 위한 애플리케이션을 개발하는 데 필요한 도구, 라이브러리, 문서, 코드 샘플의 종합 패키지입니다. SDK를 사용하면 개발자가 처음부터 모든 것을 구현할 필요 없이, 플랫폼 제공자가 미리 준비한 기능을 활용하여 빠르고 안정적으로 개발할 수 있습니다. 대표적으로 Android SDK, iOS SDK, AWS SDK 등이 있습니다.

SDK와 API, Library는 서로 관련되지만 구별되는 개념입니다. API는 소프트웨어 간 통신 규약(인터페이스)이고, Library는 재사용 가능한 코드의 집합입니다. SDK는 이 둘을 포함하면서 추가로 개발 도구, 디버거, 에뮬레이터, 문서까지 제공하는 포괄적인 개발 환경입니다. 예를 들어 Android SDK에는 Android API, 각종 라이브러리, Android Studio IDE, 에뮬레이터, ADB 디버깅 도구가 모두 포함됩니다.

SDK의 핵심 구성 요소는 크게 네 가지입니다. 첫째, 플랫폼 기능을 쉽게 호출할 수 있는 라이브러리와 프레임워크입니다. 둘째, API 레퍼런스와 튜토리얼이 포함된 공식 문서입니다. 셋째, 실제 사용법을 보여주는 샘플 코드와 예제 프로젝트입니다. 넷째, 컴파일러, 디버거, 테스트 도구 등 개발을 지원하는 도구들입니다.

실무에서 SDK는 개발 생산성을 극대화합니다. Android SDK는 전 세계 30억 대 이상의 디바이스를 대상으로 앱을 개발할 수 있게 하고, AWS SDK는 200개 이상의 클라우드 서비스를 프로그래밍 방식으로 제어할 수 있게 합니다. OpenAI SDK, Stripe SDK, Firebase SDK 등 서드파티 SDK를 통해 결제, 인증, AI 기능을 몇 줄의 코드로 통합할 수 있어, 현대 소프트웨어 개발에서 SDK는 필수적인 도구입니다.

💻 코드 예제

"""
AWS SDK (boto3) 사용 예제
S3 버킷 생성, 파일 업로드, 다운로드를 포함한 실무 패턴
"""

import boto3
from botocore.exceptions import ClientError
import logging
import os

# 로깅 설정
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class S3Manager:
    """AWS S3 작업을 관리하는 클래스"""

    def __init__(self, region_name: str = "ap-northeast-2"):
        """
        S3 클라이언트 초기화

        Args:
            region_name: AWS 리전 (기본값: 서울)
        """
        self.s3_client = boto3.client(
            "s3",
            region_name=region_name,
            # 자격 증명은 환경 변수 또는 AWS CLI 설정에서 자동 로드
            # AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
        )
        self.region = region_name

    def create_bucket(self, bucket_name: str) -> bool:
        """
        S3 버킷 생성

        Args:
            bucket_name: 생성할 버킷 이름 (전역적으로 고유해야 함)

        Returns:
            성공 여부
        """
        try:
            # 서울 리전은 LocationConstraint 필수
            self.s3_client.create_bucket(
                Bucket=bucket_name,
                CreateBucketConfiguration={
                    "LocationConstraint": self.region
                }
            )
            logger.info(f"버킷 생성 완료: {bucket_name}")
            return True
        except ClientError as e:
            error_code = e.response["Error"]["Code"]
            if error_code == "BucketAlreadyOwnedByYou":
                logger.info(f"버킷이 이미 존재합니다: {bucket_name}")
                return True
            logger.error(f"버킷 생성 실패: {e}")
            return False

    def upload_file(
        self,
        file_path: str,
        bucket_name: str,
        object_key: str = None
    ) -> dict:
        """
        파일을 S3에 업로드

        Args:
            file_path: 로컬 파일 경로
            bucket_name: 대상 버킷 이름
            object_key: S3 객체 키 (기본값: 파일명)

        Returns:
            업로드 결과 딕셔너리
        """
        if object_key is None:
            object_key = os.path.basename(file_path)

        try:
            # 파일 크기 확인
            file_size = os.path.getsize(file_path)

            # 5GB 이상이면 멀티파트 업로드 사용
            if file_size > 5 * 1024 * 1024 * 1024:
                logger.info("대용량 파일, 멀티파트 업로드 사용")

            self.s3_client.upload_file(
                file_path,
                bucket_name,
                object_key,
                ExtraArgs={"ContentType": "application/octet-stream"}
            )

            # 업로드된 객체 URL 생성
            url = f"https://{bucket_name}.s3.{self.region}.amazonaws.com/{object_key}"

            logger.info(f"업로드 완료: {object_key}")
            return {
                "success": True,
                "bucket": bucket_name,
                "key": object_key,
                "size_bytes": file_size,
                "url": url
            }
        except ClientError as e:
            logger.error(f"업로드 실패: {e}")
            return {"success": False, "error": str(e)}

    def download_file(
        self,
        bucket_name: str,
        object_key: str,
        download_path: str
    ) -> dict:
        """
        S3에서 파일 다운로드

        Args:
            bucket_name: 소스 버킷 이름
            object_key: S3 객체 키
            download_path: 다운로드 경로

        Returns:
            다운로드 결과 딕셔너리
        """
        try:
            self.s3_client.download_file(
                bucket_name,
                object_key,
                download_path
            )
            logger.info(f"다운로드 완료: {download_path}")
            return {
                "success": True,
                "path": download_path,
                "size_bytes": os.path.getsize(download_path)
            }
        except ClientError as e:
            logger.error(f"다운로드 실패: {e}")
            return {"success": False, "error": str(e)}


# 사용 예시
if __name__ == "__main__":
    # S3 매니저 초기화
    s3 = S3Manager(region_name="ap-northeast-2")

    # 버킷 생성
    bucket = "my-app-data-bucket-2024"
    s3.create_bucket(bucket)

    # 파일 업로드
    result = s3.upload_file(
        file_path="./data/model.pkl",
        bucket_name=bucket,
        object_key="models/v1/model.pkl"
    )

    if result["success"]:
        print(f"업로드 URL: {result['url']}")
        print(f"파일 크기: {result['size_bytes']:,} bytes")

🗣️ 실무 대화 예시

기술 스택 선정 회의에서

"결제 기능 구현에 Stripe SDK를 사용하면 좋겠습니다. PCI-DSS 준수, 3D Secure, 다양한 결제 수단을 직접 구현하려면 6개월은 걸리는데, SDK를 쓰면 2주면 충분합니다. 다만 트랜잭션당 수수료가 있으니 비용 분석도 같이 해봐야 합니다."

서드파티 SDK 도입 검토에서

"이 SDK는 마지막 업데이트가 2년 전이고, GitHub 이슈가 300개 넘게 쌓여있네요. Android 14 호환성 문제 리포트도 있고요. 공식 문서도 빈약해서, 차라리 공식 API를 직접 호출하는 래퍼를 우리가 만드는 게 나을 것 같습니다. 유지보수가 안 되는 SDK는 기술 부채가 됩니다."

모바일 앱 개발 킥오프에서

"크로스 플랫폼으로 가면 Flutter SDK가 좋은 선택입니다. Google이 관리하고, 문서가 잘 되어있고, Hot Reload로 개발 속도가 빠릅니다. 다만 네이티브 기능이 많이 필요하면 각 플랫폼 SDK를 직접 써야 하는 경우도 있으니, 요구사항을 먼저 정리합시다."

💬 면접에서 - SDK 선택 기준

"SDK를 선택할 때 저는 세 가지를 봅니다. 첫째 유지보수 상태 - GitHub 마지막 커밋이 언제인지, 이슈 대응이 활발한지. 둘째 문서 품질 - 예제 코드와 API 레퍼런스가 잘 정리되어 있는지. 셋째 커뮤니티 크기 - Stack Overflow 질문 수나 npm 주간 다운로드 수를 확인합니다. 이전 프로젝트에서 유지보수가 중단된 SDK 때문에 마이그레이션에 2개월 걸린 경험이 있어서 이 부분을 꼼꼼히 보게 됐습니다."

💬 코드 리뷰에서 - SDK 버전 관리

"이 PR에서 SDK 버전을 caret(^)으로 지정했는데, 메이저 SDK는 정확한 버전으로 고정하는 게 좋아요. ^2.0.0이면 2.x.x 최신 버전이 설치되는데, 패치 버전에도 breaking change가 있는 경우가 있거든요. 특히 결제 SDK는 버전 고정하고, lockfile을 커밋해서 팀 전체가 동일한 버전을 쓰도록 합시다. CI에서도 npm ci로 설치하고요."

⚠️ 주의사항

⚠️
버전 호환성 확인

SDK 버전과 런타임 환경의 호환성을 반드시 확인하세요. 예를 들어 Android SDK 34는 Java 17 이상이 필요하고, AWS SDK v3는 Node.js 14 이상을 요구합니다. 메이저 버전 업그레이드 시 Breaking Change가 있는지 릴리스 노트를 꼼꼼히 확인해야 합니다.

⚠️
라이센스 검토

SDK의 라이센스가 프로젝트와 호환되는지 확인하세요. GPL 라이센스 SDK를 상용 앱에 사용하면 소스 공개 의무가 발생할 수 있습니다. 대부분의 상용 SDK는 MIT, Apache 2.0 또는 자체 상용 라이센스를 사용하며, 법무팀 검토가 필요한 경우도 있습니다.

⚠️
보안 업데이트 모니터링

SDK에서 보안 취약점이 발견되면 즉시 업데이트해야 합니다. Dependabot, Snyk 같은 도구로 의존성 취약점을 자동 모니터링하고, 특히 인증, 결제, 암호화 관련 SDK는 보안 공지를 구독하여 신속하게 대응하세요.

🔗 관련 용어

📚 더 배우기