728x90
반응형

사내 스터디 세미나로 준비한 자료 정리

 

Go 언어를 활용한 마이크로서비스 개발

2장 좋은 API 디자인하기


api 규약 작성이 매우 중요하며 어려움

RESTful API

  • REpresentational State Transfer(표현적 상태 전송)
    • 컴포넌트(서비스 단위) 간 상호작용의 확장성, 범용적인 인터페이스, 컴포넌트의 독립적인 배포를 강조하며 응답 지연시간 감소, 보안 강화, 레거시 시스템의 캡슐화를 위한 중간 컴포넌트 역시 강조한다.

URI, URN, URL

  • RFC 3986
  • URI 형식 지정의 규칙
    • 슬래시(/)는 리소스 사이의 계층적 관계를 나타내는 데 사용
    • URI의 마지막에 슬래시가 포함되어서는 안된다.
    • 하이픈(-) 사용, _ 사용 x
    • 대소문자 구분하므로 소문자 사용 권장

URI 경로

표현설명비고

GET /cats 모든 고양이 컬렉션 명사로 명명
GET /cats/1 1번 고양이를 위한 하나의 문서 db의 행과 비슷. 하위 리소스를 가질 수 있음
GET /cats/1/kittens 1번 고양이의 모든 새끼 고양이들  
POST /cats/1/feed 1번 고양이에게 먹이 주기 컨트롤러: 하위 경로가 없는 URI의 마지막 부분, 동사 사용
POST /cats/1/feed?food=fish 1번 고양이에게 물고기를 먹이로 주기 컨트롤러의 매개변수
PUT /cats/2 2번 고양이 추가(새로운 URI 생성이 아닌 리소스 추가 저장) 컬렉션과 마찬가지로 명사로 명명

REST URI 디자인

  • DELETE /cats/1234: 좋은 예
  • GET /deleteCat/1234: 나쁜 예
  • POST /cats/1234/delete: 나쁜 예
  • HTTP 동사
    • GET / POST / PUT / DELETE / PATCH / HEAD / OPTIONS

응답코드

  • 요청의 성공이나 실패를 클라이언트에게 알려주기 위한 HTTP 응답 코드
  • 즉각적으로 요청의 상태를 알 수 있게 설계

나쁜 응답

POST /kittens RESPOSNE HTTP 200 OK { "status": 401, "statusMessage": "Bad Request" }

POST /kittens RESPOSNE HTTP 200 OK { "id": "123434jvjv4564", "name": "Fat Freddy's Cat" }

  • 좋은 응답은 HTTP 상태 코드를 문자 그대로 사용하는 것

실패 응답의 좋은 예

POST /kittens RESPONSE HTTP 400 BAD REQUEST { "errorMessage": "Name should be between 1 and 256 characters...." }

성공한 응답의 좋은 예:

POST /kittens RESPONSE HTTP 201 CREATED { "id": "123434jvjv4564", "name": "Fat Freddy's Cat" }

HTTP 상태 코드

  • 구글에 더 자세하게 나와있지만 간략하게 정리
  • 200 OK: 요청이 성공했음을 나타내는 일반적인 응답 코드
  • 201 Created(생성): 요청이 성공하고 새 엔티티가 생성된 경우의 응답
  • 204 No Content: 내용 없음. 클라이언트의 요청이 잘 처리되었지만 본문은 없음. DELETE 요청에 대한 응답이 될 수 있음
  • 3xx: 경로 재지정.
  • 4xx: 클라이언트 에러
    • 400 Bad Request / 401 Unauthorized / 404 Not Found / ...
  • 5xx: 서버 오류

mozilla 상태코드 참고 사이트

HTTP 헤더

  • 표준에 맞추면 모두에게 도움이 된다!
  • 표준 요청 헤더
    • 요청에 대한 메타 데이터 개념
    • 요청 및 API 응답에 대한 추가 정보 제공
  • Authorization - 문자열
    • 권한 부여: Authorization key 요청
    • 이런 표준 접근 방식을 따르면 클라이언트가 알아서 구현알 수 있다는데
    • 사실 이걸 어떻게 부여하는지는 잘 모르겠습니다!
  • Date
    • 요청의 타임스탬프
  • Accept - 콘텐츠 타입
    • application/xml
    • text/xml
    • application/json
  • Accept-Encoding - gzip, release
    • REST 엔드 포인트는 가능한 경우 gzip과 deflate 인코딩을 항상 지원해야 한다.
    • gzip 지원은 간단함: 표준 라이브러리의 일부인 compress/gzip 패키지 사용
    • 뉴욕타임즈 오픈소스
    • 비손실 압축을 위한 인코딩,,
  • 에러 리턴
    • API 사용자는 에러가 발생했을 때 여러 앤드 포인트에서 발생한 에러를 처리하는 하나의 코드를 작성할 수 있어야 하는데
    • 표준 에러 엔티티를 제공함으로써 클라이언트 또는 서버로 인한 에러가 발생할 때 클라이언트를 도와줄 수 있음
    • 마이크로소프트의 API 가이드라인 자료

API 버전 관리

  • 초기부텉 고려해야하는 사항, 피할 수 있으면 피하는 것이 좋다!
  • 버전 관리가 필요한 상황
    • 주요 변경 사항이 생기면 API 버전 번호를 증가시키는데 주요 변경사항은
      1. API나 API 매개 변수의 제거 또는 이름 변경
      2. API 매개 변수의 타입 변경(정수 -> 문자열)
      3. 응답 코드, 에러 코드 또는 실패 규약 변경
      4. 기존 API 의 동작 변경
  • 시맨틱 버전 관리
    • 메이저 버전과 마이너 버전: 1.0 에서 1은 메이저, .0은 마이너
    • 마이너의 변경은 클라이언트가 API와 상호작용하는 데 영향을 주지 않음
  • REST API의 버전 관리 형식

객체 타입 표준화

  • 클라이언트에서 객체를 쉽게 처리할 수 있도록 고려
  • JSON을 사용하는 경우 기본 타입으로 날짜 개념이 없다! --> ISO 표준을 사용하는 것이 도움이 된다
    • {"date": "2021-07-08T04:52:57Z"}
    • {"date": {"kind": "U", "value": 1625719977221}

API 문서화

  1. Swagger
  • YAML로 작성
  • 배책임님께서 이전에 소개해주신 API 문서 자동화 도구!
  1. API Blueprint
  • 마크다우능로 작성돼 중첩된 레이어를 다루는 것보다 좀 더 자연스럽게 문서 작성 가능
  1. RAML
  • RESTful API Modeling Language의 약자
  • YAML로 작성

API 문서 자동화 오픈소스(https://github.com/swaggo/swag)

여러가지 참고 링크

728x90
반응형
728x90
반응형

오늘은 2회차 고랭 강의!

자꾸 미뤄서 듣게 된다.. ㅎㅎ 5분도 안되는 영상들인데 뭔가 다른 일들에 밀려 듣게 됨.. ㅎㅎ

 

오늘은 Go syntax 재목의 강의를 요약해 보았다.


Go syntax

 

Case sensitive 함 => 대소문자 구별을 한다는 것

Function, 변수명, 타입이름 등의 Identifier 들은 모두 document에 나와있는 그대로 써야함 

 

변수와 package 이름들은 소문자거나 대소문자 합쳐져있음

그러나 public fields의 첫 글자는 대문자임

 

여기서 첫 글자가 대문자라는 것은 그 symbol은 exported 라는 것!

반대로 말하면 첫 글자가 소문자라는 것은 private이고 대문자면 public.

 

go는 타이핑을 줄임

; <- 와 같은 세미콜론 입력하지 않아도 됨

lexer라는 애가 필요하면 알아서 추가함

그러나 탭이나 띄어쓰기와 같은 whitespace에는 민감하니 조심!

 

Code bloc은 괄호나 대괄호와 같은 braces 로 묶임

 

코드에서 언제나 쓸 수있는 package가 있는데 이것을 builtin package라고 부름

자바에서는 import 해야했던 것을 그냥 쓸 수 있다는 말!

예를 들어 len(string), panic(error),  recover() 과 같은 것들

 

더 참고할 만한 builtin package 설명은 공식문서를 참고!

https://golang.org/pkg/builtin

 

builtin - The Go Programming Language

Package builtin


자바나 다른 언어와 달리 builtin 을 import 없이 쓸 수 있다는 점을 알아차리지 못하고 있었는데 알아차리니 신기하군.. 

깊게 들어가면 어려우니 일단 쓸 수 있게만 써봐야지 ㅎㅎ

728x90
반응형
728x90
반응형

벌써 2주차는 시작되었고 1주차는 오늘 정리한다.

 

지난주 발목뽀각사태로 인해 내내 칩거 아닌 칩거를 했다.

회사는 내내 재택 때리고 집에서 열심히 업무 마무리 & 새로운 업무 사태(?) 파악 ㅋㅋㅋㅋ 을 하고 진짜 집 밖으로는 한 발자국도 나가지 않았다. (목요일 병원 진료 빼고..) 그 와중에 기계처럼 규칙적으로 생활했다.

7시 40분쯤에 일어나서 출근하고.. 일하다가 쉬다가.. 퇴근하고 밥도 먹고 아 옷장 한칸씩 정리하고(재택이라 가능한 것) 띵가띵가 놀다가 1시 조금 안돼서 잠이 든다.

 

그 와중에 몇 가지 하기도 했는데,

 

1. GGLTM 스피치

모임에 온 사람들이 더 많았으면 좋겠지만 몇 안 되는 멤버들이더라도 내가 준비한 연설을 했다. 제목은 "Toastmasters Spirit".

이제 Personal story + 토마 짱! 을 나름 잘 섞어 연설하는데 도가 튼 것 같다. 세계 여행하며 방문한 토마 이야기와 그래서 왜 Toastmasters Spirit이며 왜 주변 사람에게 토마를 추천해야 하는지에 대해 잘 녹여 연설을 했다.

6며으로도 재밌게 연설하고 모임할 수 있다구! + 내가 받은 코멘트 💕

언제나 우리 토마에 함께하고 싶다면 댓글로 남겨주세요 히힛 

 

2. 고랭 스터디

요즘 고랭 스터디를 하고 있다. 사실 업무에서 고랭을 사용하진 않지만 알아두면 좋다 + 고랭 대세(?) 라기에 ㅋㅋㅋ

그리고 단순히 언어를 배운다기보다 언어를 배우며 개발 아키텍처나 개발 방법, 알고리즘 등등 다양하게 커리어에 도움이 될 것 같았다. 어쩌다가 스터디 리더를 맡게 되어 스터디 그룹 신청 등 이것저것 맡아하게 되어 부담스럽기도 하지만 역시 난 리더형이라며 ㅋㅋㅋ 내가 하는 게 편하다며 나름 열심히 하고 있다.

최근에 다룬 개발 방법에는 TDD가 있었다. 그냥 TDD로 문제를 풀고 코드를 올린 게시물이긴 한데 조심스레 투척... https://haonly.tistory.com/76

 

[프로그래머스] 내적 | TDD로 풀어본 연습문제 | 고랭 | Go TDD

사내 스터디에서 TDD를 배워봤다. 앞으로 고랭 문제나 모듈 개발할 때 TDD를 활용하면 좋겠다고 생각했다. 그래서 이번 주 스터디 문제를 TDD로 풀어보았다. 다행히 이번 주 스터디 리더가 쉬운 문

haonly.tistory.com

지금 보니 넘 쉬워서 굳이...? 이긴 싶지만 ㅋㅋㅋ 다음에 기회가 된다면 TDD도 정리해야겠다. 

이 외에 고랭 TDD 테스트 코드 템플릿? 포멧? 도 스터디원들과 공유해서 좋은 코드를 가지고 있으니 공유해야지!!

 

3. 다리는 다쳤지만 클라이밍은 하고 싶어.

일주일 동안 돌을 안 잡고 벽을 안 탔더니 뭔가 답답.. + 살이 조금 찌는 느낌이 들었다. 실제로 몸무게가 1.5kg 정도 늘었다 ㅠㅠ

그래서 턱걸이라도 틈틈이 10개씩 (물론 밴드의 도움을 받아) 해 주었다.

토요일이 되니 다리도 크게 아프지 않고, 살살해볼 만할 것 같아 학교 선배 오빠와 언니 + 형부를(??) 꼬셨다. ㅋㅋㅋㅋ 이게 무슨 조합이야.

언니 + 형부가 삼계탕을 사주어서 몸보신을 하고 암장에 가 올랐다 내렸다 몇 번 해주었다. 

특전사 출신 형부는 첫날부터 엄청 잘해서 신기했고 운동 1도 안 하는 언니는 진짜로 1도 못해서 신기했다. 그래도 다들 재미있었다고 한다!!

근데 내가 클라이밍 했다고 하니 누가 이 사진을 보내줬다. 고통이 없어지더라도 회복이 다 된 것은 아니라는.. ㅋㅋㅋ 조심하겠습니다.

다음날(오늘) 일어나니 몸무게가 2kg가 빠졌고(ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ) 살짝 근육통 + 피곤함이 있다. 

또 평일 한 주는 쉬다가 다음 주말에 살살해봐야지 낄낄 누가 말려~

728x90
반응형
728x90
반응형

사내 스터디에서 TDD를 배워봤다. 

앞으로 고랭 문제나 모듈 개발할 때 TDD를 활용하면 좋겠다고 생각했다.

 

그래서 이번 주 스터디 문제를 TDD로 풀어보았다. 다행히 이번 주 스터디 리더가 쉬운 문제를 내서 TDD로 풀어볼 만했다.

문제는 아주 간단하다. 

문제링크

 

코딩테스트 연습 - 내적

길이가 같은 두 1차원 정수 배열 a, b가 매개변수로 주어집니다. a와 b의 내적을 return 하도록 solution 함수를 완성해주세요. 이때, a와 b의 내적은 a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] 입니다. (n은 a, b의

programmers.co.kr

입출력 예만 간단히 보여주자면 아래와 같다. 

 

나는 이제 이 문제를 그냥 접근해 볼 수도 있었지만 TDD를 활용해 test 코드를 작성하고 풀어보았다.

import (
	"testing"
	"github.com/stretchr/testify/assert"
)

우선 위 두 라이브러리를 import 해서 test 코드를 작성할 수 있도록 해주었다.

그리고 아래와 같이 전체 테스트 코드를 작성해 보았다. 조건이 두 가지뿐이었고 예시 케이스로만 테스트해도 모두 통과하기 때문에 두 예시에 대한 테스트 코드만 작성했다. 

전체 코드

package study_0603_1

import (
	"testing"
	"github.com/stretchr/testify/assert"
)

func Test1(t *testing.T) {
	a := []int{1, 2, 3, 4}
	b := []int{-3, -1, 0, 2}
	assert.Equal(t, 3, solution(a, b))
}

func Test2(t *testing.T) {
	a := []int{-1,0,1}
	b := []int{1, 0, -1}
	assert.Equal(t, -2, solution(a, b))
}

이 테스트 코드에 맞게 main 코드를 작성했다.

solution 코드

package study_0603_1

func solution(a []int, b []int) int {
	ret := 0
	for idx, _ := range a{
		ret += a[idx] * b[idx]
	}
	return ret
}

간단하네!?

 

끝!

728x90
반응형
728x90
반응형

MSA: Microservice Architecture 약자로 문장으로 정리하자면 아래와 같다습니다

"하나의 어플리케이션을 여러개의 작은 어플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아키텍쳐"

 

작은 서비스들을 만들어 합쳐 하나의 어플리케이션으로 만든다는 개념으로 컴포넌트들의 조합이라고 이해했습니다.

 

등장 배경

MSA 반대 개념은 Monolithic Architecture 소프트웨어의 모든 구성요소가 프로젝트에 통합되어 있는 형태입니다.

아직까지 개발하기 간단하다는 장점으로 많은 소프트웨어가 Monolithic 형태로 구현되어 있습니다.

 

하지만 규모의 개발 프로젝트에서는 한계와 단점 존재한다고 합니다. 아무래도 규모의 개발을 진행할 때는 빌드 테스트 하는 시간이 오래걸리고 전체 시스템 구조를 파악하는 것이 쉽지 않기 때문입니다.


제가 이해하기로는 규모의 온라인 주문 사이트에서 MSA 형태의 개발을 하겠구나 싶었습니다.

 

그래서 이번에 고랭으로 MSA에서 흔히 일어날 잇는 상황에 대해서 효율적인 처리를 연습해볼 있도록 Context 사용한 예시를 개발해 보았습니다. (개발 하면 링크 넣을 것… ㅎㅎ)

쿠팡에서 테크 블로그(?) 비슷하게 MSA 에 대해 정리해 글도 있더라구요.

쿠팡 - 행복을 찾기 위한 우리의 여정

 

행복을 찾기 위한 우리의 여정,

쿠팡의 MSA — Part 1

medium.com

 

 

참고할 사이트:

lion-king.tistory.com/entry/MSA-distributed-transaction

 

(MSA 분산 트랜잭션) 주문-재고관리 어떻게 하지?

MSA 분산 트랜잭션 MSA distributed transaction 일반적으로 온라인 커머스 서비스를 하고, 재고가 존재하는 상품을 판매 한다면 주문 - 재고차감- 결제 등의 프로세스가 필요할 것이다. 위 프로세스는 일

lion-king.tistory.com

medium.com/coupang-tech/%ED%96%89%EB%B3%B5%EC%9D%84-%EC%B0%BE%EA%B8%B0-%EC%9C%84%ED%95%9C-%EC%9A%B0%EB%A6%AC%EC%9D%98-%EC%97%AC%EC%A0%95-94678fe9eb61

 

행복을 찾기 위한 우리의 여정,

쿠팡의 MSA — Part 1

medium.com

www.popit.kr/msa%EC%97%90%EC%84%9C-%EB%A9%94%EC%8B%9C%EC%A7%95-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98-%EC%B2%98%EB%A6%AC%ED%95%98%EA%B8%B0

 

MSA에서 메시징 트랜잭션 처리하기 | Popit

비동기 메시지를 사용하여 상호 간에 통신하는 방식을 메시징 Messaging[1] 이라고 부른다. 마이크로서비스 환경에서 비동기 처리 시 보통 카프카 Kafka 나 래빗엠큐 RabbitMQ 같은 메시지 브로커 Message

www.popit.kr

velog.io/@tedigom/MSA-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-1-MSA%EC%9D%98-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-3sk28yrv0e

 

MSA 제대로 이해하기 -(1) MSA의 기본 개념

lego-708086_1920.jpg 마이크로 서비스 아키텍쳐를 한마디로 다음과 같이 표현할 수 있습니다. "하나의 큰 어플리케이션을 여러개의 작은 어플리케이션으로 쪼개어 변경과 조합이 가능하도록 만든 아

velog.io

jaehue.github.io/post/how-to-use-golang-context/

 

728x90
반응형
728x90
반응형

심심하니까 푸는 프로그래머스 코테 문제

 

이번에 푼 문제는 '완주하지 못한 선수'

 

코딩테스트 연습 - 완주하지 못한 선수

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다. 마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수

programmers.co.kr

문제 캡쳐본

예전에 한 번 C++로 풀어봤다. 이런저런 방법으로 풀다가 결국 해설을 봤던 것 같다.

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

string solution(vector<string> participant, vector<string> completion) {
    string answer = "";
    sort(participant.begin(), participant.end());
    sort(completion.begin(), completion.end());
    
    for(int i = 0; i < participant.size(); i++){
        if(participant[i] != completion[i])
            return participant[i];
    }

    return participant[participant.size()];
}

 


 

이번에 고랭으로 풀어보려고 했는데 C++로 어떻게 풀었는지 이미 봐버려서 그대로 풀어버렸습니다 ㅠㅠ  근데 이 문제는 고랭은 지원하지 않아서 그냥 맞겠지 하고 풀었어요 ㅎㅎ

package main

import (
	"fmt"
	"sort"
)

func solution(participant []string, completion []string) string {
	sort.Strings(participant)
	sort.Strings(completion)
	
	for i:=0; i < len(completion); i++{
		if(participant[i] != completion[i]){
			return participant[i]
		}
	}
	return participant[len(participant)-1]
}

func main() {
	participant := []string{"leo", "kiki", "eden"}
	completion := []string{"eden", "kiki"}
	ret := solution(participant, completion)
	fmt.Println(ret)
}

sort 내장 모듈을 지원해주니 이 모듈을 사용했고 정확히 C++로 푼 방법과 똑같이 풀어버렸습니다 ㅋㅋㅋ 그래도 고랭 익숙해지는 거라고 생각하면 여전히 문제 풀어보는 건 좋지요!

728x90
반응형

+ Recent posts