Home 행정안전부 도로명 주소 API 연동
Post
Cancel

행정안전부 도로명 주소 API 연동

개요

메이플스토리 월드에서 크리에이터 정보 등록/수정 시 도로명 주소 검색 Open API 연동이 필요했다. 대표적으로 카카오가 해당 서비스를 제공하지만, 도로명 주소 검색 팝업 하단에 카카오 BI가 들어가고 가리지 못하는 이유로 행정안전부에서 제공하는 도로명 주소 검색 서비스를 연동했다.

행정안전부 도로명 주소 API 신청은 링크에 접속해서 신청하면 된다.

엥 JSP?

링크의 연동 가이드를 살펴보면 JSP, ASP, PHP 언어 기반으로만 설명하고 있다. 세 언어는 서버를 기반으로 동작하기 때문에 Javascript로 변환하는 과정에서 Nuxt 서버를 이용했다.

도로명 주소 API 연동 구조

행정안전부 주소 연동 구조도

코드

주소 컴포넌트 작성

주소 검색 팝업창을 띄우고, 팝업창으로부터 사용자가 선택한 주소 정보를 응답받는 컴포넌트를 작성했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<template>
  <button @click="handleClick">
    <slot />
  </button>
</template>
<script>
import { v4 as uuidv4 } from 'uuid'
 
export default {
  // ... 중략
  data() {
    return {
      uuid: uuidv4() // 컴포넌트 이벤트 식별 키
    }
  },
  mounted() {
    window.addEventListener('message', this.receiveMessage)
  },
  beforeDestroy() {
    window.removeEventListener('message', this.receiveMessage)
  },
  methods: {
    // 클릭 이벤트 발생 시 주소 검색 팝업 띄우기
    handleClick() {
      window.open(
        `/address?uuid=${this.uuid}`,
        'pop',
        'width=570,height=420, scrollbars=yes, resizable=yes'
      )
    },
    // 사용자가 검색한 주소 정보를 전달받는 함수
    receiveMessage(event) {
      // ... 중략
 
      // addressInfo 데이터 형식 https://business.juso.go.kr/addrlink/openApi/popupApi.do
      this.$emit('onChange', event.data.addressInfo)
    }
  }
}
</script>

행안부 도로명 주소 검색 화면으로 리다이렉트 되는 팝업 페이지 작성

위 주소 컴포넌트에서 오픈하는 페이지로, HTML Form을 Submit 해야 행정안전부 도로명 주소 검색 페이지로 리다이렉트 되는 구조로 되어있기 때문에 팝업용 페이지가 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<template>
  <div>
    <!-- 행안부에서 제공하는 도로명 주소 찾기 팝업형 페이지 -->
    <form
      ref="addressForm"
      method="post"
      :action="$env.apiUrl"
      name="addressForm"
    >
      <!-- 행안부 API 신청 시 발급받은 키 -->
      <input type="hidden" name="confmKey" :value="$env.apiKey" />
      <!-- 사용자가 주소 검색을 완료 했을 때 데이터를 요청받을 Nuxt Server API 경로 -->
      <input
        type="hidden"
        name="returnUrl"
        :value="`${$env.baseURL}/api/address-handler?uuid=${uuid}`"
      />
      <input type="hidden" name="resultType" value="4" />
    </form>
  </div>
</template>
<script>
export default {
  // ... 중략
  computed: {
    uuid() {
      return this.$route.query.uuid
    }
  },
  mounted() {
    // 로드 후 바로 Form Submit (행안부에서 제공하는 팝업형 페이지로 파라미터 전송 및 리다이렉트)
    this.$refs.addressForm.submit()
  }
}
</script>

Nuxt 주소 핸들러 API 작성

사용자가 행정안전부 도로명 주소 검색 팝업창에서 검색을 완료할 때 해당 데이터를 전달받는 Nuxt API가 필요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 행정안전부 주소 팝업에서 전달된 주소를 처리하는 미들웨어
export default function (req, res, next) {
  // ... 중략 

  let body = ''
  req.on('data', (chunk) => {
    body += chunk.toString()
  })
  req.on('end', () => {
    const params = new URLSearchParams(body)
    const parsed = Object.fromEntries(params.entries())
    const baseURL = process.env.BASE_URL
 
    // 팝업 페이지를 오픈한 부모 페이지(= 주소 컴포넌트)에 사용자가 선택한 주소 정보를 전달하는 HTML 응답
    const html = `
    <html>
      <head>
        <meta charset="UTF-8">
        <script>
          window.onload= function() {
            window.opener.postMessage({
              action: 'address',
              uuid: '${query.uuid}',
              addressInfo: ${JSON.stringify(parsed)}
            }, '${baseURL}')
            window.close()
          }
        </script>
      </head>
      <body></body>
    </html>
    `
    res.end(html)
  })
}

사용하기

행정안전부 주소 연동 사용 1
행정안전부 주소 연동 사용 2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<template>
  <!-- ... 중략 -->
  <v-input v-model="address">
  <template #prepend>
    <v-address @onChange="handleChangeAddress">
      <v-icon icon="search" />
      </v-address>
    </template>
  </v-input>
</template>
<script>
export default {
  // ... 중략
  methods: {
    handleChangeAddress({ roadAddrPart1, addrDetail, sggNm, zipNo }) {
      this.address = roadAddrPart1
      this.addressDetail = addrDetail
      this.city = sggNm
      this.zipCode = zipNo
    }
  }
}
</script>

끄적끄적

행안부 도로명 주소 연동 시 팝업형/검색형 API가 있는데, 검색형 API를 사용할 때 address-handler와 같은 API는 필요하지 않지만, 자동 완성 기능, 에러 핸들링을 직접 구현해야하는 부담이 있어 팝업형 API를 사용했다.

리팩터링 조건부 로직을 다형성으로 바꾸기

-