amplify를 활용한 인증/미인증/cdn api를 백엔드/클라이언트에서 공유하기위함
- rest api 지원
- react 지원
- react-native 지원
- vue.js 지원
- gatsby.JS 지원
- next.js(테스트중)
- v3.0.1
라이브러리 최신화 제거된 기능 제거
- v1.0.65
loadingCallback의 null 허용
로딩 처리는 react-query 사용 권장
- v1.0.58
아래 부분 참고
-
api default 옵션 관련 작업 로딩
-
api 재시도 기능 추가
-
v1.0.51
appsync 에러 처리
try {
var textSample = {
type: "TEXT", //"IMAGE" , "SYSTEM", "MOVIE"
text: newMessages[0].text,
};
var data = await Api.graphql(
{
query: mutations.createChatMessage,
variables: {
input: {
chat_room_no: chat_room_no,
chat_message_type_code_id: "DEFAULT",
chat_message_content: JSON.stringify(textSample),
},
},
},
{
// fetchPolicy: "cache-only",
},
(flag) => {
console.log(flag);
}
);
} catch (error) {
console.log("log -> ------------------------------");
console.log("log -> ~ testFunction ~ error", { error });
console.log("log -> ~ testFunction ~ error", error.response);
console.log("log -> ------------------------------");
}
/*
log -> ~ testFunction ~ error [
{
"path": [
"data"
],
"data": null,
"errorType": "INCLUDE_CHAT_BAN_WORD",
"errorInfo": [
{
"errorType": "INCLUDE_CHAT_BAN_WORD",
"message": "금칙어가 포함되어 있습니다."
}
],
"locations": [
{
"line": 2,
"column": 3,
"sourceName": null
}
],
"message": "금칙어가 포함되어 있습니다."
}
]
*/
- v1.0.46
appsync 사용 예시
/src/graphql/subscriptions.js 예시
구독 기능 설명 추가
각 프로젝트의 개발 환경에 맞는 aws-exports.js 요청
React- native는
<project root>/aws-exports.js
web/cms은
<project root>/src/aws-exports.js
yarn add @psyrenpark/auth
yarn add @psyrenpark/api
yarn add @psyrenpark/storage
yarn add amazon-cognito-identity-js
yarn add aws-amplify
// react-native 추가 설치
yarn add @react-native-community/netinfo
새버전 공지시 npm에 맞는것 재설치
yarn add @psyrenpark/auth
yarn add @psyrenpark/api
yarn add @psyrenpark/storage
- 이후 최신버전으로 변경되었는지 확인할것.
//--------------------------------------------------
// 각 프로젝트 루트
import { Auth } from "@psyrenpark/auth";
import { Api } from "@psyrenpark/api";
import { Storage } from "@psyrenpark/storage";
import awsmobile from "./aws-exports";
Auth.setConfigure(awsmobile);
Api.setConfigure(awsmobile);
Storage.setConfigure(awsmobile);
//--------------------------------------------------
// 혹 import가 지원 되지 않는 javascript 버전에서 사용시
// aws-exports
// export default awsmobile;
module.exports = awsmobile; // 로 변경
// 각 프로젝트 루트
const { apiObject } = require("./api");
const { Api } = require("@psyrenpark/api");
const { Auth, AuthType } = require("@psyrenpark/auth");
const { Storage } = require("@psyrenpark/storage");
const awsmobile = require("./aws-exports");
Auth.setConfigure(awsmobile);
Api.setConfigure(awsmobile);
Storage.setConfigure(awsmobile);
로딩에 대한 불편함을 해결하기위해 콜백형식의 함수를 주입가능하도록 되어있음
// 아래 auth 함수가 실행될때 로딩함수를 넣으면
// 시작시 isLoading => true
// 종료시 isLoading => false
// 로 주입한 함수가 호출됨
const loadingFunction = (isLoading) => {
dispatch({ type: "SET_IS_LOADING", payload: isLoading });
// or
setIsLoading(isLoading);
};
- api들 모아 놓은 object
- 여기에 모든 api들을 함수화 한다.
- 로그인이 필요없이 사용가능한 noneauth 버전
- 일반적인 로그인 필요 api 인 api 버전
- 속도향상을 위해 캐싱된 api은 cdn 버전
- 서버 개발자는 테스트를 위해 이를 작성하여 테스트후 공유한다.
- 백엔드와 별도의 테스트가 필요하다면 아래 [테스트 필요시] 참고할것
//--------------------------------------
// api/index.js
import { Api } from "@psyrenpark/api";
const projectName = "ll"; // 각 프로젝트 단축명
const cognitoType = "admin"; // 코그티노 종류 // admin, cust
const projectEnv = "prod"; // 각 프로젝트 환경 // dev, test, prod
const v1Api = `${projectName}${cognitoType}-${projectEnv}-api-v1`;
const v1Cdn = `${projectName}${cognitoType}-${projectEnv}-cdn-v1`;
const v1NoneAuth = `${projectName}${cognitoType}-${projectEnv}-noneauth-v1`;
const v1Cms = `${projectName}${cognitoType}-${projectEnv}-cms-v1`;
export const apiObject = {
//------------------------------------------
// 인증 없는 api
/**
* [] cdn 테스트
* @param {string} langCode - 예시 언어코드
* @param {Function} LoadingCallback - 로딩 콜백
*/
getTestNoneauth: (
{
langCode, //
// 필요에 맞게 파라미터를 넣는다.
// ...
},
loadingFunction,
) => {
var apiName = v1Noneauth; // 인증 유, 인증 무 api 구분은 이부분이 다르다.
var path = "/test_test_test"; // test_test_test는 무조건 테스트 api로써 반드시 작동한다.
var myInit = {
headers: {}, // OPTIONAL
// body: { // post나 put일경우 사용한다.
//
// },
queryStringParameters: {
langCode: langCode,
},
// response: true, // axios 원형 response 필요할 경우 ture로 설정한다.
};
// get, post, put, del 상황에 맞게 사용한다
return Api.get(apiName, path, myInit, loadingFunction);
},
//------------------------------------------
// 인증 있는 api
getTestApi: (
{
langCode,
// ...
// 필요에 맞게 파라미터를 넣는다.
},
loadingFunction,
) => {
var apiName = v1Api; // 인증 유, 인증 무 api 구분은 이부분이 다르다.
var path = "/test_test_test";
var myInit = {
headers: {}, // OPTIONAL
// body: { // post나 put일경우 사용한다.
//
// },
queryStringParameters: {
langCode: langCode,
},
// response: true, // axios 원형 response 필요할 경우 ture로 설정한다.
};
// get, post, put, del 상황에 맞게 사용한다
return Api.get(apiName, path, myInit, loadingFunction);
},
//------------------------------------------
// 개발계에 테스트시 (디폴트 계정으로만 테스트 가능)
getTestCdn: (
{
langCode,
// ...
// 필요에 맞게 파라미터를 넣는다.
},
loadingFunction,
) => {
var apiName = v1Cdn; // 인증 유, 인증 무 api 구분은 이부분이 다르다.
var path = "/test_test_test";
var myInit = {
headers: {}, // OPTIONAL
// body: { // post나 put일경우 사용한다.
//
// },
queryStringParameters: {
langCode: langCode,
},
// response: true, // axios 원형 response 필요할 경우 ture로 설정한다.
};
// 테스트 필요시
// 테스트가 필요할경우 로딩콜백 뒤에 {url, port}를 추가한다. // 백엔드 개발자에게 테스트 요청
// get, post, put, del 상황에 맞게 사용한다
return Api.get(apiName, path, myInit, LoadingCallback, {
url: "http://18.177.73.12",
port: 3006,
});
// return Api.get(apiName, path, myInit, loadingFunction);
},
};
- jsx에서 버튼클릭등 에서 사용
//--------------------------------------
// api/index.js
//--------------------------------------
// api 호출
// 특정 버튼 클릭등 에서 아래 함수 호출
import React from "react";
import { apiObject } from "../../api";
export const TestComponent = (props) => {
const testApiFunction = async () => {
try {
var userData = await apiObject.getTestCdn(
{
langCode: "ko",
},
loadingFunction,
);
} catch (error) {
if (error.response) {
// Request made and server responded
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// The request was made but no response was received
console.log(error.request);
} else {
// Something happened in setting up the request that triggered an Error
console.log("Error", error.message);
}
}
};
return (
<div>
<button onClick={testApiFunction}>테스트</button>
</div>
);
};
- 구독
//--------------------------------------
// appsync를 사용하여 실시간 데이터 관련
// 아래 3파일은 서버 담당자가 제공
// /src/graphql/queries.js
// /src/graphql/mutations.js
// /src/graphql/subscriptions.js
//--------------------------------------
// /src/graphql/subscriptions.js 예시
//--------------------------------------
import gql from "graphql-tag";
export const onCreateCpMsg = gql`
subscription onCreateCpMsg($pk: String!) {
data: onCreateCpMsg(pk: $pk) {
pk
sk
dt
msg_type
info
}
}
`;
//--------------------------------------
// 구독 관련 샘플
//--------------------------------------
import { API, graphqlOperation } from "aws-amplify";
import * as subscriptions from "../graphql/subscriptions";
import * as mutations from "../graphql/mutations";
import * as queries from "../graphql/queries";
let subscribeRef = null;
const subscribe_key = "cust_20210402000333";
const Main = (props) => {
const setMessage = async (data) => {
console.log("log -> --------------------------");
console.log("log -> ~ Main ~ data", data);
console.log("log -> --------------------------");
};
const appSyncInit = () => {
if (subscribeRef) {
return;
}
subscribeRef = API.graphql(
graphqlOperation(subscriptions.onCreateCpMsg, {
pk: subscribe_key,
}),
).subscribe({
next: (data) => setChatMessage(data.value.data.data),
});
};
const appSyncRelease = () => {
if (subscribeRef) {
subscribeRef.unsubscribe();
subscribeRef = null;
}
};
useEffect(() => {
appSyncInit();
return () => {
appSyncRelease();
};
}, []);
return {};
};
- 아래 코드를 사용시 모든 Api 에서 로딩, 재시도를 세팅가능
// 각 프로젝트 에서 한번만
import { Api } from "@psyrenpark/api";
Api.setApiClassValue({
loadingCallback: (flag) => { console.log("loading : ", flag ) }
retries: 0
});
- 에러시 재시도
var apiName = v1Cdn; // 인증 유, 인증 무 api 구분은 이부분이 다르다.
var path = "/test_test_test";
var myInit = {
headers: {}, // OPTIONAL
// body: { // post나 put일경우 사용한다.
//
// },
queryStringParameters: {
langCode: langCode,
},
// response: true, // axios 원형 response 필요할 경우 ture로 설정한다.
};
// 마지막 파라미터 에 재시도할 카운트 넣을것
return Api.get(apiName, path, myInit, LoadingCallback, null, 3);