All
13 posts
HTTP/1.0부터 HTTP/3.0까지

이전 포스팅: <어떤 API를 사용해야 할까? - REST, GraphQL, 그리고 GRPC>에서 다양한 API 형식에 대하여 소개했다. 그 중 REST는 프로토콜을 기반으로 동작한다면, gRPC는 프로토콜을 기반으로 동작한다는 점이 가장 큰 차이점이었다. 그동안 HTTP와 HTTPS를 ‘웹에서 동작하는 어플리케이션을 만들기 위해 정의된 클라이언트-서버 모델의 프로토콜’ 정도의 넓은 개념으로만 이해하고 있었다. 시간의 흐름에 따라 발전해온 HTTP 프로토콜의 버전과 그 특징에 대하여 자세하게 알아보려고 한다. 웹은 어떻게 동작하는가? 인터넷이 메세지를 routing할 수 있는 을 기반으로 연결된 public한 computer들의 집합이라는 넓은 개념이라면, Web은 이메일, 파일 공유처럼 인터넷을 구성하는 여러 서비스 중 하나라고 말할 수 있다. IP(Internel Protocol): 송신 호스트와 수신 호스트 사이에서 패킷이 네트워크를 통해 이동할 수 있도록 데이터를 라우팅…

June 03, 2023
|
네트워크
어떤 API를 사용해야 할까? - REST, GraphQL, 그리고 GRPC

는 서비스와 서비스끼리 통신하기 위해, 즉 요청과 응답을 주고받기 위해 정의된 다양한 종류의 인터페이스이다. ‘다양한 서비스가 만나는 지점’이자 ‘서비스의 동작을 정의한 일종의 약속’이라고도 표현할 수 있을 것 같다. 실제 서비스를 제공하기 위해서는 무수히 많은 소프트웨어 서비스가 맞물려서 운영되어야 하기 때문에, 구체적이고 확장성이 높은 API를 정의하는 것은 매우 중요하다. API는 어떤 방식으로 동작할까? API는 클라이언트와 서버 사이에서 요청과 응답을 통해 리소스를 주고받는 방식으로 동작한다. API를 구성하는 요소들은 아래와 같다. 자원(resource) ‘이 리소스를 어떻게 명확하게 표현할 수 있을지?‘가 바로 API가 풀어내야 할 과제가 된다. 여기서 리소스는 DB에 저장된 데이터 자체가 아닌, 데이터의 상태를 클라이언트가 요청한 방식에 맞추어 표현하여 전달한 응답이다. 리소스는 JSON 데이터일수도, 이미지일수도 또는 어떠한 문서일수도 있다. 동작(method) 또…

June 01, 2023
|
파이선에서 asyncio로 비동기 처리하기

비동기 프로그래밍과 동작원리 비동기(asynchronous) 처리는 현재 실행 중인 작업이 완료되지 않은 상태에서 다른 작업을 처리하도록 요청할 수 있는 방식이다. 동기(synchronous) 처리와 다르게 여러 작업을 동시에 실행할 수 있다는 장점이 있다. 파이선에서는 비동기 프로그래밍을 적용하여 동시성을 보장하기 위해 라는 모듈을 사용한다. Coroutine(코루틴) 특정 함수를 실행할 때, 반복되는 작업을 개별 함수로 분리하고 이를 호출하여 사용할 수 있다. 여기서 호출되어 수행되는 흐름을 이라고 한다. 은 하나의 entry point를 가지고 있으며 호출되는 에 종속적이라는 특징을 가지고 있다. 이란 서브 루틴처럼 특정 함수의 실행에 종속되어 있는 것이 아닌, 대등한 관계를 가지고 서로 순차적으로 호출할 수 있도록 구현된 함수라고 할 수 있다. 과 달리 여러 개의 entry point와 exit point를 가진다. 을 이해하기 위해 아래 개념들을 알 필요가 있다. Iter…

May 14, 2023
|
python
Django에서 migration으로 테이블 관리하기

기능을 추가하며 모델을 변경해야 할 일이 새겼다. 테이블을 수정하고 migration을 적용하면서 dependency 오류부터 relationExists 오류까지 아주 난항을 겪었다. 사실 토이프로젝트에서는 migration이 꼬이면 그냥 전부 밀어버리고 다시 적용하면 그만이었다. 하지만 실제로 배포되고 데이터가 담겨 있는 DB의 테이블을 수정하는 경우에는 이런 1차원적인 방식으로 접근할 수는 없었다. 다소 긴 삽질의 과정을 경험하며, 내가 migration에 대하여 정확히 이해를 하지 못하고 있음을 깨달았다. Migration이란? 일종의 database version control log라고 이해하면 될 것 같다. 명령어를 수행하면 각 app의 모델에 대한 변경사항을 기록한 python script가 자동으로 생성되고 명령어를 수행하면 db에 변경사항을 반영할 수 있다. 이 migration script는 형식으로 네이밍되며, 모델 간의 관계(생성 순서, 참조 방향 등)를…

December 30, 2022
|
프레임워크
Github Action으로 EC2에서 배포 자동화하기

Github Action은 build, test, deployment와 같은 workflow를 자동화할 수 있는 CI/CD 플랫폼으로, github repository에서 발생하는 모든 이벤트(push, pull request, merge 등)에 대하여 정해진 동작을 실행시키도록 할 수 있다. 진행중인 프로젝트에서는 를 이용해 서비스 컨테이너들을 관리하고 있다. 소스코드가 수정될 때마다 수동으로 컨테이너를 삭제하고 빌드하는 방식으로 테스트 서버를 운영하다가 을 사용하여 CI/CD를 자동화해보기로 했다. CI/CD 프로세스 설계해보기 다음과 같은 프로세스들을 자동화시키려 하였다. github/workflow에 YAML파일 생성 생성된 pull request에 대하여 자동으로 build 테스트를 수행 → 실패시 merge 불가 main branch에 pull request가 merge된 경우, a) production 서버에 동작하던 컨테이너를 중지 / dangling image를 삭…

December 16, 2022
|
DevOps
ci/cd
Github
(Backend.AI) hotfix PR 뜯어보기

얼마전, 오픈소스에 하나의 PR을 머지시켰다. 다음날 레포를 확인해보니, 내가 merge시킨 기능과 관련한 hotfix가 2개나 열려있었다.. #768. create vfolder status correctly 첫번째로 새로 추가한 컬럼()의 default value 설정값과 관련하여 버그가 발생한 듯하다. python sqlalchemy에서는 다음과 같은 포맷으로 table과 column을 관리한다. 테이블에 컬럼을 추가하는 작업을 진행할 때, 컬럼의 기본값을 지정해주기 위해 인자를 사용했다. 하지만 이미 존재하던 테이블에 새로운 컬럼을 추가한 것이므로, 새로운 데이터를 생성할 때 뿐만 아니라 기존에 table에 존재하던 데이터에 이 속성의 값을 어떻게 설정해주어야 할지까지 고려했어야 했다. 따라서 “없던 속성을 새로 추가한 상황”에서는 단순히 컬럼의 기본 속성값을 지정해주는 가 아닌, 해당 속성을 가지고 있지 않던 데이터에도 기본값을 저장하도록 인자를 사용했어야 했다. …

October 06, 2022
|
오픈소스
데이터베이스
(Backend.AI) 614. ImageNotFound message typo error

Issue Contents #614 존재하지 않는 이미지로 세션을 생성할 때 발생하는 ImageNotFound 에러의 메세지 typo errorf를 수정한다. Ideation & Issue Solving ImageNotFound typo error 수정 (a9801d) 주요 변경/개선 사항 반영완료 #615 Issue Contents #614 Ideation & Issue Solving 주요 변경/개선 사항

October 03, 2022
|
오픈소스
(Backend.AI) 742. Auto-generate and auto-commit news fragment from PR title

Issue Contents #742 프로젝트에 새롭게 기여하는 컨트리뷰터들에게 news fragment 작성 방법을 설명하는 번거로움을 덜기 위하여 PR제목을 수정할 경우 towncrier news fragment를 자동으로 생성/수정하도록 workflow를 구현하자. PR에 assign된 label과 매칭되는 news fragment를 가져오고, PR 제목이 변경될 경우 그 내용을 자동으로 수정/commit/push한다 assign된 label이 없는 경우는 workflow를 수행하지 않는다 label과 매칭되는 news fragment가 없는 경우 workflow는 failure를 뱉어야 한다 news fragment가 존재하지 않는 경우, 현재의 PR제목으로 news fragment를 생성해주자 Ideation & Issue Solving news fragment를 생성 및 수정하는 파이선 스크립트 파일을 생성하고, 를 사용하여 변경할 내용(—content) / 매칭여부를 확…

October 02, 2022
|
오픈소스
(Backend.AI) 575. introduce vfolder status

Issue Contents #575 vfolder clone, delete와 같은 storage-proxy operation 작업을 수행할 때, 사용자의 접근을 제어할 수 있도록 vfolder 상태값을 관리하려고 한다. Ideation & Issue Solving status값을 관리하기 위한 값을 생성하고 이 값을 field로 가지는 table을 생성한다. 새로 생성한 테이블은 FK로 vfolder table을 참조하도록 하자. manager의 vfolder api에 정의된 operation(create, clone, delete)에 vfolder status값을 관리하는 쿼리를 추가하자. vfolder status에 따라 사용자 접근을 제어하기 위해서 어떤 방법을 사용할까? Pull Request Review 테이블을 추가로 선언하는 것이 과연 필요할까? 라는 의문이 들어서, 이슈 작업을 시작하기 전에 멘토님께 아래와 같은 내용을 문의드렸다. 자주 일어나는 오퍼레이션이 아니므…

September 14, 2022
|
오픈소스
(Backend.AI) 691. Add the commit history between releases in the release notes

Issue Contents #691 release note()에 커밋 히스토리 기록을 추가하도록 를 수정한다. Ideation & Issue Solving 이전에 release된 버전의 tag와 현재 release된 버전의 tag를 얻어와서, 전체 커밋 히스토리를 조회할 수 있는 링크를 CHANGELOG에 추가하면 될 것 같았다. 기능상으로 유의미한 변화를 가져오지는 않지만, 사용자(오픈소스 기여자 및 프로젝트 관리자) 편의성을 충분히 개선시킬 수 있는 작업이라고 생각했다. 스크립트 내부에서 git shell command를 실행하기 위해 라이브러리(파이선 스크립트에서 다른 프로세스를 실행, 출력할 수 있다)를 사용 (1a3063) 이전~현재 버전 사이의 커밋 히스토리는 링크를 통해 조회할 수 있었다. 스크립트를 실행하면 생성되는 에 해당 링크가 추가되도록 수정했다. (1a3063) scripts/extract-release-changelog.py 주요 변경/개선 사항 반영완료…

September 14, 2022
|
오픈소스
@abstractmethod를 통한 SOLID 원칙 적용하기

개요 db에는 여러 종류의 table이 존재하며, 서비스의 business layer에서는 필요에 따라 각 table에 접근하여 query를 수행해야 할 것이다. ORM같은 프레임워크 툴을 사용하지 않고 raw query를 전부 선언하여 사용하는 경우, 이 query들을 어떻게 작성하는게 좋을까? 전부 하나의 class에 method로서 선언하기? create, update등 용도에 따라 분리하기? , , layer를 각각 추상화하여 코드를 작성하며 내가 그리고자 했던 파이선 아키텍쳐가 어떤 모습이었는지 기록해보려 한다. SOLID 원칙: 객체지향설계 5원칙 로버트 마틴이 2000년대 초반에 명명한 객체 지향 프로그래밍 및 설계에 대한 5원칙이다. 코드의 가독성과 확장성을 위한 가장 기본적인 원칙이라고 볼 수 있다 Type Name Description SRP 단일 책임 원칙 (Single Responsibility Principle) 한 클래스는 하나의 책임만 가져야 한다 OC…

February 27, 2022
|
python
파이선의 isinstance 활용하기

Django에서 APIException에 대한 응답 데이터를 재구성하기 에서 api response를 커스터마이징하기 위하여 jsend 포맷을 적용한 renderer를 작성하고 있었다. jsend format 400번대 에러코드를 반환하는 client error들에 대한 format을 작성하려 하는데.. 아래 예시처럼 400을 반환하는 와 나머지 400번대 에러들이 반환하는 data의 type이 달랐다. ValidationError PermissionDenied 처음엔 반환되는 객체의 변수인 (에 정의된 값)를 뽑아와서 400번대 에러를 두 종류로 나누었는데, 특정 에러에 대해서만 이렇게 문자열로 처리를 한다는 것이 영 마음에 들지 않았다. Django에서는 예외처리를 위한 data를 어떻게 구현했을까? Django에서는 함수를 호출하여 에 대한 데이터를 구성하고 있다. 이 함수는 파이선의 built-in method인 를 사용해 data를 구성한다. 이를 활용하여, data …

December 29, 2021
|
python
Django 프로젝트 구조 잡기

장고는 하나의 프로젝트 내에 여러 개의 app이 존재하는 구조이다. 명령으로 app을 생성한 뒤, 에 생성한 app을 등록하여 손쉽게 관리할 수 있다. 아래의 이미지는 명령어를 통해 app을 생성했을 떄의 기본 구조이다. 루트 디렉토리에 장고 서버를 구동하기 위해 필요한 파일이 존재하고, 생성된 app 디렉토리 내부에 , , , 과 같은 파일이 생성된다. 새로운 사이드 프로젝트를 사용하면서도 이러한 디렉토리 구조를 그대로 사용하고 있었는데, 프로젝트가 정리되어 있지 않은 느낌이 있다는 피드백을 들었다. 하지만 과 를 개발용/운영용 환경으로 분리하는 것 외에 프로젝트 구조를 유연하게 설정할 수 있는 방법이 어떤 것이 있을지 감히 잡히지가 않았다. “장고는 프로젝트를 app 단위로 나누어 관리하니까, app을 더 쪼개야 하는건가? 아니면 합쳐서 단순화해야 하는걸까?”와 같은 고민을 하다가.. app을 생성하고 디렉토리가 많아지면서 프로젝트 구조가 난잡하다라는 생각이 종종 들었으니,…

October 17, 2021
|
프레임워크