본문 바로가기
  • Seizure But Okay Developer
강의 | 대외활동 | 개인플젝/마스크 재고 관리_개인플젝

마스크 재고 관리 프로젝트 - 1

by Sky_Developer 2020. 3. 27.

개요

바이러스가 만연한 현재에 개발자로써 주변사람들을 도울 수 있는 방법이 없을까 고민을 하다가, 마스크 재고를 알려주는 사이트를 만들어야 겠다 결심하고 시작한 끝에 완성을 하였습니다.

 

완성해가는 과정에서 생각보다 많은 것을 얻을 수 있었고 배운 점을 잘 정리하면 사이드 프로젝트를 시작하는 분들께도 도움이 되고 저 나름 정리하는것 또한 학습차원에서 좋을 것 같아 글을 작성하였습니다. 점점 더 사회에 도움을 주는 개발자분들의 능력이 발휘되길 기원합니다.

 

프로젝트 글은 총 5편으로 나뉘어 작성될 예정이며 각 글은 자료조사, 프론트엔드, 서버세팅에 대한 내용을 담습니다.

 

목차

  • 들어가기 앞서
  • 자료조사
    • 공공 데이터 포털(마스크 판매 정보) 
    • Geolocation API
    • Permission API

 

들어가기 앞서

어느 날 마스크를 구하기 위해 줄을 서는데 무려 1시간씩이나 줄을 기다렸다. 요일제를 도입된지 2주가 되었는데도 여전히 마스크를 구하기 힘들었다. 또 막상 약국마다 파는 시간이 다른 곳도 있었지만 어느 약국에 재고가 있는지 파악하는 것 또한 직접 발품을 팔아야 해서 힘들었다.

 

정부가 공공 API를 제공한지 1달 가까이 지났는데도 이런 불편함을 해소해주는 프로그램이 없는 것이 아이러니하게 느껴졌고, 집에 오는 길에서 '내가 직접 마스크 재고를 알려주는 프로그램을 만들면 어떨까?' 라는 작은 동기가 생겼다.

( 지금에서야 마스크 재고를 알려주는 많은 좋은 프로그램이 있었다는 것을 알게 되었지만, 당시 프로젝트를 시작할 때는 정말 마스크 재고만을 간편하게 보여주는 서비스가 없다는 느낌이었다 )

 

내가 알고 있는 지식들로 사람들에게 도움을 줄 수 있다면 정말 의미가 깊을 것 같다는 생각이 들어 프로젝트를 시작하였다.

 

자료조사

먼저 마스크 재고 API를 제공하는 공공 데이터 포털로 들어가서 사용법을 확인했다. 사용법은 간단하게도 GET 메소드로 요청을 하면 XML 또는 JSON 형식으로 반환해주는 식이었다. 총 4 종류의 API가 있었다.

  • Query String에 파라미터를 넣으면 그에 맞는 판매처 데이터를 반환

결론 : 위도, 경도, 반경을 파라미터로 넣어주면 그에 맞는 판매처 목록을 반환해주는 API를 사용하기로 결정

이유 : 자기 위치를 기준으로 약국이나 판매처의 현황을 알 수 있으면 유용하다고 판단

 

공공 데이터 포털(마스크 판매 정보)

https://www.data.go.kr/dataset/15043025/openapi.do

 

공공데이터포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Dataset)와 Open API로 제공하는 사이트입니다.

www.data.go.kr

 

API를 swagger 로 정리한 링크도 제공되어 있어 확인하기 편했음

https://app.swaggerhub.com/apis-docs/Promptech/public-mask-info/20200307-oas3#/

 

 

사용자 위치 정보 얻기

약국 정보를 받아오기 위해 Javascript로 사용자 위치 정보를 얻을 수 있는지 MDN을 찾아보니 Geolocation API가 존재했다.

Geolocation API

개념

  • 필요시 웹 애플리케이션에 사용자의 위치 정보를 제공할 수 있는 API.
  • 개인정보 보호를 위해, 브라우저는 위치 정보를 제공하기 전에 사용자에게 위치 정보 권한에 대한 허락을 받음.
  • 이 기능은 몇몇 혹은 모든 브라우저의 보안 컨텍스트(HTTPS)에서만 유효함 ( 즉, 사이트가 HTTPS를 지원해야 함 )

Chrome의 경우 버전 50부터 비보안 출처(예: HTTP)에서 호스팅 될 때 사용자 위치 요청 기능이 작동하지 않음. 그러므로 프로젝트에 Geolocation API 기능을 사용하기 위해선 HTTPS를 꼭 지원해야 함.

(https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only)

 

로컬에서 Geolocation API를 테스트하면 사용할 때마다 매번 권한을 묻는다. Origin이 null이기 때문.

이러한 권한 허용 문제가 신경쓰인다면 웹 서버를 이용하면 쉽게 해결된다. 간단하게는 http-server 모듈을 설치하거나,  parcel 번들러를 설치해서 사용하면 된다.

 

사용법  (의역 주의)

Geolocaiotn API는 navigator.geolocation을 통해 접근합니다. 이 때, 사용자의 브라우저는 위치 정보 접근 권한을 요청하게 되고 사용자가 허가할 경우 현재 장치에서 사용 가능한 최선의 방법(GPS, WiFi, ...)을 통해 위치를 알아냅니다.

 

Method

  • Geolocation.getCurrentPosition() : 장치의 현재 위치를 가져옵니다.
  • Geolocation.watchPosition() : 장치의 위치가 바뀔 때마다, 자동으로 새로운 위치를 사용해 호출할 처리 함수를 등록합니다.

각 메서드를 호출하면 사용자의 위치를 비동기식으로 보고합니다.

 

Method Parameter

두 메서드 모두 최대 세 개의 매개변수를 받습니다.

  • 성공 콜백 [필수] : 위치 정보를 가져오는데 성공하면 호출되며 위치 데이터가 담긴 GeolocationPosition 객체가 매개변수로 넘겨집니다.
  • 실패 콜백 [선택] : 위치 정보를 가져오지 못하면 호출되며 실패 원인을 담은 GeolocationPositionError 객체가 매개변수로 넘겨집니다.
  • PositionOptions [선택] : 위치 정보 획득에 적용할 옵션을 제공합니다.

 

PositionOptions

PositionOptions에는 세 가지 속성이 있습니다.

  • enableHighAccuracy : 높은 정확도로 위치정보를 수신하고 싶음을 나타내는 Boolean.
    true로 설정하면 더 정확한 위치정보를 받을 수 있습니다. 단 응답 속도가 느릴 수 있고 전력 소모량이 증가합니다.
    false로 설정하면 더 빠르게 반응하고 전력 소모를 줄일 수 있습니다.
  • timeout : 기기가 위치정보를 알아낼 때 허용되는 최대 시간(밀리초). 기본값은 Infinity로 이 경우 위치 정보를 알아낼 때까지 메서드의 성공 콜백이 호출되지 않습니다. 너무 짧게 설정하면 timout expired 에러발생하므로 적절한 값 설정해줘야 합니다.
  • maximumAge : 캐시에 저장한 위치정보를 대신 반환할 수 있는 최대 시간(밀리초). 사전에 저장한 위치정보를 얼마동안 유효하다고 볼 것인지 정합니다. 0으로 설정하면 사전에 저장한 위치 대신 항상 현재 위치를 새로 검색
    Infinity로 설정하면 항상 캐시에 저장된 위치를 반환합니다. 즉 새로고침 하지 않으면 항상 같은 위치를 보여줍니다

 

그런데 위치가 정확하지 않다..?

 

문제점

Geolocation API 에서 받아온 GeolocationPosition 값을 통해 위도와 경도를 얻을 수 있었고 정부 API를 성공적으로 호출할 수 있었다.

그런데 받아오는 약국들의 위치가 현재 위치에 기반한 것이 아닌 전혀 다른 곳에 있는 약국들이었다.

 

원인

집에서 사용하는 유선 인터넷 통신과 연관이 있었다. 실제 집의 위치와 다르게 좌표가 찍히는 것은 통신 사업자가 정확하게 정보를 제공하지 않기 때문이었다. 위치정보는 유선 인터넷 통신사업자에서 제공하는 IP 대역별 위치 데이터와 추가 통계 정보를 통해 얻게 되는데 보통 정확하지 않고 IP 대역별 위치 입력 작업 또한 소극적으로 이뤄지고 있어서 그럴수 있다고 한다. (해당 정보에 대한 글이 11년도에 작성되었는데 20년도인 지금도 여전히 위치 정보가 잘못된 것으로 보아 아직도 문제가 개선되지 않은 것으로 보인다? 잘못되었다면 댓글로 피드백 부탁드려요..)

 

모바일 핫스팟으로 인터넷을 연결해보고 확인해보니 현재 내 위치정보가 정확하게 나타났다.

마스크 재고 프로젝트의 1차 목표는 핸드폰으로 재고 확인을 쉽게 알 수 있게끔 하는 것이므로 이러한 문제는 큰 이슈가 아니라고 판단했다.

 

getCurrentPosition vs watchPosition

결론 : getCurrentPosition

이유 : watchPosition 사용시 알 수 없는 에러 발생

정확한 위치를 얻는게 중요하므로 MDN의 설명따라 getCurrentPosition 보다 정확한 위치를 반환해주는 watchPosition 메서드를 사용했다. 하지만 위치가 전혀 변하지 않았는데 불구하고 watchPosition에서 계속 현재 위치를 알아내려고 했고 이 때문에 timeout expired라는 에러 문구가 계속 떴다.

timeout 시간을 좀 더 많이 할당해주는 것이 해결방법인데 값을 최대 10초 정도 주고 다시 테스트를 해봐도 오류가 해결이 안되었다. 그래서 getCurrentPosition 를 사용해보니 오류 없이 위치도 큰 오차없이 정확하게 반환해주어서 해당 메소드를 사용하기로 했다.

 

끝?

이제 위치 정보까지 얻어올 수 있으니 큰 거 하나는 해결했다고 느꼈다. 추가적으로 Geolocation과 관련해 많이 사용되는 Permission API가 있어서 이에 관해서도 알아보았다.

 

Permission API

개념과 사용법 (의역 주의)

  • 특정 API에 대한 액세스 권한이 부여되었는지 여부를 확인할 수 있게 해주는 API.
  • 현재 컨텍스트에 기인한 특정 API의 상태를 쿼리함.

기존 API들은 일관되게끔 자체 권한을 처리하지 않았습니다. 예를 들면, Notification API는 권한 상태를 확인하고 권한을 요청하지만 Geolocation API는 그렇지 않습니다 (이는 초기에 권한허용을 거부할 시에 문제가 됨)

Permission API는 그러한 권한 문제에 대하여 개발자가 더 나은 user experience 를 구현할 수 있게끔 해줍니다.

 

권한 속성은 표준 브라우저 컨텍스트와 Worker 컨텍스트에 존재하는 Navigator 객체에서 사용할 수 있습니다. 이 객체를 통해 권한과 관련된 작업(예: Permission.query() 메서드를 통해 권한을 쿼리하여 특정 API에 대한 PermissionStatus를 resolve 하는 Promise 객체를 반환)을 수행할 수 있습니다.

 

현재 API 구현은 초기 단계이므로 아래와 같은 3가지 제약사항이 있습니다. (2020-03-27 글 작성 기준)

  • Chrome 44 이상 및 Firefox 43 이상
  • 현재 지원되는 방법은 권한 상태를 쿼리하는 Permission.query() 메서드 뿐임
  • 현재 Chrome에서 권한 API에게 인식되는 API는 Geolocation, Notification 뿐이며, Firefox는 Push 및 WebMIDI도 인식함

 

Permission API에 접근하기

global Permission object에 액세스 할 수 있도록 Navigator.permissions 특성이 브라우저에 추가되었습니다. 이 object에는 권한을 쿼리, 요청 및 취소하기위한 메서드가 포함되지만 현재는 Permissions.query() 만 포함합니다

 

Permission 상태 쿼리하기

PermissionStatus 는 다음 3가지 상태로 나뉘어 집니다.

  • "granted"
    Geolocation에 대한 권한이 이미 허용되어 있는 상태
  • "prompt"
    처음 페이지가 로딩되어 권한 허용을 받기 전의 상태. 유저에게 Geolocation 에 대한 권한 허락을 받기 위한 프롬프트(창)이 뜸. Geolocation.getCurrentPosition 메서드가 실행되면서 유저에게 권한 허용 프롬프트를 띄우고 유저가 허용하면 성공 콜백을, 거부하면 실패 콜백을 실행함.
  • "denied"
    prompt 상태일 때, 즉 페이지가 처음 로딩되었을 때 유저가 권한허용을 거부했을 때의 상태

 

더 자세한 내용이 궁금하다면 MDN 문서의 Using the Permission API을 참고하시기 바랍니다.

 

여기까지가 마스크 재고 프로젝트와 관련된 자료 조사였고, 다음 글에는 프론트엔드 작업(퍼블리싱과 화면 렌더링)에 관하여 다뤄보겠습니다. 감사합니다.

 

 

출처

https://www.data.go.kr/dataset/15043025/openapi.do

https://app.swaggerhub.com/apis-docs/Promptech/public-mask-info/20200307-oas3#/v1/get_storesByAddr_json

https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API

https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API/Using_the_Geolocation_API

https://lists.w3.org/Archives/Public/public-html-ig-ko/2011Jan/0009.html

https://developers.google.com/web/fundamentals/native-hardware/user-location

https://developers.google.com/web/updates/2015/04/permissions-api-for-the-web

https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API

https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API/Using_the_Permissions_API

https://developers.google.com/web/updates/2016/04/geolocation-on-secure-contexts-only

댓글