데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      MSA에서 Gateway 활용하기 (기존 API를 Wrapping하기)

      심재훈 23.10.19
      3,064 18 0
      DEVOTEE 요약
      SK하이닉스는 Google Sheets나 Airtable과 같은 웹 기반 스프레드 시트인 Goodocs를 운영하며, 이를 위한 API를 제공하지만 복잡해 한 번의 호출로 모든 데이터를 불러오기 어렵다. 이에 Gateway 서버를 만들어 기존 API를 Wrapping함으로써 편리하게 데이터를 불러올 수 있도록 제안하며, 그 과정은 Python의 FastAPI로 구현하고 기존에 복잡했던 부분을 간결하게 만든다. 이로써 각각 필요한 데이터 형태를 원하는 대로 받을 수 있어, 특히 마이크로 서비스 아키텍처에서는 각 부서가 필요에 따라 이런 Gateway를 만들어 사용하는 것이 효율적이다.
      DEVOTEE 추천 블로그

      개요

      SK하이닉스에서는 Google Sheets, Airtable과 비슷한 웹기반 스프레드 시트 Goodocs를 운영하고 있습니다.


      Goodocs 서비스는 업무 자동화를 위해 API를 제공하고 있는데요.

      키값 하나로 데이터를 전부 받으려면 코드를 여러 줄 작성해야 하는 불편함이 있습니다.

      기존 API가 불편하게 구성되어 있어, 매번 불편하게 이용하는건 별로겠죠?


      이럴 때 Gateway 서버를 만들어서 기존 API를 Wrapping하면 좋습니다!

      Gateway를 구성하면 다른 서비스에서도 이용할 수 있고, 좀 더 본인의 필요에 맞게 API를 구성할 수 있기 때문이죠.


      결과물 Preview

      Gateway를 만들어서 편하게 데이터를 불러오는 것이 목표입니다.

      want.jpg

      기존 API 구성

      기존 API는 아래와 같이 데이터를 불러올 수 있습니다.

      rows, cols 따로 불러와야 합니다.

      저희가 원하는 테이블 형태의 데이터를 받으려면 rows, cols를 조합해야 돼요.

      import json
      import requests
      
      ROOT = '.../openAPI/v1'
      HEADERS = {'Content-type': 'application/json'}
      
      
      def get_cols(doc_id, params):
          url = f'{ROOT}/column'
          params['DOC_ID'] = str(doc_id)
          response = requests.post(url, headers=HEADERS, data=json.dumps(params))
          cols_str = response.json()['COLS']
          cols_raw = json.loads(cols_str)
          return cols
      
      
      def get_rows(doc_id, params):
          url = f'{ROOT}/row'
          params['DOC_ID'] = str(doc_id)
          response = requests.post(url, headers=HEADERS, data=json.dumps(params))
          rows_str = response.json()['ROWS']
          rows_raw = json.loads(rows_str)
          return rows_raw
      
      
      params = {'USER_ID': '...', ...}
      doc_id = '...'
      rows = get_rows(doc_id, params)
      cols = get_cols(doc_id, params)

      rows_raw.jpg

      cols_raw.jpg

      rows에서 원하는 데이터를 받았지만, 열 이름은 키값으로만 받았습니다.

      cols는 데이터는 있지만, 저희가 원하는 {키값: 열 이름} 형태로 받진 못했습니다.


      원하는 Gateway 구성

      저희가 원하는건 API 호출 한번으로 DataFrame을 만드는 것입니다.

      import requests
      import pandas as pd
      
      BASE_URL = '.../api/v1/gooddocs'
      params = {'USER_ID': '...', ...}
      doc_id = '...'
      url = f'{BASE_URL}/{doc_id}/'
      response = requests.get(url, params=params)
      rows = response.json()
      
      data = pd.DataFrame(rows)


      FastAPI로 Gateway 만들기

      이제 원하는 서비스를 만들면 됩니다.

      rows, cols를 기존 API에서 받아와서 가공을 해주고, API로 만들어줍니다.

      # util.py
      import json
      import requests
      
      ROOT = '.../openAPI/v1'
      HEADERS = {'Content-type': 'application/json'}
      
      
      def get_cols(doc_id, params):
          url = f'{ROOT}/column'
          params['DOC_ID'] = str(doc_id)
          response = requests.post(url, headers=HEADERS, data=json.dumps(params))
          cols_str = response.json()['COLS']
          cols_raw = json.loads(cols_str)
          cols = {}
          for col in cols_raw:
              if 'userSetting' not in col:
                  continue
              field = col['field']
              name = col['headerName']
              cols[field] = name
          return cols
      
      
      def get_rows(doc_id, params):
          url = f'{ROOT}/row'
          params['DOC_ID'] = str(doc_id)
          response = requests.post(url, headers=HEADERS, data=json.dumps(params))
          rows_str = response.json()['ROWS']
          rows_raw = json.loads(rows_str)
          cols = get_cols(doc_id, params)
          rows = []
          for row in rows_raw:
              new_row = {}
              for col, name in cols.items():
                  new_row[name] = row[col]
              rows.append(new_row)
          return rows
      # main.py
      from fastapi import FastAPI
      from .util import get_rows
      
      app = FastAPI()
      
      
      @app.get('/api/v1/gooddocs/{doc_id}')
      async def read(doc_id: str, USER_ID: str, ...):
          params = {'USER_ID': USER_ID, ...}
          rows = get_rows(doc_id, params)
          return rows


      Gateway get_rows 결과

      이제 만들어둔 Gateway에 docs_id만 넣어서 호출해주기만 하면 됩니다.

      저희가 딱 필요한 데이터만, 원하는 형태로 받을 수 있죠!

      rows.jpg


      기존 API를 수정하면 되는거 아닌가요?

      사내에서 만든 API이기 때문에, 만든 부서에서 쓰기 쉽게 수정하면 되는거 아닌가 생각할 수 있습니다.

      일단 API를 배포하면, 사내라고 해도 쉽게 변경하기 어렵습니다. 해당 API에 의존하고 있는 다른 서비스도 맞춰서 변경해야 하죠.

      또한 각 부서에서 필요한 데이터가 다르고, 원하는 형태가 다를 수 있습니다.

      그렇기 때문에 Micro Service Architecture에서는 각 부서가 Gateway (Simple Wrapper)를 만들어서 쓰는 구조가 좋습니다.



      참고문서

      Martin Fowler의 Gateway Pattern

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      심재훈 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기