댓글 검색 목록

[javascript] TypeScript 및 AWS로 API를 구축하기 위한 전체 안내서

페이지 정보

작성자 운영자 작성일 20-08-31 18:26 조회 686 댓글 0

이 기사에서는 TypeScript 및 Serverless로 API를 빠르고 쉽게 빌드 할 수 있는 방법을 살펴 보겠습니다.


https://www.freecodecamp.org/news/build-an-api-with-typescript-and-aws/


그런 다음 aws-sdk를 사용하여 다른 AWS 서비스에 액세스하고 자동 번역 API를 생성하는 방법을 알아 봅니다.


보고 배우고 싶다면 아래 비디오를 확인하십시오.



시작하기 


이 전체 프로세스를 시작하려면 서버리스 프레임 워크가 설치되어 있고 컴퓨터에 AWS 프로필이 설정되어 있는지 확인해야 합니다. 그렇지 않은 경우 모든 설정 방법에 대한 이 비디오를 확인할 수 있습니다.


이 자습서를 따르려면 모든 단계를 따르거나 여기에서 코드를 다운로드하고 완성 된 코드를 따를 수 있습니다.


이제 서버리스 프로젝트와 API를 만드는 중입니다. 터미널에서 시작하고 명령을 실행하여 새 저장소를 만들어야 합니다. 폴더 이름을 {YOUR FOLDER NAME}으로 전환하기 만하면 됩니다.


serverless create --template aws-nodejs-typescript --path {YOUR FOLDER NAME}

이것은 TypeScript로 매우 기본적인 서버리스 프로젝트를 생성합니다. VS Code로 이 새 폴더를 열면 템플릿이 제공 한 내용을 볼 수 있습니다.

Screenshot-2020-08-21-at-06.54.45.png 


우리가 보고자 하는 주요 파일은 serverless.ts 파일과 handler.ts 파일입니다.


serverless.ts 파일은 배포를 위한 구성이 보관되는 곳입니다. 이 파일은 서버리스 프레임 워크에 프로젝트 이름, 코드의 런타임 언어, 함수 목록 및 기타 몇 가지 구성 옵션을 알려줍니다.


프로젝트의 아키텍처를 변경하고자 할 때마다 이것이 우리가 작업 할 파일입니다.


다음 파일은 handler.ts 파일입니다. 여기에 템플릿에서 제공한 람다에 대한 예제 코드가 있습니다. 매우 기본적이며 메시지 및 입력 이벤트와 함께 API Gateway 응답을 반환합니다. 나중에 이를 자체 API의 시작 블록으로 사용할 것입니다.


나만의 Lambda 생성 


이제 템플릿으로 얻은 결과를 확인 했으므로 자체 Lambda 및 API 엔드 포인트를 추가 할 차례입니다.


시작하려면 모든 람다 코드를 담을 새 폴더를 만들고 람다라고 부를 것입니다. 이는 특히 한 프로젝트에서 몇 가지 다른 람다를 얻기 시작할 때 이를 구성하는 데 도움이 됩니다.


이 새 폴더에서 getCityInfo.ts라는 새 람다를 만들 것입니다. 이 파일을 열면 코드 생성을 시작할 수 있습니다. 모든 handler.ts 코드를 시작점으로 복사하여 시작할 수 있습니다.


첫 번째로 할 일은 함수의 이름을 핸들러로 변경하는 것입니다. 이것은 개인적인 선호 사항이지만 이벤트 핸들러를 처리하는 함수의 이름을 지정하는 것을 좋아합니다.


이 함수의 첫 번째 줄에 사용자가 요청하는 도시를 가져 오기 위해 코드를 추가해야 합니다. pathParameters를 사용하여 URL 경로에서 가져올 수 있습니다.


const city = event.pathparameter?.city;

눈에 띄는 한 가지는?. 그 선언에서. 이것은 Optional Chaining이며 정말 멋진 기능입니다. 


경로 매개 변수가 진실이면 도시 매개 변수를 가져오고, 그렇지 않으면 정의되지 않음을 리턴 함을 의미합니다. 즉, pathParameter가 객체가 아닌 경우 노드 런타임 오류를 유발하는 정의되지 않은 오류의 도시를 읽을 수 없음 속성을 얻지 못합니다.


이제 도시가 생겼으므로 해당 도시가 유효하고 해당 도시에 대한 데이터가 있는지 확인해야 합니다. 이를 위해서는 데이터가 필요합니다. 아래 코드를 사용하여 파일 하단에 붙여 넣을 수 있습니다.


interface CityData {
    name: string;
    state: string;
    description: string;
    mayor: string;
    population: number;
    zipCodes?: string;
}

const cityData: { [key: string]: CityData } = {
    newyork: {
        name: 'New York',
        state: 'New York',
        description:
            'New York City comprises 5 boroughs sitting where the Hudson River meets the Atlantic Ocean. At its core is Manhattan, a densely populated borough that’s among the world’s major commercial, financial and cultural centers. Its iconic sites include skyscrapers such as the Empire State Building and sprawling Central Park. Broadway theater is staged in neon-lit Times Square.',
        mayor: 'Bill de Blasio',
        population: 8399000,
        zipCodes: '100xx–104xx, 11004–05, 111xx–114xx, 116xx',
    },
    washington: {
        name: 'Washington',
        state: 'District of Columbia',
        description: `DescriptionWashington, DC, the U.S. capital, is a compact city on the Potomac River, bordering the states of Maryland and Virginia. It’s defined by imposing neoclassical monuments and buildings – including the iconic ones that house the federal government’s 3 branches: the Capitol, White House and Supreme Court. It's also home to iconic museums and performing-arts venues such as the Kennedy Center.`,
        mayor: 'Muriel Bowser',
        population: 705549,
    },
    seattle: {
        name: 'Seattle',
        state: 'Washington',
        description: `DescriptionSeattle, a city on Puget Sound in the Pacific Northwest, is surrounded by water, mountains and evergreen forests, and contains thousands of acres of parkland. Washington State’s largest city, it’s home to a large tech industry, with Microsoft and Amazon headquartered in its metropolitan area. The futuristic Space Needle, a 1962 World’s Fair legacy, is its most iconic landmark.`,
        mayor: 'Jenny Durkan',
        population: 744955,
    },
};

이것과 JavaScript의 차이점은 데이터 구조가 무엇인지 시스템에 알려주는 인터페이스를 만들 수 있다는 것입니다. 이것은 처음에는 추가 작업처럼 느껴지지만 나중에 모든 것을 더 쉽게 만드는 데 도움이 될 것입니다.



인터페이스 내에서 도시 객체의 키를 정의합니다. 일부는 문자열, 하나의 숫자, zipCodes는 선택적 속성입니다. 이것은 그것이 있을 수 있지만 반드시 있을 필요는 없음을 의미합니다.


인터페이스를 테스트하려면 도시 데이터의 모든 도시에 새 속성을 추가해 볼 수 있습니다.


TypeScript는 새 속성이 인터페이스에 존재하지 않는다는 것을 즉시 알려줍니다. 필요한 속성 중 하나를 삭제하면 TypeScript도 불평합니다. 이렇게 하면 항상 올바른 데이터가 있고 개체가 항상 예상대로 정확하게 표시됩니다.


이제 데이터가 확보되었으므로 사용자가 올바른 도시 요청을 보냈는지 확인할 수 있습니다.


if (!city || !cityData[city]) {
    
}

이 문장이 참이면 사용자가 잘못한 것이므로 400 응답을 반환해야 합니다.


여기에 코드를 수동으로 입력 할 수 있지만 가능한 API 응답 코드 중 몇 가지에 대한 메서드를 사용하여 새 apiResponses 객체를 만들 것입니다.


const apiResponses = {
    _200: (body: { [key: string]: any }) => {
        return {
            statusCode: 200,
            body: JSON.stringify(body, null, 2),
        };
    },
    _400: (body: { [key: string]: any }) => {
        return {
            statusCode: 400,
            body: JSON.stringify(body, null, 2),
        };
    },
};

이렇게 하면 나중에 파일에서 훨씬 쉽게 재사용 할 수 있습니다. 또한 body의 속성 하나 : {[key : string] : any}가 있음을 확인해야 합니다. 이것은 이 함수가 객체가 되어야 하는 하나의 body 속성을 가지고 있음을 나타냅니다. 해당 개체는 모든 유형의 값을 가진 키를 가질 수 있습니다.


본문이 항상 문자열이라는 것을 알고 있기 때문에 JSON.stringify를 사용하여 문자열 본문을 반환 할 수 있습니다.


이 함수를 핸들러에 추가하면 다음과 같이 됩니다.


export const handler: APIGatewayProxyHandler = async (event, _context) => {
    const city = event.pathParameters?.city;

    if (!city || !cityData[city]) {
        return apiResponses._400({ message: 'missing city or no data for that city' });
    }

    return apiResponses._200(cityData[city]);
};

사용자가 도시를 전달하지 않았거나 데이터가 없는 도시를 전달했다면 오류 메시지와 함께 400을 반환합니다. 데이터가 존재하는 경우 데이터 본문과 함께 200을 반환합니다.


새 번역 API 추가 


이전 섹션에서는 TypeScript API 저장소를 설정하고 하드 코딩 된 데이터를 사용하는 람다를 만들었습니다.


이 부분에서는 aws-sdk를 사용하여 다른 AWS 서비스와 직접 상호 작용하여 정말 강력한 API를 생성하는 방법을 알려드립니다.



시작하려면 번역 API에 대한 새 파일을 추가해야 합니다. translate.ts라는 lambdas 폴더 아래에 새 파일을 만듭니다. 몇 가지 기본적인 상용구 코드로 이 파일을 시작할 수 있습니다. TypeScript API Lambda의 시작 코드입니다.


import { APIGatewayProxyHandler } from 'aws-lambda';
import 'source-map-support/register';

export const handler: APIGatewayProxyHandler = async (event) => {
    
};

이제 사용자가 번역하려는 텍스트와 번역 할 언어를 가져와야 합니다. 요청 본문에서 얻을 수 있습니다.


여기서 해야 할 한 가지 추가 작업은 본문을 구문 분석하는 것입니다. 기본적으로 API Gateway는 본문에 전달 된 모든 JSON을 문자열화 합니다. 그런 다음 본문에서 텍스트와 언어를 분해 할 수 있습니다.


const body = JSON.parse(event.body);
const { text, language } = body;

이제 사용자가 텍스트와 언어를 전달했는지 확인해야 합니다.


if (!text) {
    // retrun 400
}
if (!language) {
    // return 400
}

마지막 부분에서는 400 응답을 파일의 함수로 만들었습니다. 여러 파일에서 이러한 API 응답을 사용할 것이므로 자체 공통 파일로 가져 오는 것이 좋습니다.


common이라는 람다 아래에 새 폴더를 만듭니다. 여기에 모든 공통 기능을 저장할 것입니다.


해당 폴더에서 apiResponses.ts라는 새 파일을 만듭니다. 이 파일은 _200 및 _400 메소드가 있는 apiResponses 객체를 내보낼 것입니다. 다른 응답 코드를 반환해야 하는 경우 이 개체에 추가 할 수 있습니다.


const apiResponses = {
    _200: (body: { [key: string]: any }) => {
        return {
            statusCode: 200,
            body: JSON.stringify(body, null, 2),
        };
    },
    _400: (body: { [key: string]: any }) => {
        return {
            statusCode: 400,
            body: JSON.stringify(body, null, 2),
        };
    },
};

export default apiResponses;

이제 해당 객체를 코드로 가져와 코드에서 이러한 일반적인 메서드를 사용할 수 있습니다. translate.ts 파일 맨 위에 다음 줄을 추가 할 수 있습니다.


import apiResponses from './common/apiResponses';

해당 개체에 대해 _400 메서드를 호출하도록 텍스트 및 언어 검사를 업데이트합니다.


if (!text) {
    return apiResponses._400({ message: 'missing text fom the body' });
}
if (!language) {
    return apiResponses._400({ message: 'missing language from the body' });
}

완료되면 번역 할 텍스트와 번역 할 언어가 있음을 알고 있으므로 번역 프로세스를 시작할 수 있습니다.


aws-sdk를 사용하는 것은 거의 항상 비동기 작업이므로 오류 처리가 더 쉬워 지도록 try / catch로 래핑 할 것입니다.


try {
    
} catch (error) {
    
}

가장 먼저 해야 할 일은 aws-sdk를 가져 와서 번역 서비스의 새 인스턴스를 만드는 것입니다.


이를 위해서는 aws-sdk를 설치 한 다음 가져와야 합니다. 먼저 npm install --save aws-sdk를 실행 한 다음이 코드를 번역 파일 상단에 추가합니다.


import * as AWS from 'aws-sdk';

const translate = new AWS.Translate();

이것으로 우리는 번역 코드를 작성할 수 있습니다. 먼저 번역을 하는 줄부터 시작하겠습니다. 이것을 시도 섹션에 추가하십시오.


const translatedMessage = await translate.translateText(translateParams).promise();

여러분 중 일부가 눈치 채 셨을 수 있는 한 가지는 우리가 아직 정의하지 않고 translateParams를 전달하고 있다는 것입니다. 아직 어떤 유형인지 확실하지 않기 때문입니다.


이를 확인하기 위해 VS Code에서 go to definition이라는 도구를 사용할 수 있습니다. 이를 통해 정의 된 경우 함수가 있는 위치로 이동할 수 있으므로 매개 변수 유형이 무엇인지 알아낼 수 있습니다. 마우스 오른쪽 버튼을 클릭하고 정의로 이동을 선택하거나 Ctrl 키를 누른 상태에서 기능을 클릭 할 수 있습니다.


Screenshot-2020-08-23-at-08.14.03.png 


보시다시피 translateText 함수는 Translate.Types.TranslateTextRequest의 매개 변수를 사용합니다.


이것을 알아내는 또 다른 방법은 translateText 함수 위에 마우스를 올려 인텔리 센스를 사용하는 것입니다. 다음과 같은 매개 변수를 볼 수 있습니다. AWS.Translate.TranslateTextRequest :


Screenshot-2020-08-23-at-08.15.30.png 


이를 통해 이전에 만든 번역 요청 위에 번역 매개 변수를 만들 수 있습니다. 그런 다음 설정하는 유형에 따라 채울 수 있습니다. 이것은 우리가 올바른 필드를 전달하고 있는지 확인합니다.


const translateParams: AWS.Translate.Types.TranslateTextRequest = {
    Text: text,
    SourceLanguageCode: 'en',
    TargetLanguageCode: language,
};

이제 매개 변수가 있고 이를 translate.translateText 함수로 전달 했으므로 응답 생성을 시작할 수 있습니다. 이것은 번역 된 메시지와 함께 200 개의 응답이 될 것입니다.


return apiResponses._200({ translatedMessage });

이 모든 것이 완료되면 캐치 섹션으로 이동할 수 있습니다. 여기에서는 오류를 로그 아웃 한 다음 공통 파일에서 400 응답을 반환하려고 합니다.


console.log('error in the translation', error);
return apiResponses._400({ message: 'unable to translate the message' });

완료되면 람다 코드가 완료되었으므로 severless.ts 파일로 이동하여 이 새 API 엔드 포인트를 추가하고 필요한 권한을 부여해야 합니다.


serverless.ts 파일에서 함수 섹션으로 스크롤 할 수 있습니다. 여기에서 객체에 새 함수를 추가해야 합니다.


translate: {
    handler: 'lambdas/translate.handler',
    events: [
        {
            http: {
                path: 'translate',
                method: 'POST',
                cors: true,
            },
        },
    ],
},

이 엔드 포인트와 이전 엔드 포인트의 주요 차이점은 엔드 포인트가 이제 POST 메서드라는 것입니다. 즉,이 URL 경로에 대한 GET 요청을 시도하고 수행하면 오류 응답을 받게 됩니다.


마지막으로 할 일은 람다에게 번역 서비스 사용 권한을 부여하는 것입니다. 거의 모든 AWS 서비스에서 람다 내에서를 사용할 수 있도록 추가 권한을 추가해야 합니다.


이를 위해 iamRoleStatements라는 공급자 섹션에 새 필드를 추가합니다. 이는 다양한 서비스 및 리소스에 대한 허용 또는 거부 문 배열입니다.


iamRoleStatements: [
    {
        Effect: 'Allow',
        Action: ['translate:*'],
        Resource: '*',
    },
],

이 기능이 추가되면 sls deploy를 실행하여 새 API를 배포 할 수 있도록 필요한 모든 것을 설정할 수 있습니다.


이것이 배포되면 API URL을 얻고 postman 또는 postwoman.io와 같은 도구를 사용하여 해당 URL에 대한 요청을 할 수 있습니다. 다음의 본문 만 전달하면 됩니다.


{
    "text": "This is a test message for translation",
    "language": "fr"
}

그런 다음 200 개의 응답을 받아야 합니다.


{
  "translatedMessage": {
    "TranslatedText": "Ceci est un message de test pour la traduction",
    "SourceLanguageCode": "en",
    "TargetLanguageCode": "fr"
  }
}

요약 


이 기사에서는 다음과 같은 방법을 배웠습니다.


  • severless create --template aws-nodejs-typescript를 사용하여 새 TypeScript 리포지토리 설정
  • 엄선 된 하드 코딩 된 데이터를 반환하는 자체 Lambda 추가
  • 해당 Lambda를 API 엔드 포인트로 추가
  • 전달 된 모든 텍스트를 자동으로 번역하는 또 다른 Lambda를 추가했습니다.
  • API 엔드 포인트를 추가하고 Lambda에 작업에 필요한 권한을 부여했습니다.


이 기사를 즐겼고 서버리스와 AWS에 대해 더 자세히 알고 싶다면 이 모든 것에 대한 50 개 이상의 비디오가 있는 Youtube 채널이 있습니다. 내 서버리스 및 AWS 재생 목록에서 가장 흥미로운 동영상을 시청하는 것이 좋습니다.



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.