카테고리 없음

[vanilla+typescript]API 서비스 함수 작성

ehddkDEV 2024. 8. 23. 16:20

공공데이터에서 제공하는 미세먼지 api를 호출하여 미세먼지 데이터를 화면에 뿌려줄 것이다.

일단 그럼 서비스함수, 인스턴스를 생성해보자.

 

이뤄지는 과정

요청 타입 정의
응답 타입 정의
서비스 함수 정의
해당 ts 파일로 와서 요청하기

 

 

우선 api 호출을 했을때 응답값이 잘 반환이 되는지 postman으로 확인해보는 것이 좋다!

이렇게  params에 필수 요청 파라미터를 담아서  url로 get 요청을 한다.

 

그럼 성공적으로 이렇게 응답값이 json형식으로 받아와지는 걸 확인 할 수 있다.

이때 내가 returnType을 json으로 했기에 이렇게 나온다.

여기서 난 infromCause,informOverall만 추출할것이다.

 

일단 그럼 요청타입을 먼저 정의해보자!

1. dust.type.ts란 파일 생성

요청시에는 필수적으로 params,Path,body 이 3가지가 들어가야 한다.

 

getDustRequestParams에는 내가 요청할때 넣어야 할 기본적인 요청 파라미터가 들어가야 하는 것이다.

내가 postman에서도 serviceKey,returnType,numOfRows,pageNo---등등을 넣었듯이!

 

export type getDustRequestParams={
  returnType: string,
    numOfRows:number,
    pageNo:number,
    searchDate:string,
    InformCode: string
 }

해당 파라미터 옆에는 타입명을 꼭 명시해줘야 한다.

 

getDustRequestPath, getRequestBody도!

export type getDustRequestPath={}
export type getDustRequestBody={}

 

 

그럼 이제 요청 타입을 명시

export type getDustRequest={
    params:getDustRequestParams,
    body?:getDustRequestBody,
    path?:getDustRequestPath
}

이때 ?란 -> 옵셔널 체이닝으로 뒤에 값이 만약 없으면 생략 가능함을 의미한다. 

params는 우리가 요청해야할 파라미터가 명시되어 있으니까 꼭 넣줘야 하기에 ?가 들어가지 않는다.

 

이때 내가 postman에서는 테스트해보느라 직접 url에 서비스키를 넣었지만 , 이러면 url에 노출되는 것이기에 탈취위험이 있다.

따라서 요청 파라미터에는 serviceKey를 따로 명시하지 않는다.

 

그다음, 이젠 미세먼지 조회 응답 타입을 정의해야한다.

해당 데이터를 어떻게 받아올 것 인지를 !

난 infromCause,informOverall만 가져올것이기에 

export type getDustResponse={
    response:{
        body:{
            items:Array<{
                /** 발생원인 */
                informCause:string,
                /**예보 예상 */
                informOverall:string,
            }>
        }
    }
}

이런식으로 명시한다.

postman 응답데이터에서 봤듯이 items가 현재 배열로 되어있기에 Array<{}> 라고 명시해줘야 한다!

처음에 무턱대고 객체로 받아왔다가 왜 데이터가 안 불러오지..? 헤맸던 ^^ 🥹

 

타입을 다 정의했으면 이제 서비스 함수를 생성하자!

 

dustService란 class 생성을 하여 getDust라는  메소드를 정의한다. 이때 메소드명은 직관적,내 마음대로!

이 함수는 요청 파라미터를 통해 미세먼지 정보를 가져오는 역할을 한다.

내가 dust.type.ts에서 정의한 getDustRequest 타입의 req 객체를 받아오면, 이 객체에는 내가 요청할 때 필요한

파라미터가 들어있다.(returnType,numOfRows 등등)

 

export class DustService{
    async getDust(req: getDustRequest) {
       const {params} = req;
    }
}

그럼 객체 구조 분해 할당으로 params를 꺼내온다.

미세먼지 API의 기본 URL이자 실제 API의 엔드포인트를 선언해줘야 한다. 이 url로부터 데이터를 전달 받 을 수 있는 거니까!

 

        const url = new URL(`http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMinuDustFrcstDspth?`);

이건 고유 url인데 만약 공통적으로 쓰이는 url이면 변수처리도 가능하다.

 

이 url 뒤에 덧붙여야할 내용은 우리가 요청한 파라미터들, 앞에서 내가 따로 params에 넣지 않은 serviceKey다.

이때 Object.entries() 메서드를 사용해 해당 객체의 [key, value] 쌍의 배열을 반환할 수 있다.

자바스크립트 객체를 배열로 변환해주는 메소드로 이를 이용해 우리가 받아야할 응답 데이터에서 items가 배열로 되어있으니까 

객체 형태인 요청한 params를 배열로 바꿔줘야지! 

 

postman으로 test했듯이 원래 url 형태는 다음과 같이 ? 뒤에 쿼리 파라미터가 붙는다.

http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getMinuDustFrcstDspth?serviceKey=인증키&returnType=json&numOfRows=100&pageNo=1&searchDate=2024-08-22&InformCode=PM10

기존 params 객체에 serviceKey를 덧붙여야 하니까

스프레드 연산자를 사용하고, url 객체에 forEach를 사용해 searchParams로 각 파라미터를 추가한다.

 

 

Object.entries({
  ...params,
  serviceKey:decodeURIComponent(API_KEY),
 }).forEach(([key, value]) => {
            url.searchParams.append(key, value.toString());
 });

이때 forEach는 map 과 다르게 어떤 값을 반환하지 않고 순회만 한다.따라서 내부적으로 순서를 보장하지 않는다.

 

이때 searchParams 객체는 쿼리 스트링의 매개변수를 읽거나 쓸 수 있도록 해준다.

append() 메서드를 이용하여 파라미터를 하나씩 추가하여 기존 url뒤에 value값이 추가되는 것이다!

 

그다음 fetch() 를 이용하면 url을 통해 원하는 API의 결과값을 받아오면 된다.

const res = await fetch(url);
const data = (await res.json()) as getDustResponse;
      
return data;

dust.type.ts에서 정의한 getDustReponse객체로부터 .json() 메서드로 파싱한 json 값을 리턴받아 data에 담은다음 return!

 

이러면 서비스 함수 생성 끝!

이제 main.ts파일(실제 html에 보이는)에서 함수를 호출해서 화면에 뿌려보자

 미세먼지 데이터이니까 dust.ts라는 파일에 작업하겠다!

 

우선 앞에서 class로 정의한 DustService를 import해서 getDust 메소드에 있는 params에 

요청 파라미터를 명시한다.

dust.type.ts에서 내가 getDustRequestParams에 returnType,numOfRows,pageNo ---등등을 요청한다고 명시했으니까!

const dustService= new DustService();
const today_date = new Date(); //오늘 날짜,시간 나옴.

const dustData=await dustService.getDust({
    params:{
        returnType: 'json',
        numOfRows:100,
        pageNo:1,
        searchDate:today_date,
        InformCode: 'PM10'
    }
})

console.log(dustData);

 

console 확인해보면 

이렇게 데이터가 잘 불러와진다!