-
Notifications
You must be signed in to change notification settings - Fork 0
✒ [BE] 개발일지
분류 | 사용 기술 |
---|---|
서버 프레임워크 | NestJS |
프로그래밍 언어 | TypeScript |
테스트 | Jest, Docker, Apache Jmeter |
로깅 | Winston |
DB | PostgreSQL, TypeORM |
웹 서버 | NginX |
클라우드 컴퓨팅 | Naver Cloud Platform |
이미지 저장 | Object Storage, multer, sharp |
CI/CD | GitHub Action, Docker |
사용 기술 | 기술 선택의 이유 |
---|---|
|
프로젝트는 TypeScript를 기반으로 한 서버 아키텍처를 사용하며, NestJS를 선택했습니다. NestJS는 Angular에서 영감을 받은 모듈러 아키텍처를 채택하고 있어, 모듈, 컨트롤러, 서비스 등을 쉽게 구성할 수 있습니다. 이 때문에 개발의 유연성과 확장성을 높아졌으며, 기능 추가나 변경이 간편했습니다. |
|
백엔드 개발 인원 모두가 ORM(Object-Relational Mapping) 사용 경험이 적었습니다. 이를 고려하여, 문서가 풍부하고 TypeScript 클래스 및 데코레이터를 사용하는 TypeORM을 선택했습니다. 이는 TypeScript를 처음 사용하는 저희에게 좋은 학습 기회를 제공하며, 프로젝트에 보다 많은 TypeORM 적용을 가능하게 했습니다. |
|
기존에 사용하던 pg-mem 라이브러리가 PostGIS 확장에서 제공하는 point 타입의 location field를 지원하지 않았습니다. 이에 따라, Docker를 사용한 컨테이너 가상 DB 테스트 방식을 채택했습니다. 이 방식은 보다 실제 환경에 가까운 테스트를 가능하게 하여 더 나은 품질의 소프트웨어 개발을 할 수 있었습니다. |
|
로그를 파일로 저장함으로써 추후 확인 작업을 용이하게 하기 위해, NestJS의 기본 logger 대신 Winston을 사용하여 custom logger를 구현했습니다. 또한, 모든 동작에 대해 일관된 로깅을 위해 interceptor를 활용했습니다. 이는 효율적인 로그 관리와 문제 해결에 도움을 주었습니다. |
|
PostgreSQL은 대규모 트랜잭션 처리와 복잡한 쿼리에 강점을 가지고 있으며, 이는 사용자와 데이터가 많은 음식점 공유 플랫폼에 적합하다고 판단되었습니다. 또한, PostGIS 확장 기능은 고급 공간 쿼리 처리 및 확장성 면에서 MySQL보다 우수하다고 평가되었습니다. |
|
GitHub를 사용하는 프로젝트에서 특정 브랜치에 push가 이루어질 때 자동 배포를 구현하려고 계획하고 있습니다. 이 과정에서 GitHub Actions를 활용하여 push 이벤트가 발생할 때마다 자동으로 배포가 진행되도록 설정하는 것을 고려하고 있습니다. 또한, 기존에 실행 중인 웹 애플리케이션 서버(WAS)를 종료하고 새로운 WAS를 실행시키는 과정이 환경에 구애받지 않고 원활하게 수행되기 위해 Docker를 사용하는 것이 바람직하다고 판단했습니다. |
|
github action과 docker를 이용해서 ci/cd를 구축하는 과정에서 기존에 was에 직접 SSL 인증서를 저장하고 https 접속을 하는 과정을 변경할 필요가 있다고 판단했습니다. 그 결과 was docker에 매번 SSL 인증서를 넣어서 실행시키는 대신, 앞 단에 nginx를 두고 SSL 인증서를 등록한 후 리버스 프록시로 사용하여 모든 요청을 https로 수신한 후 was에 내부망을 통해 http로 요청을 전달하는 방식을 결정했습니다. |
|
부하테스트를 직접 api 호출을 여러번 해보는 형태로 하는 것 보다는 자동화 된 툴을 사용하는 것이 좋다고 판단했고, 그 중 학습 자료가 풍부하고 GUI를 통해 쉽게 사용이 가능한 JMeter를 사용해보기로 결정했습니다. |
|
DB에 고화질 사진과 같은 대용량 버퍼 데이터 자체를 보관하기에는 DB의 비용 증가와, 트래픽 과부하 시 DB 서버에 더욱 부담을 줄 수 있기에 DB에는 이미지의 path( URL ) 만을 저장하고, 이후 해당 정보에 대한 요청이 들어온다면 DB에서 해당 URL을 꺼내 서버가 클라이언트에게 응답하도록 하는 것이 좋다고 판단했습니다. |
고민 | 해결 과정 |
---|---|
왜 공공 API를 선택했나? | 앱 개발 과정에서 서울시 내 음식점 데이터를 서버에 통합하려 할 때, 저희는 적절한 API를 찾는 데 있어 몇 가지 선택지를 고려했습니다. 처음에는 Naver와 Kakao의 지도 검색 API를 사용하는 방안을 모색했습니다. 그러나 이러한 서비스들은 API 호출 시 반환할 수 있는 데이터의 수에 한계가 있었는데, 대략 한 번에 45개의 데이터만을 받을 수 있었습니다. 이는 서울시에 있는 약 15만 개의 음식점 데이터를 효율적으로 수집하기에는 불충분했습니다. 또한, 모든 데이터를 수집하기 위해서는 다양한 키워드로 반복 검색을 해야 했으며, 이러한 방식은 서버 자원을 비효율적으로 사용하는 것이라 판단했습니다. 이 문제를 해결하기 위해, 저희는 서울시 일반 음식점 인허가 정보 API로 전환하기로 결정했습니다. 이 API를 통해 저희는 페이지 당 최대 1천 개의 데이터를 받아올 수 있었고, Promise를 활용한 비동기 처리를 통해 데이터를 서버의 데이터베이스에 효과적으로 저장하고 업데이트할 수 있었습니다. 이로 인해 데이터 관리 작업의 시간을 단축시킬 수 있었습니다. |
고민 | 해결 과정 |
---|---|
Object Image Resizing | 저희 프로젝트에서는 오브젝트 스토리지를 이용하여 이미지를 관리하고 있습니다. 최적화를 위해 이미지를 서버에 업로드하기 전에 리사이징 처리를 적용했습니다. 이로 인해 처음 이미지 업로드 시 리사이징 작업으로 인해 속도가 다소 느려질 수 있지만, 한 번 리사이즈된 이미지는 클라이언트의 다운로드 속도를 향상시켰습니다. 이 변경은 초기 업로드 시간이 길어지는 트레이드오프를 감수하는 대신, 사용자 경험을 개선하고 네트워크 대역폭 비용을 절감하는 장기적인 이점을 제공합니다 |
고민 | 해결 과정 |
---|---|
어플리케이션 통신 과정 | 저희 앱의 백엔드 통신 과정은 최적의 보안과 효율성을 고려하여 설계되었습니다. 먼저, 사용자가 앱을 통해 발생시키는 모든 요청은 Ncloud에 배포된 Nginx 서버를 통해 처리됩니다. 이때 HTTPS 프로토콜을 사용함으로써 데이터의 안전한 전송을 보장합니다. HTTPS는 사용자 데이터의 암호화를 통해 외부 위협으로부터 보호하는 역할을 합니다. 다음으로, 이 요청들은 VPC(Virtual Private Cloud)라는 격리된 네트워크 환경 내부에서 라우팅됩니다. Nginx 서버에서는 요청을 받아 웹 애플리케이션 서버(WAS)로 전달하고, WAS는 이를 처리하여 필요한 데이터를 데이터베이스(DB)와 상호작용하며 요청에 응답합니다. VPC 내부에서의 이 통신 과정은 각각의 요소가 서로 안전하게 연결되도록 하여, 요청 처리와 데이터 전송이 외부 위험으로부터 보호받을 수 있도록 합니다. 이 구조를 통해 사용자의 요청은 신속하고 안전하게 처리되며, 결과적으로 사용자에게 안정적인 서비스 경험을 제공합니다. |
고민 | 해결 과정 |
---|---|
Pg-mem |
개발 과정에서 저희 팀은 단위 테스트를 진행하기 위해 'pg-mem'이라는 인메모리 가상 데이터베이스 테스트 방식을 사용하고 있었습니다. 이 방식은 빠른 테스트 실행 속도를 제공하며, 실제 데이터베이스 환경을 모방하는 데 유용했습니다. 그러나, 저희가 구현하고자 한 기능 중 위치 기반 서비스가 중요한 부분을 차지했고, 이를 위해 PostgreSQL의 확장인 PostGIS를 사용하게 되었습니다. 하지만 'pg-mem'은 PostGIS와 같은 확장 기능을 지원하지 않았습니다. 이에 따라, 저희는 테스트 환경을 Docker를 기반으로 한 테스트로 전환하기로 결정했습니다. Docker를 사용함으로써, 실제 PostGIS를 포함한 PostgreSQL 환경을 재현할 수 있었고, 이는 저희가 위치 기반 기능을 정확히 테스트할 수 있게 해주었습니다. 이 변경은 초기 설정에 조금 더 시간이 소요되었지만, 테스트의 신뢰성과 정확성을 크게 향상시켰습니다. 결과적으로, 이는 사용자에게 더 정확한 위치 기반 서비스를 제공할 수 있는 기반을 마련해주었습니다. |
개발일지
📢2023-11-07
고민사항
-
user의 login api 설계시 social-login 부분을 따로 만들어야 하는가?
- 관리 측면 및 코드 재사용성 측면에서 하나로 하되, social-provider 컬럼을 추가하여 관리하는 것이 효율적이라 판단하여 login 만 사용하도록 작성.
-
login, signup 같은 엔드포인트를 작성할 때 'kebab-case'로 작성하는 방법과 'camel-case'방법 중 어떤 방법을 채택할까?
- 우선 kebab-case를 채택하는 것이 일반적인만큼 이 방법을 채택, 너무 길어지는 경우에만 넣고 짧을 경우 빼도록 규칙정하기.
한 일 / 할 일
- api 설계 생각하기 ( 엔드포인트, 응답 생각하기 )
📢2023-11-09
고민사항
DB 관련 작업을 featureList에 추가해야하는가? 추가한다면 비기능적인 부분인가? 추가하여 DB를 FeatureList의 title로 정한다면, 각각의 다른 기능들에서는 DB entity, schema같은 부분들의 설계를 고려해야 하는가?
-
DB 관련 작업을 featureList에 추가한다면, 각 기능 별 task에서는 DB를 통해 작업하는 부분을 제외시켜야 할지 고민이 되었다.
- 결과 : featureList에 있는 DB 부분을 통해 DB 쪽 스토리를 만들고 이 부분에서 공통적으로 진행할 erd, schema 설계등의 작업을 하고, 다른 기능에 대한 스토리에서 각각에 필요한 DB 조회나 업데이트 등의 기능을 task로 적기로 결정
단일 엔드포인트 처리, 분리된 엔드포인트
-
/api/user/follow-list의 단일 엔드포인트 에서 팔로우 / 언팔로우 처리
-
[post] /api/user/follow 와 [post] /api/user/unfollow와 같이 같은 메서드이지만 url을 다르게 작성하여 분리된 엔드포인트에서의 처리
-
[post] /api/user/follow-list/{userId} 와 [delete] /api/user/follow-list/{userId} 와 같이 같은 url이지만 다른 메서드로 엔드포인트 분리.
-
결과 : 3번 채택
-
이유 : 단일 엔드포인트 처리로 두 기능을 처리 가능하기에 단순하지만, 같은 메서드이면서 같은 url이라면 어떤 동작을 수행하는지 명확하게 알기 어렵다. RESTful API에 맞게 같은 url을 사용하더라도 HTTP메서드를 다르게 하여 엔드포인트의 동작을 다르게 하여 엔드포인트를 구분하는 기준으로 정하는 것이 좋다고 판단하였음.
-
사용자에대한 get, post, put, delete 요청에 대한 엔드포인트 형태
-
put /api/user/{userId}
-
put /api/user
-
결과: b채택
-
jwt 형식을 사용할 때 payload에 userid를 넣어준다면 엔드포인트에 넣어주지 않고 동작할 수 있다고 판단함
-
비기능적 FeatureList 추가 ( DB, 배포, API 문서화, 보안, 로깅 )
배포
-
VPC : Virtual Private Cloud [ 클라우드 컴퓨팅 환경에서 사용자가 정의한 가상 네트워크 ]
Api 문서 작성 시작
개발 프로세스
기술 스택
- 프레임워크 : NestJS
- IOC
- 의존성 주입
- https://github.com/nestjs/typescript-starter
- 프로그래밍 언어 : TypeScript
- 테스트 : Jest
- DB: https://www.npmjs.com/package/pg-mem
- 외부 API : mocking
- logger : Winston
- 규칙 정하기
- RESTful API
- DB : MongoDB, PostgreSQL, MySQL
- 설계 툴 : https://dbdiagram.io/home
- Web Server : NginX, Apache
네이버 api - Geocode
-
https://api.ncloud-docs.com/docs/ai-naver-mapsgeocoding-geocode
-
[https://developers.naver.com/docs/serviceapi/search/local/local.md#지역](https://developers.naver.com/docs/serviceapi/search/local/local.md#%EC%A7%80%EC%97%AD)
-
카카오 음식점 api
-
https://developers.kakao.com/docs/latest/ko/local/dev-guide#search-by-category
📢2023-11-11
고민사항
refresh-token 처리 하는 엔드포인트를 분류해야 하는가? - 미들웨어에서 바로 처리를 해줘도 되지 않을까? - 만약 그렇다면, 미들웨어에서는 어떻게 처리를 하지? 미들웨어 위치를 뒤로 미뤄야 할까?
- 결론 :
- refresh-token을 처리하는 엔드포인트를 분류하되, access-token 유효성 검사는 미들웨어에서 하자.
- 이유 :
- 같은 엔드포인트에서 access-token를 처리하는 로직과 refresh-token을 처리하는 로직이 있다면, 요청이 access-token이 올 때가 있고 refresh-token이 올때가 나눠지므로 일관성 있게 같은 형식의 요청만 받아오고 이를 처리하도록 하는 것이 좋을 것 같았다.
Oauth를 앱(프론트)에서 처리하여 이후 서버에 로그인 요청을 보낸다면, 서버는 클라이언트에게 어떤 정보를 받아서 처리를 해야하는가?
- 결론:
- Resource Server의 Authorization Code를 클라이언트가 서버에게 전송한다.
- 서버는 클라이언트로부터 받은 Authorization Code를 사용하여 소셜 로그인 제공자에게 Access Token을 요청한다.
- 서버는 받은 Access Token을 사용하여 사용자의 프로필 정보(이름, 이메일 등)를 소셜 로그인 제공자로부터 가져온다.
- 이후 서버는 DB서버 테이블 정보와 해당 정보가 일치하는지 확인.
한 일 / 할 일
- API 문서화 작업
- /api/auth 요청 문서화 하기
- access-token 확인은 미들웨어에서 하도록 계획.
- refresh-token 발급하는 end-point 분리.
- 각 요청에 대한 성공 / 실패 상황에 대한 응답 작성.
- 11월 12일 일요일에 할 일 미리 정하기 ( 중요도 순서 )
- API 문서화 로그인은 필수 ( 에러를 포함한 응답, 나머지는 정상 응답 위주 )
- DB 스키마 설계, ERD 그리기 ( https://dbdiagram.io/home , PostgreSQL )
- 개발 프로세스 룰 정하기 ( 시간이 남으면 )
📢2023-11-12
고민사항
accessToken을 메서드 별 서버로 보내는 방법
-
body에 accessToken을 보내주면 되지 않을까?
-
get이나 delete의 경우 body를 사용하지 않는데 여기서는 어떻게 보내줘야 할까?
-
결론: 어떤 메서드든지 header에 Authorization 부분에 accessToken값을 넣어서 보내자
-
이유: 처음에는 costom header를 통해서 accessToken을 보내는 방식을 생각했다가, 이 부분에 대해 MDN 공식 문서를 찾아보니 해당 역할을 해주는 Authorization 헤더가 있어서 이걸 사용하기로 결정했다.
리뷰내용을 하나의 컬럼 json 형식으로 저장할지, 테이블을 따로 만들지
- 결론 : 테이블을 따로 추가하자
- 이유 : 리뷰에 포함되는 정보가 텍스트 만이 아닌 주차 공간, 맛, 서비스 평가 등 여러 요소가 있기 때문에 이를 user 테이블에서 함께 관리한다기 보다는, 정규화를 만족시키기 위해 이를 review 테이블로 분리하여 관리하자.
미들웨어에서 응답하는 부분을 엔드포인트 외에 다른 부분에서 따로 문서화를 해야할지
- 결론 : 문서화는 모든 엔드포인트에서 하도록 하자.
- 이유 : 미들웨어에서 라우팅 하지 않고 에러를 응답한다고 해도 각 엔드포인트에서는 에러 응답이 어떤 형식인지 문서화를 하는 것이 개발할때에는 좋다고 판단.
📢2023-11-13
고민사항
- 검색 결과 or 홈 페이지에 맛집 리스트를 표기하기 위해 서버가 클라이언트에게 제공하는 정보에 각 맛집을 클릭했을 때의 간략한 정보를 표기하는 바텀 시트에 포함될 정보까지 주어야 할까?
- 너무 많은 데이터를 한번에 주는 것은 아닌가?
- 각각의 맛집을 클릭했을 때 api요청을 반복한다면 api 오버 헤드가 부담이 될까?
결론 : 일단 간략한 정보까지 주되, 상세한 정보 요청 api는 분리하고 클라이언트에서 부담이 된다면 수정하기.
한 일 / 할 일
-
Ncloud VPC 서버 구동
- Ncloud VPC Public, Private 서버 가동.
- Public 서버는 웹 어플리케이션 서버
- Private 서버는 DB 서버
- Subnet 및 ACG 설정.
-
Ncloud 계정 나누기
- https://guide.ncloud-docs.com/docs/subaccount-overview 참고하여 안드로이드, 백엔드 계정 분류
📢2023-11-14
고민사항
-
동일한 엔드포인트로 회원가입을 처리하려고 할 때, 일반 로그인 사용자와 소셜 로그인 사용자의 정보가 다른데 이걸 어떻게 처리해야 할까?
- 결론 : 상세 회원가입 페이지에서 요청하는 것은 같으므로, 클라이언트에서 데이터 형식만 맞춰서 보내는 것으로 결론.
-
소셜 로그인 할 때 사용자를 인증하는 과정을 어떻게 해야할까?
-
단순히 사용자가 주는 정보로 jwt를 만들어 발급해주면 보안상 문제가 될 것 같다.
-
결론 : 클라이언트에서 소셜 로그인을 한 곳에 대한 accesstoken과 email을 주고, 서버에서 accesstoken을 통해 유저 정보를 받아와서 email과 비교한 후 맞으면 jwt 발급하는 방식이 서버 측 업무라고 판단하였음.
-
-
토큰 검증같은 경우는 공통 로직으로 빼는 게 좋을것 같다.
-
api 만드는 작업을 클라이언트쪽과 맞춰서 진행을 해야할까?
-
백엔드 관련 작업을 우선적으로 진행하고 추후에 api를 해야하나?
-
결론 : 우선 진행 내용은 공유하되, 클라이언트는 api 완성을 기다리지 말고 Mock 데이터로 먼저 기능 구현하기.
-
한 일 / 할 일
- 이번 주에 구현해야 할 회원가입/마이페이지/로그인 구현하기.
-
토큰 검증 유무에 따른 데코레이터 사용 ( UseGuard 모듈 )
📢2023-11-15
고민사항
- DB 엔티티 나누기
- 엔티티 :
- 유저 ( 이메일, 닉네임, 비밀번호, 지역, 신뢰도, 나이, 성별, 생년월일, 소셜 로그인 )
- 등록 맛집 리스트 ( 사용자, 음식점 이름, 카테고리, 위치 정보, 등록 날짜, 전화번호 )
위시 맛집 리스트 ( 사용자, 음식점 이름, 카테고리, 위치 정보, 등록 날짜, 전화번호 )- 리뷰 ( 사용자 , 리뷰 내용, 등록 날짜 )
- 카테고리 ( 사용자 , 음식 카테고리 )
- 팔로우 / 팔로워 ( 사용자 , 팔로우 대상 )
한 일 / 할 일
- DB 서버에 스키마 생성
-
회원 가입을 같이 하고 분업 시작
-
로그인 : 이태훈
-
마이 페이지 : 최근혁
📢2023-11-16
기술 적용
-
Object-Relational Mapping
-
선택 이유
- ORM을 사용하면 복잡한 SQL 쿼리를 작성하는 대신 객체 지향적 방식으로 데이터베이스 작업을 수행할 수 있기에, 코드를 더 읽기 쉽고 유지 보수하기 쉽게 만들었다.
- 기존 멤버십 과정의 Vanillat JS 에서 MySQL을 이용해 직접 쿼리문을 작성하여 실행해본 경험과 이번 ORM을 통해 두 방법의 비교를 해보고 싶었다.
-
typeorm 과 prisma 중 왜 typeorm을 선택했는가?
- 우리 백엔드 분야 캠퍼 2명은 ORM을 사용해 본 적이 거의 없다시피 했기에 학습할 자료가 많이 필요하다고 판단하였고, 이에 더 오래 존재했던 TypeORM이 관련 문서가 더 많을 것이라 생각해 선택했다.
- Prisma는 Prisma 스키마 파일을 사용하여 모델을 정의하고, TypeORM은 TypeScript 클래스와 데코레이터를 사용한다. typeScript를 이번 멤버십 과정을 통해 처음 사용하기 시작한 만큼 조금이라도 더 적용해보고 싶었기에 TypeORM을 선택했다.
-
-
Response Interceptor
- 선택 이유
- 개발을 하며 협업이라는 부분에서 서버가 주는 응답을 프론트 개발자가 좀 더 쉽게 접근 할 수 있으면 좋겠다는 생각을 했고, 에러와 성공응답의 데이터포맷이 일치하는 방법을 적용하면 좋겠다는 생각을 가지다 이 방법을 찾게 되었다.
- 모든 응답을 특정 JSON 구조로 래핑하거나 추가 메타데이터를 포함시키는 경우, Response Interceptor를 사용하여 이를 효율적으로 관리할 수 있었다.
- 2번째 멤버십 프로젝트에서 모든 서버 구조를 net 모듈로 구현하면서 응답 구조를 직접 구현해야 했는데 그 때의 response make를 담당하는 클래스를 통해 통일된 구조의 응답을 생성하는 부분이 이 response Interceptor과 비슷하게 느껴지기도 하여 사용해보고 싶다고 생각되었다.
- 선택 이유
-
Guard
- 선택 이유
- 서버에서 발급한 jwt를 포함한 요청을 클라이언트가 보냈을 때에, 모든 엔드포인트에서 이러한 jwt의 유효성 검증을 하는 것은 비효율적이라고 판단되었고, 이를 모든 요청이 먼저 거치는 미들웨어에서 하는 것이 효율적이라고 생각되었다.
- 그러나, jwt토큰을 검증하지 않아도 되는 요청 ( ex : 회원가입, 로그인 ) 을 기존 프로젝트에서는 whitelist 를 만들어, 해당 리스트에 포함되는 url에서는 토큰 검증을 하지 않도록 했었는데 이러한 개념을 nest에서 적용한 것이 Guard 데코레이터인 것으로 이해되어 사용하는 것이 좋다고 판단했다.
- 선택 이유
한 일 / 할 일
- typeOrm 틀 세우기
- 웹 어플리케이션 서버와 DB 서버 연동하기.
- Base Response 만들기
- Guard 적용.
📢2023-11-20
고민사항
한 일 / 할 일
이번 주 작업할 목록
- 홈 페이지 api
- postgis 사용
- 로그인 refresh 토큰 발급
목록 분담
📢2023-11-21
고민사항
앱 사용자에게 제공할 지도 음식점 정보 데이터 제공 - 음식점 정보를 받아오는 api
사용한 기술 : 서울시 공공 api
-
기술 선택의 이유 : 처음에는 네이버나 카카오 api를 사용할 계획을 세웠으나, 한번에 가져올 수 있는 양이 너무 적고 반복해서 api 요청을 하는것도 불가능했기 때문에 사용하기 부적절하다고 판단했다. 그래서 한번에 1000개씩 반복적으로 api 요청을 하여 모든 정보를 가져올 수 있는 서울시 공공 api를 선택했다.
-
고민 및 해결 과정 :
- 약 50만개의 데이터를 받아와야 하기 때문에 1000개씩 500번 정도의 api 요청을 해야하고 이 데이터를 DB에 매번 저장하는 과정에서 매우 오랜 시간(약 13분)이 걸렸다. 이 부분을 개선하기 위해 처음에는 worker 모듈을 사용하여 쓰레드를 생성하여 작업하고 저장하니 시간이 약 4분 정도로 단축됐다.
- 이후 조금 더 개선을 하기 위해 api를 비동기적으로 요청하고 해당 작업이 어느 정도 진행됐을 때마다 한번씩 DB에 bulk insert를 하는 방식을 시도했고 시간은 약 2분 정도로 단축됐다.
- 위치 정보는 postGIS 확장을 이용하여 저장을 시도했고, 이때 안드로이드쪽과 편하게 협업하기 위해서는 WGS좌표계로 저장할 필요가 있었는데, 서울시 공공 api에서 제공하는 위치 정보는 중부TM 좌표계였기 때문에 변환을 해야했다. proj4 라는 npm 모듈을 이용하여 변환을 시도했는데 위치 정보에 오차가 매우 큰 오류가 발생했고 더 정확한 보정된 중부원점 좌표계를 활용하여 WGS 좌표계로 변환하여 위치 정보를 저장했다.
한 일 / 할 일
- 기존 네이버, 카카오로 이용할 계획이었던 음식점 정보 얻어올 api를 대체할 또다른 open api 찾기.
- 서울시 음식점 공공 open api를 통한 12만개 음식점 지리 및 메타 데이터를 WAS가 받아와 DB에 저장.
📢2023-11-22
고민사항
트러블 슈팅
-
synchronize 옵션 → typerom config
- 이걸 옵션을 설정해야 엔티티 설정이 변경되었을 때 변경 사항을 적용해서 새로 생성 → 개발 환경에서 용이
-
schema
- 여러 스키마에 같은 extension 설치가 안됨
- 한 스키마 설치된 extension이 다른 스키마에 영향을 미치지 않음 → 사용할 스키마에 따로 설치 필요
- 기존에 있던 스키마에서 extension을 삭제하고 사용할 스키마에 재설치 과정 필요
-
트랜잭션 충둘
- 각 스레드가 repository(DB)에 접근하려고 하니 id 컬럼의 auto increment로 인한 중복 접근이 발생해 데드락 발생 → 각 스레드가 실행한 결과를 모아서 DB에는 한번에 접근하기 → DB작업이 중간에 실패하면 이전으로 rollback하기 -> 스레드에서 비동기 promise 처리로 변경 예정
한 일 / 할 일
- 서울시 음식점 공공 open api를 통한 12만개 음식점 지리 및 메타 데이터를 WAS가 받아와 DB에 저장속도 개선 방안 생각하기
- 팀 오프라인 미팅
-
👬 팀 회고
-
🙍♂️ 개인 회고