# Go 웹 개발에 대한 몇가지 노트

> Clean Markdown view of GeekNews topic #16990. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=16990](https://news.hada.io/topic?id=16990)
- GeekNews Markdown: [https://news.hada.io/topic/16990.md](https://news.hada.io/topic/16990.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-09-30T09:51:10+09:00
- Updated: 2024-09-30T09:51:10+09:00
- Original source: [jvns.ca](https://jvns.ca/blog/2024/09/27/some-go-web-dev-notes/)
- Points: 24
- Comments: 2

## Summary

Go 1.22부터는 표준 라이브러리에서 더 나은 라우팅을 지원하며, 로그인 미들웨어 추가로 보안을 강화 할 수 있습니다. sqlc 도구를 사용하면 ORM 없이도 SQL 쿼리를 쉽게 작성하고 Go 코드로 자동 변환 가능합니다. Go 1.19부터 추가된 기능인 `GOMEMLIMIT` 설정으로 메모리 사용량을 효율적으로 관리할 수 있습니다. Go로 웹사이트를 만들면 내장 웹서버를 가지는 단일 정적 바이너리로 배포가 간편합니다.

## Topic Body

### Go 1.22부터 표준 라이브러리에서 더 나은 라우팅 지원을 제공함  
- 기존에는 수동으로 라우팅을 처리했으나, 이제는 `mux.HandleFunc`을 사용하여 간단하게 라우팅 가능  
- 로그인 미들웨어를 추가하여 보안 강화 가능  
  
### 내장 라우터의 주의사항: 후행 슬래시로 인한 리디렉션  
- `/records/` 경로를 만들면 `/records` 요청이 `/records/`로 리디렉션됨  
- 이로 인해 POST 요청의 본문이 제거되어 GET 요청으로 변경되는 문제가 발생할 수 있음  
- 해결책은 `POST /records/` 대신 `POST /records`와 같은 API 엔드포인트를 사용하는   
  
### sqlc로 데이터베이스 쿼리 코드 자동 생성  
- ORM을 배우지 않고도 SQL 쿼리를 작성할 수 있는 sqlc 도구 발견  
- SQL 쿼리를 작성하면 Go 코드로 자동 변환됨  
- ORM의 문서를 참조하지 않고도 필요한 SQL 쿼리를 쉽게 작성 가능  
  
### sqlite 최적화 팁  
- 데이터베이스에 쓰기 전용 객체를 사용하고 `db.SetMaxOpenConns(1)` 설정  
- 읽기 속도를 높이려면 쓰기용과 읽기용으로 별도의 DB 객체를 사용  
- JOIN이 필요 없는 두 개의 테이블은 별도의 데이터베이스에 넣어 독립적으로 연결 가능ㅍ  
  
### Go 1.19의 GC 메모리 제한 설정  
- 256MB 또는 512MB와 같이 메모리가 상대적으로 적은 VM에서 모든 Go 프로젝트를 실행하면 애플리케이션이 계속 OOM으로 종료되는 문제 발생  
- 가비지 컬렉터 기본 설정으로 인해 현재 힙 크기의 2배까지 메모리 할당을 허용  
- Go 1.19에서 애플리케이션이 특정 메모리 사용량에 도달하면 GC를 실행하도록 지시하는 방법이 추가됨  
- GC 메모리 제한을 250MB로 설정한 후 OOM 종료 빈도가 줄어듦 ```export GOMEMLIMIT=250MiB```  
  
### Go로 웹사이트를 만드는 이유  
- 단일 정적 바이너리로 배포가 간편함  
- 프로덕션에서 사용할 수 있는 내장 웹서버가 있어 WSGI 등을 구성할 필요가 없음  
- Go의 도구 체인이 설치 및 사용이 간편함  
- HTTP 응답을 보내는 것이 간단하여 프로젝트 유지보수가 쉬움  
- 표준 라이브러리에 `net/http`가 포함되어 있어 추가 라이브러리 설치 없이 웹사이트 제작 가능  
- 시스템 수준의 작업도 쉽게 수행 가능  
- 모든 것이 프로젝트를 쉽게 다룰 수 있도록 만들어진 것 같음  
  
### 아직 해결하지 못한 문제들  
- Go에서 아직 많이 해보지 않은 것들  
  - HTML 템플릿 렌더링  
  - 실제 로그인 시스템 구현  
  - CSRF 구현  
- 일반적으로 보안에 민감한 기능을 구현하는 방법을 잘 모르기 때문에 로그인/CSRF 등이 필요한 프로젝트는 시작하지 않음  
  
### Go의 새로운 기능을 보는 것이 멋짐  
- 이 글에서 언급한 두 가지 Go 기능(`GOMEMLIMIT`와 라우팅)은 지난 몇 년 동안 새로 추가된 것  
- 새로운 Go 버전에 대한 릴리스 노트에 더 주의를 기울여야 할 것 같음

## Comments



### Comment 29508

- Author: secret3056
- Created: 2024-09-30T11:10:51+09:00
- Points: 1

sqlc 정말 좋습니다

### Comment 29482

- Author: neo
- Created: 2024-09-30T09:51:10+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=41687707) 
- Go 언어는 프로젝트를 5일 동안 작업하고 2년 동안 방치한 후에도 문제없이 다시 코딩할 수 있게 해줌
- Go 언어는 몇 년 전부터 배우기 시작했지만 크게 변하지 않아 오랜 시간이 지나도 여전히 유용함
- Go 언어의 웹 개발 포스트에서 `embed` 패키지가 언급되지 않은 것이 아쉬움
  - 단일 바이너리로 정적 리소스를 번들링하는 것이 매우 편리함
- 데이터베이스 트랜잭션은 실패하도록 설계되었기 때문에 항상 재시도 루프를 사용해야 함
  - 트랜잭션 루프에 `Context`를 추가하여 취소할 수 있도록 하는 것이 좋음
- `sqlc`는 몇 가지 주요 제한 사항과 사소한 불편함이 있어 사용하기 전에 이슈 목록을 확인하는 것이 좋음
  - 동적 쿼리, 일대다 관계, 임베디드 CTE, 복합 타입 등을 지원하지 않음
  - 간단한 요구사항에는 적합하지만 복잡한 작업에는 수동 접근 방식을 사용해야 함
- Go를 컨테이너 내에서 실행할 때 `GOMAXPROCS`를 적절히 설정하여 CPU 스로틀링을 피해야 함
- `GOMEMLIMIT`을 사용하면 GC에 대한 걱정을 줄일 수 있음
  - Kubernetes나 Docker를 사용할 때 자동으로 설정할 수 있음
- `html/template`는 이상하고 많은 문제를 가지고 있어 사용하지 않는 것이 좋음
  - 대신 `Templ`을 선호함
- 라우팅에 대한 언급이 반가움
  - 오랫동안 `mux`에 익숙해져 있었지만 새로운 릴리스 기능을 주목하지 않았음
- 새로운 직장에서 한 달 동안 Go를 사용했지만 싫어함
  - Go는 지난 20년간의 언어 개발에서 아무것도 배우지 않은 것 같음
  - `nil` 문제로 인해 간단한 작업도 복잡해짐
- SQLite를 사용할 때 단일 쓰레드 작성자 풀과 다른 읽기 풀을 사용하는 것이 좋음
  - `BEGIN CONCURRENT`를 사용하여 동시성을 개선할 수 있음
- Go의 단순성과 프레임워크 의존성이 없는 점을 사랑함
  - 표준 라이브러리와 검증된 서드파티 라이브러리만으로도 훌륭한 것을 만들 수 있음
  - 웹 앱이나 CLI 도구를 만들 때 Go가 적합함
  - 명시적인 오류 처리를 좋아함
  - 큰 Go 팬임
