본문 바로가기
국회도서관 자료검색 서비스

vue axios 로 외부 API 호출 응답 받기, vue cli 환경변수 env 세팅 #16

by 유니네 라이브러리 2024. 8. 21.

Axios 란

node.js 와 브라우저를 위한 Promise 기반 HTTP 클라이언트 라이브러리

☞ 보다 자세한 정보는 아래 링크 참고

https://axios-http.com/kr/docs/intro

 

이번에는 국회도서관 자료검색 리스트 페이지를 개발하면서

이전에 개발했던 django API 서버와 HTTP 통신하는 로직을 개발해 본다.

 

Axios 설치

외부 연계를 위한 HTTP 클라이언트 라이브러리 설치

  • pubdweb 디렉터리로 이동한다.
  • npm install axios으로 설치한다.
pubdweb % npm install axios
pubdweb %

 

☞ 소스 개발순서는 이전 글 참고

https://yuneenelife.tistory.com/entry/vue-v-router-통해-타-페이지-호출-방법-및-데이터-전달-방법-15

 

vue v-router 통해 타 페이지 호출 방법 및 데이터 전달 방법 #15

v-router로 타 페이지 호출하고, 데이터를 전달하는 방법은국회도서관 자료검색 화면을 개발하면서 적용한다.vue cli 로 화면을 개발하기 위해 먼저 개발 순서를 정하고, 이후 하나씩 개발하면서 v-r

yuneenelife.tistory.com

  • .env
    • 외부 호출 URL 및 키를 관리하기 위해 환경변수 사용
      • 중앙에서 관리할 수 있고, 개발/테스트/운영 환경에 따라 다르게 설정할 수 있기 때문
      • vue cli 는 환경변수 관리를 쉽게 할 수 있도록 .env 파일을 지원한다.
    • root 디렉터리에 파일명을. env로 생성
    • api url 들을 모아놓는 환경변수 파일 용도
    • 변수명은 VUE_APP_ 으로 시작해야 환경변수로 인식된다.
    • 환경변수는 작성 후, npm run serve 로 재빌드해야 인식된다.
VUE_APP_NANET_API_URL=http://localhost:4000/api/pubd/nanet_main/
  • ./assets/api.js
    • axios 모듈로 api 통신 로직 모음 파일
    • async, await 사용하여 javascript 비동기 처리 적용
    • url 은 환경 변수에서 불러옴
      • process.env.VUE_APP_NANET_API_URL
// src/api.js
import axios from 'axios';
var api_res = [];

export default {
    async getNanetAPI(param) {
        //console.log("process.env.VUE_APP_NANET_API_URL :",process.env.VUE_APP_NANET_API_URL);
        await axios.get(process.env.VUE_APP_NANET_API_URL, {
            params: {
                search: param.search,
                pageno: param.pageno,
                displaylines: param.displaylines
            },
        })
        .then(response => {      
            //console.log("api_response:", response);      
            api_res = response.data.response.recode.map((items) => {
                return {
                    item: items.item
                }
            });
        })
        //console.log("api_res:", api_res);        
        return api_res;
    },
};
  • ./pages/ResultList.vue
    • 검색결과 리스트
    • 페이지 오픈되면 실행되는 create() 모듈에서 CallThisApi() 호출
      • created : 컴포넌트 렌더링 될 때 mounted 보다 먼저 호출된다.
    • props 로 넘어온 파라미터 처리
      • 파라미터 명은 넘긴 변수명과 동일하게 작성
    • 외부 연계 호출 / 응답
      • CallThisApi() : API 호출 / 응답
      • async, await 사용하여 javascript 비동기 처리 적용
      • try catch 문으로 api 호출 error 대응
    • 응답 데이터로 리스트 노출
      • this.api_list 변수로 API response 값 리턴 받음
    • 상세페이지 components 적용
      • 파라미터 적용 : items = “items”
      • modalCheck 변수로 components의 v-show 설정
<template>
    <div>
        <br>
        <h2><p v-bind:align="myCenter">검색 결과</p></h2>  
        <template>
            <table >
                <thead>
                    <tr>
                        <th v-bind:align="myCenter">제어번호</th>
                        <th v-bind:align="myCenter">자료명</th>
                        <th v-bind:align="myCenter">저자명</th>
                        <th v-bind:align="myCenter">발행자</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(items, i) in this.api_list" :key="i">                    
                        <td>
                            <a v-on:click="goDtl(items.item)" class="underline"> {{ items.item[0].value }} </a>
                        </td>
                        <td>
                            {{ items.item[1].value }}
                        </td>
                        <td>
                            {{ items.item[2].value }}
                        </td>                    
                        <td>
                            {{ items.item[3].value }}
                        </td> 
                    </tr>
                </tbody>
            </table> 
        </template>       
        <p v-bind:align="myCenter">
            <a class="underline" v-on:click="goNext(-1)"><b>이전</b></a>            
            &nbsp;&nbsp;
            <a class="underline" v-on:click="goMain"><b>Main</b></a>
            &nbsp;&nbsp;
            <a class="underline" v-on:click="goNext(1)"><b>다음</b></a>
        </p>
        <rDtl v-show="modalCheck" :items="items" @childClose="modalClose"></rDtl>
        <br>        
    </div>

</template>
<script>
import router from '../assets/index'
import rDtl from './ResultDtl'
import api from '../assets/api'

var param = {
    search: '',
    pageno: '',
    displaylines: '',
};

export default {
    data: () => ({
        myCenter: 'center',        
        api_list: [], 
        myVisible: false,
        items: [],  
        modalCheck: false,
        pageNo: 1,
        displayNum: 10,        
    }),
    components: {        
        rDtl
    },   
    props: {
        srhs: {
            type: String,
            required: true,
            default: '',
        }        
    },
    created() {
        //console.log("parameter :", this.srhs)
        this.CallThisApi();
    },
    methods: {
        async CallThisApi() {
            //console.log("start CallThisApi :");
            param.search = "자료명,"+this.srhs;
            param.pageno = this.pageNo;
            param.displaylines = this.displayNum;
            //console.log("object param :", param);
            try {
                this.api_list = await api.getNanetAPI(param);
                //console.log("this.api_list :", this.api_list);    
            } catch (error) {
                console.error('API 호출 에러:', error);
            }
        },
        goDtl(rData) {            
            this.items = rData;
            this.modalCheck = true;            
        },
        goMain: function() {
            //console.log("srhInp :", this.srhInp);            
            router.push({               
                name: 'searchMain' 
            }).catch(() => {})
        },
        goNext(no) {
            if (no == -1) {
                if (this.pageNo < 2) {
                    alert('첫번째 페이지입니다.');
                } else {
                    this.pageNo -= 1;
                    this.CallThisApi();
                }
            } else {
                this.pageNo += 1;
                this.CallThisApi();
            }
        },
        modalClose() {
            this.modalCheck = false;
        }
    },
    
}
</script>

마무리

여기까지 vue cli 환경변수 세팅하고, axios 모듈로 외부 API 통신하는 것까지 완성되었다.

다음에는 components로 설정된 상세페이지를 모달(modal)로 팝업 되는 페이지를 만들어본다.

상세페이지는 vuetify의 data tables components를 적용한다.

 

 국회도서관 자료검색 API 호출하는 django 설치는 이전 글 참고

https://yuneenelife.tistory.com/entry/API-Server-django-python-Framework-설치-1 

 

API Server django python Framework 설치 #1

python framework 인 django를 이용해서 API Server를 구축한다.API는 공공데이터 포털에서 제공하는 국회 도서관 자료검색 서비스를 이용한다. 먼저 작업을 시작하기에 앞서 작업을 진행할 폴더를 생성

yuneenelife.tistory.com

 

☞ vue, vue cli 설치는 이전 글 참고

https://yuneenelife.tistory.com/entry/vue-vue-cli-설치하고-버전-확인-12

 

vue, vue cli 설치하고 버전 확인 #12

국회도서관 자료검색 서비스를 위한 프런트엔드 웹 환경 구성작업 환경작업폴더명public_data/pubd_web프로젝트 명pubdwebOSmacOS sonoma v 14.5☞ vue cli 의 가이드는 아래 URL에서 자세히 다루고 있다.https://c

yuneenelife.tistory.com