Slide 1

Slide 1 text

Go 언어로 쉽고 빠르게 서버 만들기 1

Slide 2

Slide 2 text

GDG Golang Korea Flutter Seoul 2

Slide 3

Slide 3 text

Go 언어로 쉽고 빠르게 서버 만들기 Index 1. Go Programming Language 2. The Basic of Go 3. Go 언어 서버 개발 3

Slide 4

Slide 4 text

1. Go Programming Language Go 언어로 쉽고 빠르게 서버 만들기 4

Slide 5

Slide 5 text

Go 언어로 쉽고 빠르게 서버 만들기 5

Slide 6

Slide 6 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language ● November 10, 2009 (14 years ago) ● Robert Griesemer ● Rob Pike ● Ken Thompson @source: https://youtu.be/sln-gJaURzk?feature=shared 6

Slide 7

Slide 7 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language ● November 10, 2009 (14 years ago) @source:https://www.youtube.com/watch?v=rKnDgT73v8s 7

Slide 8

Slide 8 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 8

Slide 9

Slide 9 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language ● Cloud & Network Services ● Command-line Interfaces (CLIs) ● Web Development ● Development Operations & Site Reliability Engineering 9

Slide 10

Slide 10 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 10

Slide 11

Slide 11 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language ● 컴파일 언어 & 정적 타입 ● 간결한 문법 ● Concurrency ● GC (Garbage Collector) ● 크로스 플랫폼 지원 11

Slide 12

Slide 12 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 12 @source: https://github.com/e3b0c442/keywords

Slide 13

Slide 13 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 13 @source: https://go.dev/ref/spec

Slide 14

Slide 14 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 14 https://pkg.go.dev/

Slide 15

Slide 15 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 15 https://go.dev/play/

Slide 16

Slide 16 text

2. The Basic of Go Go 언어로 쉽고 빠르게 서버 만들기 16

Slide 17

Slide 17 text

Go 언어로 쉽고 빠르게 서버 만들기 17 https://go.dev/dl/

Slide 18

Slide 18 text

Go 언어로 쉽고 빠르게 서버 만들기 Go Programming Language 18 package main import "fmt" func main() { fmt.Println("Hello, 世界") }

Slide 19

Slide 19 text

Go | Variables Go 언어로 쉽고 빠르게 서버 만들기 19 package main import "fmt" func main() { var number1 int = 10 // 정수형 변수 선언과 초기화 var number2 = 20 // 타입 추론을 통해 int 타입으로 선언됨 number3 := 30 // := 연산자를 사용한 짧은 변수 선언과 초기화 // 문자열 변수 선언과 초기화 var message string = "Hello, Go!" message2 := "안녕하세요, 고!" // 변수 값 출력 fmt.Println("Number 1:", number1) fmt.Println("Number 2:", number2) }

Slide 20

Slide 20 text

Go | Type | Numeric types Go 언어로 쉽고 빠르게 서버 만들기 20 uint8 the set of all unsigned 8-bit integers (0 to 255) uint16 the set of all unsigned 16-bit integers (0 to 65535) uint32 the set of all unsigned 32-bit integers (0 to 4294967295) uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) int8 the set of all signed 8-bit integers (-128 to 127) int16 the set of all signed 16-bit integers (-32768 to 32767) int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) float32 the set of all IEEE-754 32-bit floating-point numbers float64 the set of all IEEE-754 64-bit floating-point numbers complex64 the set of all complex numbers with float32 real and imaginary parts complex128 the set of all complex numbers with float64 real and imaginary parts byte alias for uint8 rune alias for int32

Slide 21

Slide 21 text

Go | Type | Array Go 언어로 쉽고 빠르게 서버 만들기 21 func main() { var numbers [3]int // 크기가 3인 정수형 배열 선언과 초기화 numbers[0] = 10 // 배열 요소에 값 할당 numbers[1] = 20 numbers[2] = 30 fmt.Println("Numbers array:", numbers) // 배열 요소 출력 // 배열의 각 요소 출력 for i := 0; i < len(numbers); i++ { fmt.Printf("Index: %d, Value: %d\n", i, numbers[i]) } }

Slide 22

Slide 22 text

Go | Type | Slice Go 언어로 쉽고 빠르게 서버 만들기 22 func main() { var myList []string // 문자열 슬라이스 선언과 초기화 numbers := []int{1, 2, 3, 4, 5} // 문자열 슬라이스 선언과 초기화 fruits := []string{"apple", "banana", "orange", "grape", "kiwi"} myList = append(myList, "apple") // 슬라이스에 요소 추가 myList = append(myList, "banana") fmt.Println("My List:", myList) // 슬라이스 출력 fmt.Println("Length of my list:", len(myList)) // 슬라이스 길이 출력 // 슬라이스의 각 요소 출력 for index, value := range myList { fmt.Printf("Index: %d, Value: %s\n", index, value) } }

Slide 23

Slide 23 text

Go | If statements Go 언어로 쉽고 빠르게 서버 만들기 23 func main() { // 변수 선언 age := 20 // if 문 사용 if age > 18 { fmt.Println("성인입니다.") } else { fmt.Println("미성년자입니다.") } } // if 문 안에서 변수 선언과 초기화 후 조건 처리 if age := 20; age > 18 { fmt.Println("성인입니다.") } else { fmt.Println("미성년자입니다.") }

Slide 24

Slide 24 text

Go | for statements Go 언어로 쉽고 빠르게 서버 만들기 24 func main() { // 1부터 10까지의 숫자 출력 for i := 1; i <= 10; i++ { fmt.Println(i) } } for { fmt.Println("무한 루프") } // 슬라이스 순회 for index, value := range numbers { fmt.Printf("인덱스: %d, 값: %d\n", index, value) } i := 0 // 조건식만 사용한 for 루프 for i < 5 { fmt.Println(i) i++ }

Slide 25

Slide 25 text

Go | switch statements Go 언어로 쉽고 빠르게 서버 만들기 25 func main() { fruit := "apple" switch fruit { case "apple": fmt.Println("사과입니다.") case "banana": fmt.Println("바나나입니다.") case "orange": fmt.Println("오렌지입니다.") default: fmt.Println("다른 과일입니다.") } }

Slide 26

Slide 26 text

Go | function Go 언어로 쉽고 빠르게 서버 만들기 26 // multiplyAndDivide 함수 정의: 두 개의 정수를 받아 곱과 나눗셈의 결과를 반환 func multiplyAndDivide(x, y int) (int, float64) { multiplyResult := x * y divideResult := float64(x) / float64(y) return multiplyResult, divideResult } func main() { // multiplyAndDivide 함수 호출하여 결과 출력 multiplyResult, divideResult := multiplyAndDivide(10, 5) fmt.Println("곱셈 결과:", multiplyResult) fmt.Println("나눗셈 결과:", divideResult) }

Slide 27

Slide 27 text

Go | defer Go 언어로 쉽고 빠르게 서버 만들기 27 func main() { // 파일을 열기 위해 os.Open 호출 file, err := os.Open("example.txt") if err != nil { fmt.Println("파일을 열 수 없습니다:", err) return } // 함수가 종료되기 직전에 파일을 닫음 (defer 사용) defer file.Close() // 파일에서 데이터를 읽기 위해 필요한 코드 // (이 코드는 파일을 닫기 전까지 실행되지 않음) fmt.Println("파일을 성공적으로 열었습니다.") }

Slide 28

Slide 28 text

Go | error handler Go 언어로 쉽고 빠르게 서버 만들기 28 func divide(x, y float64) (float64, error) { if y == 0 { return 0, errors.New( "나누는 수는 0이 될 수 없습니다.") } return x / y, nil } func main() { // divide 함수 호출하여 결과 출력 result, err := divide(10, 2) if err != nil { fmt.Println("오류 발생:", err) } else { fmt.Println("나눗셈 결과:", result) } // 0으로 나누는 경우 에러 발생 result, err = divide(10, 0) if err != nil { fmt.Println("오류 발생:", err) } else { fmt.Println("나눗셈 결과:", result) } }

Slide 29

Slide 29 text

Go | channel Go 언어로 쉽고 빠르게 서버 만들기 29 ch := make(chan int) // 정수형 채널 생성 ch <- 10 // 정수 10을 채널 ch에 보냄 x := <-ch // 채널 ch에서 값을 받아 변수 x에 할당 close(ch) // 채널 ch를 닫음 // 값 보내기만 가능한 채널 func sendOnly(ch chan<- int) { ch <- 10 } // 값 받기만 가능한 채널 func receiveOnly(ch <-chan int) { x := <-ch }

Slide 30

Slide 30 text

Go | Goroutines Go 언어로 쉽고 빠르게 서버 만들기 30 // 고루틴에서 수행될 함수 func worker(id int, jobs <-chan int, results chan<- int) { for job := range jobs { fmt.Printf("Worker %d is processing job %d\n", id, job) time.Sleep(time.Second) // 일부러 1초간 대기 results <- job * 2 // 작업의 결과를 결과 채널로 전송 } } func main() { // 작업을 보낼 채널과 결과를 받을 채널 생성 jobs := make(chan int, 5) results := make(chan int, 5) // 고루틴으로 여러 개의 worker 실행 for w := 1; w <= 3; w++ { go worker(w, jobs, results) } // 작업 보내기 for j := 1; j <= 5; j++ { jobs <- j } close(jobs) // 모든 작업이 전송되었음을 알림 // 모든 결과 수신 for a := 1; a <= 5; a++ { result := <-results fmt.Println("Received result:", result) } }

Slide 31

Slide 31 text

3. Go 언어 서버 개발 Go 언어로 쉽고 빠르게 서버 만들기 31

Slide 32

Slide 32 text

A REST API (also known as RESTful API) Socket gRPC etc… Go 언어로 쉽고 빠르게 서버 만들기 32

Slide 33

Slide 33 text

● GET → The GET method requests a representation of the specified resource. Requests using GET should only retrieve data. ● POST → The POST method submits an entity to the specified resource, often causing a change in state or side effects on the server. ● PUT → The PUT method replaces all current representations of the target resource with the request payload. ● DELETE → The DELETE method deletes the specified resource. Go 언어로 쉽고 빠르게 서버 만들기 33 @source: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods Http Methods

Slide 34

Slide 34 text

Go 언어로 쉽고 빠르게 서버 만들기 34 @source: https://pkritiotis.io/clean-architecture-in-golang/ Architecture example

Slide 35

Slide 35 text

프로필 정보를 가져오는 CRUD 서버 Create, Read, Update, Delete Go 언어로 쉽고 빠르게 서버 만들기 35 아이디, 유저명, 이메일

Slide 36

Slide 36 text

Go 언어로 쉽고 빠르게 서버 만들기 36 package main import ( "encoding/json" "fmt" "net/http" ) net/http

Slide 37

Slide 37 text

Go 언어로 쉽고 빠르게 서버 만들기 37 package main import ( "encoding/json" "fmt" "net/http" ) encoding/json

Slide 38

Slide 38 text

Go 언어로 쉽고 빠르게 서버 만들기 38 // Profile 구조체 정의 type Profile struct { ID string `json:"id"` Username string `json:"username"` Email string `json:"email"` } struct 역따옴표 var profiles = make(map[string]Profile)

Slide 39

Slide 39 text

Go 언어로 쉽고 빠르게 서버 만들기 39 func createProfile(w http.ResponseWriter, r *http.Request) { var profile Profile err := json.NewDecoder(r.Body).Decode(&profile) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } profiles[profile.ID] = profile w.WriteHeader(http.StatusCreated) } create

Slide 40

Slide 40 text

Go 언어로 쉽고 빠르게 서버 만들기 40 func getProfile(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id") if id == "" { // ID가 비어있을 경우 모든 프로필을 조회 profileList := make([]Profile, 0, len(profiles)) for _, profile := range profiles { profileList = append(profileList, profile) } json.NewEncoder(w).Encode(profileList) return } } read

Slide 41

Slide 41 text

Go 언어로 쉽고 빠르게 서버 만들기 41 func getProfile(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id") if id == "" { // ID가 비어있을 경우 모든 프로필을 조회 profileList := make([]Profile, 0, len(profiles)) for _, profile := range profiles { profileList = append(profileList, profile) } json.NewEncoder(w).Encode(profileList) return } } read

Slide 42

Slide 42 text

Go 언어로 쉽고 빠르게 서버 만들기 42 read // ID가 존재할 경우 해당 ID에 대한 프로필을 조회 profile, ok := profiles[id] if !ok { http.Error(w, "Profile not found", http.StatusNotFound) return } json.NewEncoder(w).Encode(profile)

Slide 43

Slide 43 text

Go 언어로 쉽고 빠르게 서버 만들기 43 func updateProfile(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id") var updatedProfile Profile err := json.NewDecoder(r.Body).Decode(&updatedProfile) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } _, ok := profiles[id] if !ok { http.Error(w, "Profile not found", http.StatusNotFound) return } profiles[id] = updatedProfile w.WriteHeader(http.StatusOK) } update

Slide 44

Slide 44 text

Go 언어로 쉽고 빠르게 서버 만들기 44 func deleteProfile(w http.ResponseWriter, r *http.Request) { id := r.URL.Query().Get("id") _, ok := profiles[id] if !ok { http.Error(w, "Profile not found", http.StatusNotFound) return } delete(profiles, id) w.WriteHeader(http.StatusOK) } delete

Slide 45

Slide 45 text

Go 언어로 쉽고 빠르게 서버 만들기 45 func main() { mux := http.NewServeMux() mux.HandleFunc("/create", createProfile) mux.HandleFunc("/get", getProfile) mux.HandleFunc("/update", updateProfile) mux.HandleFunc("/delete", deleteProfile) server := &http.Server{ Addr: ":8080", Handler: mux, } fmt.Println("Server is listening on port 8080...") server.ListenAndServe() }

Slide 46

Slide 46 text

좀 더 개선해볼까요? Go 언어로 쉽고 빠르게 서버 만들기 46

Slide 47

Slide 47 text

Go 언어로 쉽고 빠르게 서버 만들기 47 package http // Common HTTP methods. // Unless otherwise noted, these are defined in RFC 7231 section 4.3. const ( MethodGet = "GET" MethodHead = "HEAD" MethodPost = "POST" MethodPut = "PUT" MethodPatch = "PATCH" // RFC 5789 MethodDelete = "DELETE" MethodConnect = "CONNECT" MethodOptions = "OPTIONS" MethodTrace = "TRACE" )

Slide 48

Slide 48 text

Go 언어로 쉽고 빠르게 서버 만들기 48 switch r.Method { case http.MethodGet: // Serve the resource. case http.MethodPost: // Create a new record. case http.MethodPut: // Update an existing record. case http.MethodDelete: // Remove the record. default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) }

Slide 49

Slide 49 text

Go 언어로 쉽고 빠르게 서버 만들기 49 func createProfile(w http.ResponseWriter, r *http.Request) { if r.Method == http.MethodPost { var profile Profile err := json.NewDecoder(r.Body).Decode(&profile) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } profiles[profile.ID] = profile w.WriteHeader(http.StatusCreated) } else { http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } create

Slide 50

Slide 50 text

Go 언어로 쉽고 빠르게 서버 만들기 50 func profileHandler(w http.ResponseWriter, r *http.Request) { switch r.Method { case http.MethodGet: getProfile(w, r) case http.MethodPost: createProfile(w, r) case http.MethodPut: updateProfile(w, r) case http.MethodDelete: deleteProfile(w, r) default: http.Error(w, "Method not allowed", http.StatusMethodNotAllowed) } } handler

Slide 51

Slide 51 text

Go 언어로 쉽고 빠르게 서버 만들기 51 func main() { mux := http.NewServeMux() mux.HandleFunc("/profile", profileHandler) server := &http.Server{ Addr: ":8080", Handler: mux, } fmt.Println("Server is listening on port 8080...") server.ListenAndServe() } func main() { mux := http.NewServeMux() mux.HandleFunc("/create", createProfile) mux.HandleFunc("/get", getProfile) mux.HandleFunc("/update", updateProfile) mux.HandleFunc("/delete", deleteProfile) server := &http.Server{ Addr: ":8080", Handler: mux, } fmt.Println("Server is listening on port 8080...") server.ListenAndServe() }

Slide 52

Slide 52 text

Go 언어로 쉽고 빠르게 서버 만들기 52 1. go mod init main.go 2. go mod tidy 3. go run main.go

Slide 53

Slide 53 text

Go 언어로 쉽고 빠르게 서버 만들기 53 120줄 내로 구성

Slide 54

Slide 54 text

Go 언어로 쉽고 빠르게 서버 만들기 54

Slide 55

Slide 55 text

Go 언어로 쉽고 빠르게 서버 만들기 55 @source: https://github.com/smallnest/go-web-framework-benchmark

Slide 56

Slide 56 text

이제 Go 언어로 쉽고 빠르게 서버 만들기 56 해보세요

Slide 57

Slide 57 text

Thank You GDG Golang Korea Flutter Seoul 57