Skip to main content

React Native와 AWS 함께 사용하기

· 17 min read
Richard Threlkeld
AWS 모바일 부문 시니어 기술 제품 매니저

AWS는 클라우드 서비스 제공자로 기술 업계에서 널리 알려져 있다. 컴퓨팅, 스토리지, 데이터베이스 기술부터 완전 관리형 서버리스 서비스까지 다양한 제품을 제공한다. AWS 모바일 팀은 클라우드와 연결된 모바일 및 웹 애플리케이션을 더 안전하고 확장 가능하며 개발과 배포가 쉬워지도록 고객과 자바스크립트 생태계 구성원들과 긴밀히 협력해 왔다. 완전한 스타터 키트로 시작했지만, 최근에는 몇 가지 새로운 발전이 있었다.

이 블로그 포스트는 React와 React Native 개발자에게 흥미로운 내용을 다룬다:

  • AWS Amplify: 클라우드 서비스를 사용하는 자바스크립트 애플리케이션을 위한 선언적 라이브러리
  • AWS AppSync: 오프라인 및 실시간 기능을 갖춘 완전 관리형 GraphQL 서비스

AWS Amplify

React Native 애플리케이션은 Create React Native App이나 Expo 같은 도구를 사용해 쉽게 시작할 수 있다. 하지만 클라우드와 연결하려면 사용 사례에 맞는 인프라 서비스를 선택하는 과정이 복잡할 수 있다. 예를 들어, React Native 앱에서 사진을 업로드해야 한다고 가정해보자. 이를 사용자별로 보호해야 할까? 그렇다면 회원가입이나 로그인 프로세스가 필요할 것이다. 자체 사용자 디렉토리를 사용할지, 소셜 미디어 프로바이더를 사용할지도 고려해야 한다. 사용자가 로그인한 후 커스텀 비즈니스 로직을 포함한 API를 호출해야 할 수도 있다.

이런 문제를 해결하기 위해 AWS Amplify라는 라이브러리를 출시했다. 이 라이브러리는 AWS 특정 구현보다는 작업의 "카테고리"로 설계되었다. 예를 들어, 사용자가 회원가입하고 로그인한 후 개인 사진을 업로드해야 한다면, AuthStorage 카테고리를 애플리케이션에 추가하면 된다:

import { Auth } from 'aws-amplify';

Auth.signIn(username, password)
.then(user => console.log(user))
.catch(err => console.log(err));

Auth.confirmSignIn(user, code)
.then(data => console.log(data))
.catch(err => console.log(err));

위 코드에서 Amplify가 도와주는 일반적인 작업의 예를 볼 수 있다. 이메일이나 SMS를 사용한 다중 인증(MFA) 코드 사용이 그 예이다. 현재 지원되는 카테고리는 다음과 같다:

  • Auth: 자격 증명 자동화를 제공한다. 기본 구현은 AWS 자격 증명을 사용해 서명하고, Amazon Cognito에서 OIDC JWT 토큰을 가져온다. MFA 기능 같은 일반적인 기능도 지원한다.
  • Analytics: 한 줄의 코드로 Amazon Pinpoint에서 인증된 사용자나 비인증 사용자를 추적할 수 있다. 필요에 따라 커스텀 메트릭이나 속성으로 확장할 수 있다.
  • API: AWS Signature Version 4을 활용해 RESTful API와 안전하게 상호작용한다. 이 API 모듈은 Amazon API Gateway를 사용한 서버리스 인프라에서 유용하다.
  • Storage: Amazon S3에 콘텐츠를 업로드, 다운로드, 목록화하는 간단한 커맨드를 제공한다. 사용자별로 데이터를 공개 또는 비공개로 쉽게 그룹화할 수 있다.
  • Caching: 웹 앱과 React Native 전반에서 사용할 수 있는 LRU 캐시 인터페이스를 제공하며, 구현별 지속성을 사용한다.
  • i18n and Logging: 국제화 및 지역화 기능, 디버깅 및 로깅 기능을 제공한다.

Amplify의 장점 중 하나는 특정 프로그래밍 환경에 맞는 "모범 사례"를 설계에 반영했다는 점이다. 예를 들어, React Native 개발자와 고객과 협력하면서 발견한 문제 중 하나는 빠르게 작동시키기 위해 개발 중에 취한 단축키가 프로덕션 스택으로 이어지는 경우가 많다는 것이다. 이는 확장성이나 보안을 저해할 수 있으며, 인프라 재구축과 코드 리팩토링을 강제할 수 있다.

이를 피하기 위해 도움을 주는 한 가지 예는 AWS Lambda를 사용한 서버리스 참조 아키텍처이다. 이는 백엔드를 구축할 때 Amazon API Gateway와 AWS Lambda를 함께 사용하는 모범 사례를 보여준다. 이 패턴은 Amplify의 API 카테고리에 반영되어 있다. 이 패턴을 사용해 여러 REST 엔드포인트와 상호작용하고, 커스텀 비즈니스 로직을 위해 헤더를 Lambda 함수까지 전달할 수 있다. 또한 AWS Mobile CLI를 출시해 새로운 React Native 프로젝트나 기존 프로젝트를 이 기능으로 시작할 수 있게 했다. 시작하려면 npm을 통해 설치하고, 설정 프롬프트를 따르면 된다:

npm install --global awsmobile-cli
awsmobile configure

모바일 생태계에 특화된 또 다른 모범 사례는 비밀번호 보안이다. 기본 Auth 카테고리 구현은 Amazon Cognito 사용자 풀을 사용해 사용자 등록과 로그인을 처리한다. 이 서비스는 Secure Remote Password 프로토콜을 구현해 인증 시도 중 사용자를 보호한다. 프로토콜의 수학적 원리를 읽어보면, 원시 루트를 통해 그룹을 생성할 때 큰 소수를 사용해야 한다는 것을 알 수 있다. React Native 환경에서는 JIT가 비활성화되어 있어, 이런 보안 작업을 위한 BigInteger 계산이 덜 효율적이다. 이를 고려해 Android와 iOS용 네이티브 브릿지를 출시했으며, 프로젝트 내에서 연결할 수 있다:

npm install --save aws-amplify-react-native
react-native link amazon-cognito-identity-js

또한 Expo 팀이 최신 SDK에 이를 포함시켜 Amplify를 사용할 수 있게 되어, eject 없이도 사용할 수 있다.

마지막으로, React Native(및 React) 개발에 특화된 Amplify는 고차 컴포넌트(HOCs)를 포함해 앱에 로그인이나 회원가입 기능을 쉽게 추가할 수 있다:

import Amplify, { withAuthenticator } from 'aws-amplify-react-native';
import aws_exports from './aws-exports';

Amplify.configure(aws_exports);

class App extends React.Component {
...
}

export default withAuthenticator(App);

기본 컴포넌트는 <Authenticator />로도 제공되며, UI를 완전히 커스터마이즈할 수 있다. 또한 사용자 상태를 관리하는 데 필요한 속성(예: 로그인 여부나 MFA 확인 대기 상태)과 상태 변경 시 실행할 콜백도 제공한다.

마찬가지로, 다양한 사용 사례에 사용할 수 있는 일반 React 컴포넌트도 제공한다. 필요에 따라 커스터마이즈할 수 있으며, 예를 들어 Storage 모듈에서 Amazon S3의 모든 비공개 이미지를 표시할 수 있다:

<S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}/>

앞서 보여준 것처럼, 공개 또는 비공개 스토리지 옵션을 통해 컴포넌트 기능을 제어할 수 있다. 특정 UI 컴포넌트와 상호작용할 때 자동으로 분석 데이터를 수집하는 기능도 있다:

return <S3Album track/>

AWS Amplify는 설정보다 규약을 우선하는 개발 스타일을 선호하며, 전역 초기화 루틴이나 카테고리 수준에서 초기화를 수행한다. 시작하는 가장 빠른 방법은 aws-exports 파일을 사용하는 것이다. 하지만 개발자는 기존 리소스와 함께 독립적으로 라이브러리를 사용할 수도 있다.

철학에 대한 깊은 이해와 전체 데모를 보려면 AWS re:Invent의 비디오를 확인해보자.

AWS AppSync

AWS Amplify 출시 직후, AWS AppSync도 공개했다. AWS AppSync는 오프라인과 실시간 기능을 모두 지원하는 완전 관리형 GraphQL 서비스다. 다양한 클라이언트 프로그래밍 언어(네이티브 Android 및 iOS 포함)에서 GraphQL을 사용할 수 있지만, 특히 React Native 개발자들 사이에서 인기가 높다. 이는 데이터 모델이 단방향 데이터 흐름과 컴포넌트 계층 구조에 잘 맞기 때문이다.

AWS AppSync를 사용하면 자신의 AWS 계정에 있는 리소스에 연결할 수 있다. 즉, 데이터를 소유하고 제어할 수 있다. 이는 데이터 소스를 사용해 이루어지며, Amazon DynamoDB, Amazon Elasticsearch, AWS Lambda를 지원한다. 이를 통해 NoSQL과 전체 텍스트 검색과 같은 기능을 단일 GraphQL API로 결합할 수 있다. 데이터 소스를 자유롭게 조합할 수 있다. AppSync 서비스는 스키마에서 프로비저닝할 수도 있다. 따라서 AWS 서비스에 익숙하지 않더라도 GraphQL SDL을 작성하고 버튼을 클릭하기만 하면 자동으로 실행할 수 있다.

AWS AppSync의 실시간 기능은 잘 알려진 이벤트 기반 패턴을 사용한 GraphQL 구독으로 제어된다. AWS AppSync의 구독은 스키마에서 GraphQL 지시어로 제어되며, 스키마는 모든 데이터 소스를 사용할 수 있다. 따라서 Amazon DynamoDB와 Amazon Elasticsearch Service를 통해 데이터베이스 작업에서 알림을 트리거하거나, AWS Lambda를 통해 인프라의 다른 부분에서 알림을 트리거할 수 있다.

AWS Amplify와 유사하게, AWS AppSync를 사용해 GraphQL API에 엔터프라이즈 보안 기능을 적용할 수 있다. 이 서비스는 API 키를 통해 빠르게 시작할 수 있게 해준다. 하지만 프로덕션 환경으로 전환할 때는 AWS Identity and Access Management(IAM) 또는 Amazon Cognito 사용자 풀의 OIDC 토큰을 사용할 수 있다. 타입에 대한 정책을 통해 리졸버 수준에서 접근을 제어할 수 있다. 또한 런타임에 세분화된 접근 제어를 위해 사용자가 특정 데이터베이스 리소스의 소유자인지 확인하는 등의 논리적 검사를 수행할 수 있다. 리졸버 실행 또는 개별 데이터베이스 레코드 접근을 위해 그룹 멤버십을 확인하는 기능도 제공한다.

React Native 개발자가 이 기술을 더 쉽게 배울 수 있도록, AWS AppSync 콘솔 홈페이지에서 내장된 GraphQL 샘플 스키마를 실행할 수 있다. 이 샘플은 GraphQL 스키마를 배포하고, 데이터베이스 테이블을 프로비저닝하며, 쿼리, 뮤테이션, 구독을 자동으로 연결한다. 또한 이 내장 스키마를 활용한 React Native 예제React 예제도 제공된다. 이를 통해 클라이언트와 클라우드 컴포넌트를 몇 분 만에 실행할 수 있다.

AWSAppSyncClient를 사용하면 시작이 간단하다. 이 클라이언트는 Apollo Client에 연결된다. AWSAppSyncClient는 GraphQL API의 보안 및 서명, 오프라인 기능, 구독 핸드셰이크 및 협상 프로세스를 처리한다:

import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from 'aws-appsync-react';
import { AUTH_TYPE } from "aws-appsync/lib/link/auth-link";

const client = new AWSAppSyncClient({
url: awsconfig.graphqlEndpoint,
region: awsconfig.region,
auth: {type: AUTH_TYPE.API_KEY, apiKey: awsconfig.apiKey}
});

AppSync 콘솔은 GraphQL 엔드포인트, AWS 리전, API 키가 포함된 설정 파일을 제공한다. 그런 다음 React Apollo와 함께 클라이언트를 사용할 수 있다:

const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
);

이제 표준 GraphQL 쿼리를 사용할 수 있다:

query ListEvents {
listEvents{
items{
__typename
id
name
where
when
description
comments{
__typename
items{
__typename
eventId
commentId
content
createdAt
}
nextToken
}
}
}
}

위 예제는 AppSync가 프로비저닝한 샘플 앱 스키마를 사용한 쿼리를 보여준다. 이 예제는 DynamoDB와의 상호작용뿐만 아니라 데이터 페이징(암호화된 토큰 포함)과 EventsComments 간의 타입 관계도 보여준다. 앱이 AWSAppSyncClient로 구성되어 있기 때문에 데이터는 자동으로 오프라인에 저장되고, 디바이스가 다시 연결될 때 동기화된다.

이 비디오에서 이 기술의 심층 분석과 React Native 데모를 확인할 수 있다.

피드백

라이브러리를 개발한 팀은 여러분이 이 라이브러리와 서비스를 어떻게 활용하고 있는지 듣고 싶어 한다. 또한 React와 React Native를 클라우드 서비스와 함께 사용할 때 개발을 더 쉽게 만들기 위해 어떤 부분을 개선할 수 있는지 의견을 구하고 있다. AWS 모바일 팀에 연락하려면 AWS Amplify 또는 AWS AppSync GitHub 페이지를 방문하면 된다.