Language/Typescript

API 응답 데이터의 타입

kimjingyu 2023. 5. 12. 20:13
728x90

🆚 rest-api vs graphql

  • rest-api: 타입스크립트를 적용하게 되면 수동으로 만들어줘야 한다.
  • graphql: graphql-codegen을 이용해 명령어 하나로 만들어준다.

📌 graphql-codegen 세팅

  1. graphql-codegen 사이트에 접속하여 installation 명령어 복사 후 실행
    • yarn add -D @graphql-codegen/cli
    • yarn add -D @graphql-codegen/typescript
  2. codegen.yml 파일 추가
    • schema: graphql 주소
       generates:
        ./src/commons/types/generated/types.ts:
       plugins:
        - typescript
       config:
        typesPrefix: I
    • 명령어로 codegen을 실행시키면, 스키마의 주소로 들어가 api들의 타입을 /src/commons/types/generated/types.ts 에 다운받는다.
  3. package.json 파일의 scripts 객체에 "generate": "graphql-codegen" 을 추가
  4. yarn generate 명령을 실행하면, Backend 컴퓨터에 접속하여 Graphql-API로 받아오는 모든 데이터의 타입을 조사해서 이와 일치하는 타입스크립트 파일을 ./src/commons/types/generated/types.ts 위치에 자동으로 만들어 준다.

💻  graphql에 codegen 적용

  • 처음에는 variables로 무엇을 보내줄지와 응답으로 무엇을 받아올지 잘 모른다.
  • 그래서 처음에 data로 받아올 때, 타입으로 any를 적었다.
  • 하지만 codegen을 사용하면서 graphql의 타입을 모두 다운받았고, 다운 받아온 타입 중에서 맞는 것을 뽑아 적어주면 된다.
export type IQuery = {
  __typename?: 'Query';
  fetchBoard: IBoard;
  fetchBoardComments: Array<IBoardComment>;
  fetchBoards: Array<IBoard>;
  fetchBoardsCount: Scalars['Int'];
  fetchBoardsCountOfMine: Scalars['Int'];
  fetchBoardsOfMine: Array<IBoard>;
  fetchBoardsOfTheBest: Array<IBoard>;
  fetchPointTransactions: Array<IPointTransaction>;
  fetchPointTransactionsCountOfBuying: Scalars['Int'];
  fetchPointTransactionsCountOfLoading: Scalars['Int'];
  fetchPointTransactionsCountOfSelling: Scalars['Int'];
  fetchPointTransactionsOfBuying: Array<IPointTransaction>;
  fetchPointTransactionsOfLoading: Array<IPointTransaction>;
  fetchPointTransactionsOfSelling: Array<IPointTransaction>;
  fetchUseditem: IUseditem;
  fetchUseditemQuestionAnswers: Array<IUseditemQuestionAnswer>;
  fetchUseditemQuestions: Array<IUseditemQuestion>;
  fetchUseditems: Array<IUseditem>;
  fetchUseditemsCountIBought: Scalars['Int'];
  fetchUseditemsCountIPicked: Scalars['Int'];
  fetchUseditemsCountISold: Scalars['Int'];
  fetchUseditemsIBought: Array<IUseditem>;
  fetchUseditemsIPicked: Array<IUseditem>;
  fetchUseditemsISold: Array<IUseditem>;
  fetchUseditemsOfTheBest: Array<IUseditem>;
  fetchUserLoggedIn: IUser;
};
export type IMutation = {
  __typename?: 'Mutation';
  createBoard: IBoard;
  createBoardComment: IBoardComment;
  createPointTransactionOfBuyingAndSelling: IUseditem;
  createPointTransactionOfLoading: IPointTransaction;
  createUseditem: IUseditem;
  createUseditemQuestion: IUseditemQuestion;
  createUseditemQuestionAnswer: IUseditemQuestionAnswer;
  createUser: IUser;
  deleteBoard: Scalars['ID'];
  deleteBoardComment: Scalars['ID'];
  deleteBoards: Array<Scalars['ID']>;
  deleteUseditem: Scalars['ID'];
  deleteUseditemQuestion: Scalars['ID'];
  deleteUseditemQuestionAnswer: Scalars['String'];
  dislikeBoard: Scalars['Int'];
  likeBoard: Scalars['Int'];
  loginUser: IToken;
  loginUserExample: IToken;
  logoutUser: Scalars['Boolean'];
  resetUserPassword: Scalars['Boolean'];
  restoreAccessToken: IToken;
  toggleUseditemPick: Scalars['Int'];
  updateBoard: IBoard;
  updateBoardComment: IBoardComment;
  updateUseditem: IUseditem;
  updateUseditemQuestion: IUseditemQuestion;
  updateUseditemQuestionAnswer: IUseditemQuestionAnswer;
  updateUser: IUser;
  uploadFile: IFileManager;
};
  • 응답 타입과 variables 타입은 타입 파일에 다운로드 되어있고, 맞는 것으로 import 해서 주입시켜주면 된다.
const [myFunction] = useMutation<응답 타입, variables 타입>()

mutation에 타입스크립트 적용

  • 다운로드된 타입들 중 맞는 타입을 데리고 올때는 Pick을 사용하여 해당 타입을 import 해와야 한다.
  • 예시로 타입 파일에서 Mutation과 MutationCreateBoardArgs를 import하고, Mutation 중에서 createBoard를 Pick 해오는 상황은 아래와 같다.
const [myFunction] = useMutation<Pick<IMutation, "createBoard">, IMutationCreateBoardArgs>(CREATE_BOARD)

const z = async() => {
	const result = await myFunction(CREATE_BOARD)
    console.log(result.data?.createBoard?.message)
}

query에 타입스크립트 적용

const { data } = useQuery<Pick<IQuery, "fetchBoard">, IQueryFetchBoardArgs>(FETCH_BOARD, {
	variables: {number: Number(router.query.myNumber)}
})
728x90