func createUserHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
return
}
var newUser User
if err := json.NewDecoder(r.Body).Decode(&newUser); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
newUser.ID = len(users) + 1
users = append(users, newUser)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(newUser)
}
그리고 라우터에 추가합니다.
func main() {
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
getUsersHandler(w, r)
case http.MethodPost:
createUserHandler(w, r)
default:
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
}
})
log.Println("✅ Server started on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
이제 POST /users 로 아래 JSON을 전송하면 새로운 유저가 추가됩니다.
{
"name": "Siyu",
"email": "siyu@example.com"
}
🧱 4. Clean Architecture 구조로 개선하기
실무에서는 코드가 점점 커지기 때문에 핸들러, 서비스, 모델, 라우터를 분리합니다. 폴더 구조를 아래처럼 변경해보세요 👇
package handler
import (
"encoding/json"
"net/http"
"example.com/go-rest-api/model"
"example.com/go-rest-api/service"
)
func GetUsersHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(service.GetAllUsers())
}
func CreateUserHandler(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
var user model.User
if err := json.NewDecoder(r.Body).Decode(&user); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
created := service.AddUser(user)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(created)
}
main.go
package main
import (
"log"
"net/http"
"example.com/go-rest-api/handler"
)
func main() {
http.HandleFunc("/users", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodGet:
handler.GetUsersHandler(w, r)
case http.MethodPost:
handler.CreateUserHandler(w, r)
default:
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
}
})
log.Println("🚀 Go REST API Server started on port 8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
이제 구조가 깔끔해졌습니다! 핸들러 → 서비스 → 모델 순으로 역할이 분리되어 유지보수가 훨씬 쉬워집니다.
Go는 정적 타이핑 언어라서, JSON 데이터를 다루기 전에 구조체(struct)를 정의해야 합니다.
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
jsonData := []byte(`{"name":"Heejune","age":35}`)
var p Person
if err := json.Unmarshal(jsonData, &p); err != nil {
panic(err)
}
fmt.Println(p.Name) // Heejune
// 다시 JSON으로 변환
newData, _ := json.Marshal(p)
fmt.Println(string(newData))
}
이처럼 Go에서는:
구조체 필드를 미리 정의해야 하고,
JSON 태그(json:"name")를 붙여야 하며,
Unmarshal / Marshal 과정을 거쳐야 합니다.
🤔 왜 이렇게 복잡할까?
Go는 **명시적 타입 안정성(type safety)**을 매우 중요하게 여깁니다. Python처럼 자유롭게 다루는 대신, 데이터 구조를 컴파일 시점에 보장받습니다.
그래서 런타임 오류는 줄어들지만, 코드 작성량은 늘어나는 단점이 있습니다.
💡 실무 팁: interface{}를 이용한 유연한 파싱
정확한 구조체가 정해져 있지 않다면 아래처럼 map[string]interface{}로 처리할 수도 있습니다.
var data map[string]interface{}
json.Unmarshal([]byte(`{"x":10,"y":20}`), &data)
fmt.Println(data["x"]) // 10
하지만 이 경우에도 타입 캐스팅이 필요합니다:
x := data["x"].(float64)
즉, Go는 JSON을 “안전하게” 다루기 위해 의도적으로 복잡하게 만들어둔 셈입니다.
4. Go의 실제 활용 분야
분야
설명
백엔드 서버
고성능 REST API, gRPC 서버
DevOps 도구
Terraform, Docker, Kubernetes
클라우드 서비스
마이크로서비스 기반 시스템
CLI 유틸리티
단일 실행파일 배포형 도구
보안 및 네트워크
스캐너, 로그 파서, 프록시 서버
5. Go vs Python — JSON과 개발 경험 비교
항목
Go
Python
문법 난이도
중간
쉬움
타입 안정성
강함 (정적 타이핑)
약함 (동적 타이핑)
JSON 처리
구조체 정의 필요
바로 dict 접근 가능
실행 속도
빠름
느림
유지보수
안정적
유연하지만 위험
런타임 오류
거의 없음
발생 가능
➡ 정리하자면:
Go는 명시적이고 안전한 언어,
Python은 유연하고 빠른 언어입니다.
둘 다 JSON을 잘 다루지만, Go는 “안전성”을 위해 복잡해졌고, Python은 “개발 속도”를 위해 단순해졌다고 할 수 있습니다.
6. 결론 — 단순함 속의 안정성
Go는 처음엔 약간의 불편함이 있습니다. 특히 JSON 처리처럼 “동적 데이터”를 다룰 땐 Python보다 더 많은 코드를 써야 하죠.
하지만 일단 익숙해지면, Go의 명시적인 설계는 버그를 예방하고 대규모 서비스를 안정적으로 유지하게 해줍니다.
Terraform은 HashiCorp에서 만든 IaC(Infrastructure as Code) 도구로, 인프라(서버, 네트워크, DB, IAM 등)를 선언형 구성 파일(HCL) 로 정의하고, plan/apply 명령을 통해 실제 인프라를 자동으로 생성·변경·삭제할 수 있게 해줍니다.
Terraform은 AWS, Azure, GCP뿐 아니라 VMware, GitHub, Kubernetes, Docker 등 수백 개의 Provider를 지원하여 멀티클라우드 인프라 자동화에 최적화되어 있습니다.
팀 협업 시 DynamoDB Lock(또는 Remote State Lock)으로 충돌 방지
민감 정보(State 내 포함 주의): 비밀은 별도 Parameter Store 또는 Vault에 저장
🌐 Terraform 실전 적용 사례 — 도커 기반 웹 인프라 구축
현재 저는 Terraform을 이용해 백엔드와 프론트엔드를 모두 도커 이미지 기반으로 배포하는 환경을 운영하고 있습니다. 모든 인프라는 Terraform 코드 한 세트로 관리되며, AWS의 ECS(Fargate)와 ALB, 오토스케일링 정책을 활용해 유연하고 자동화된 웹 인프라 구조를 만들었습니다.
요즘 “클라우드”라는 단어, 정말 많이 들어보셨을 겁니다. 기업 홍보 문구에도, TV 광고에도, 심지어 스마트폰 설정에도 빠지지 않죠. 그런데 막상 “클라우드가 정확히 뭐야?”라고 물으면 쉽게 설명하기가 어렵습니다.
💡 클라우드의 개념 — 내 컴퓨터 밖의 컴퓨터
가장 간단히 말하면, 클라우드(Cloud) 는 “내가 직접 가지지 않은 컴퓨터(서버)를 빌려서 사용하는 기술”입니다.
예전에는 서비스나 프로그램을 운영하려면 직접 서버를 사고, 전기·네트워크·보안까지 관리해야 했습니다. 하지만 지금은 AWS(Amazon Web Services) 같은 클라우드 서비스를 이용하면 원격으로 서버를 빌리고, 클릭 몇 번으로 웹사이트·앱·AI 모델까지 바로 실행할 수 있습니다.
즉, 클라우드는 ‘인터넷을 통해 빌려 쓰는 거대한 컴퓨터 자원’ 이라고 보면 됩니다.
🏗️ 클라우드는 이렇게 나뉩니다
1️⃣ IaaS (Infrastructure as a Service)
“서버나 저장공간 같은 인프라를 통째로 빌리는 서비스”
대표: AWS EC2, Google Compute Engine, Azure VM
예시: 물리 서버를 직접 사지 않고, AWS에서 가상 서버를 생성해 사용하는 것
사용자는 운영체제부터 직접 설치 가능 → 자유도 높지만 관리 부담도 있음
2️⃣ PaaS (Platform as a Service)
“개발에 필요한 환경을 통째로 제공”
대표: AWS Elastic Beanstalk, Google App Engine
예시: 코드만 올리면 자동으로 서버, 네트워크, 스케일링 설정
인프라 관리 부담이 줄고, 개발에만 집중할 수 있음
3️⃣ SaaS (Software as a Service)
“설치 없이 바로 쓰는 온라인 소프트웨어”
대표: Google Drive, Notion, Slack
예시: 웹 브라우저로 로그인만 하면 바로 사용 가능
서버나 업데이트는 전부 제공업체가 관리
⚙️ AWS로 보는 클라우드의 실제 동작
AWS는 클라우드의 대표 주자입니다. 아마존은 전 세계 데이터센터를 묶어서 누구나 인터넷만 있으면 서버·스토리지·AI·보안 서비스를 빌려 쓸 수 있도록 만들었죠.
예를 들어,
서비스
역할
비유
EC2
가상 서버 (CPU·RAM)
“컴퓨터 본체를 빌리는 것”
S3
저장소
“외장하드나 NAS를 빌리는 것”
RDS
데이터베이스
“SQL 서버를 대신 운영해주는 것”
CloudFront
콘텐츠 전송 네트워크
“전 세계에 복사된 CDN”
Lambda
서버리스 함수 실행
“필요할 때만 잠깐 빌려 쓰는 계산기”
💰 클라우드의 가장 큰 장점 — ‘필요할 때, 필요한 만큼만’
클라우드의 핵심은 바로 유연성(Flexibility) 입니다.
💸 필요한 만큼만 비용 지불 → 사용한 만큼만 과금(전기세처럼)
⚡ 즉시 확장 가능 → 사용자가 늘어나면 자동으로 서버 증설
🔐 보안과 백업 내장 → 데이터는 여러 지역에 복제되어 안전하게 보관
🌍 언제 어디서나 접근 가능 → 개발자나 관리자가 전 세계 어디서든 접속 가능
🧩 왜 기업들이 클라우드로 옮길까?
비용 절감 – 서버를 직접 구매·운영할 필요가 없음
유연한 확장 – 트래픽 급증에도 빠르게 대응 가능
서비스 안정성 – AWS 등은 99.9% 가용성을 보장
보안 강화 – 보안 인증, 모니터링, 자동 업데이트 지원
빠른 실험과 배포 – 클릭 몇 번으로 새로운 환경을 구축 가능
🚀 클라우드는 개발 방식을 완전히 바꿨다
과거엔 서버 한 대 사려면 몇 주 걸렸지만, 지금은 5분 만에 전 세계에 서비스를 배포할 수 있습니다.
개발자 입장에서 클라우드는 “서버 걱정 없는 세상”이자, 비즈니스 입장에서는 “빠르게 실험하고 성장할 수 있는 플랫폼”입니다.
🧠 정리 — 클라우드는 결국 ‘시간을 사는 기술’
구분
예전 방식
클라우드 방식
서버 구매
직접 구매
클릭으로 생성
비용
초기 투자
사용량 기반 과금
확장
수작업
자동 스케일링
위치
한 곳
전 세계 데이터센터
보안
직접 설정
내장 정책 + 인증
즉, 클라우드는 단순한 기술이 아니라 ‘시간과 유연성을 구매하는 방법’입니다.
📌 결론
AWS처럼 클라우드는 우리가 사용하는 모든 IT 자원을 인터넷 위로 옮겨온 것입니다. 이제 중요한 건 ‘서버를 어떻게 설치하느냐’가 아니라, ‘어떤 아이디어를 얼마나 빨리 실현하느냐’ 입니다.