Golang - 웹 서버 - 1

Lumi·2022년 2월 17일
0

Golang

목록 보기
26/38
post-thumbnail

🔥 웹 서버 -1

웹 서버를 만들기 위해서 하나하나 공부했던 부분에 대해서 정리를 하였습니다.

이전에 주로 다루었던 Node.js와의 차이점과 동일한 문법 적인 부분을 비교하면서 적어보았습니다.

실제 실습 영상은 Youtube에서 다루고 있습니다.

🔨 서버 기본

package main

import (
	"fmt"
	"net/http"
)

func basic(w http.ResponseWriter, r *http.Request) {

	// node.js에서 req,res를 받는것처럼 반드시 두개의 인자를 받아야 한다.
	// Request부분 즉 r에는 클라이언트에서 보낸 메서드. 헤더, 바디 등등 정보가 담겨있다.
	// 이와 반대로 ResponseWriter은 출력을 담당하고 있습니다.
    
	fmt.Fprint(w, "hello world")
}

func main() {
	http.HandleFunc("/", basic)

	http.ListenAndServe(":3000", nil)
}

기본적인 웹 서버 입니다.

경로는 localhost:3000으로 들어오는 경로만을 설정한 매우 간단한 서버 입니다.

  • 입력, 출력은 아무런 것도 처리를 해주지 않고 있습니다.

단순히 화면에 Fprint를 통해서 보여주는?? 역할만을 수행하고 있습니다.

주석에도 적어둔것과 같이 Node.js와 비교를 해보자면

Node.js에서 express미들웨어를 사용하여 구성한 서버에서도 인자값을 두개 받게 됩니다.

  • 주로 req, res로 사용을 합니다.

golang에서도 반드시 인자값을 두개 받게 되며 이를 http.ResponseWriter, Request 라고 합니다.

이때 Request는 Node.js에서 req와 같이 클라이언트에서 보내는 데이터를 담고 있고

ResponseWriter부분은 Node.js에서 res와 같이 클라이언트에게 보내는 데이터를 담게 됩니다.

🔨 쿼리 요청을 받는 서버

이전과는 다르게 Request를 통해서 요청을 받는 서버를 구현해 보았습니다.

package main

import (
	"fmt"
	"net/http"
	"strconv"
)

func basic(w http.ResponseWriter, r *http.Request) {
	values := r.URL.Query()    // 쿼리 인수를 받게 됩니다.
	name := values.Get("name") //특정 키값이 있는지를 확인합니다.

	if name == "" {
		name = "world" // 만약 키값이 없다면 새로 만들어 줍니다.
	}

	id, _ := strconv.Atoi(values.Get("id")) // 쿼리 인자에서 키값이 id인 값을 가져오고 int타입으로 변환시켜 줍니다.

	fmt.Fprintf(w, "hello %s! id: %d", name, id) //그후 화면에 출력합니다.
}

func main() {
	http.HandleFunc("/bar", basic)

	http.ListenAndServe(":3000", nil)
}

url에 담기는 쿼리 메시지를 가져오는 방법입니다.

r.URL.Query()를 통해 모든 쿼리 인자들을 가져올수 있고

이후 Get(키값)을 통해서 쿼리 값에 접근이 가능합니다.

또한 부가적으로 들어오는 쿼리값들은 모두 string 타입이기 떄문에 strconv.Atoi()를 통해서 string값을 int타입으로 변형시켜 줍니다.

이전 예시에 비해서 쿼리값을 받아올수 있는 부분만 변경이 되었기 떄문에 이해하기는 어렵지 않을것이라고 생각합니다.

🔨 인스턴스를 활용

사실 이러한 인스턴스가 정확하게 어떠한 방식으로 구동이 되는지는 아직은 이해하지 못하였습니다.

하지만 기능적인 부분을 추가할떄 어려운 문제점이 있고 단순히 DefaultServerMux를 사용하기 보다는 인스턴스를 만들어서 사용을 하는 것이 좀더 기능적 추가에 유용하다고 인식만을 하고 있는 시점입니다.

  • 예를들면 여러개의 서버를 구성해야 할떄 인스턴스를 활용하는 것이 좀더 낫겠다는 생각이 듭니다.
  • 좀더 알아보니 라우터의 기능을 한다고 합니다. 자세한 부분은 후에 다루어 보겠습니다.

DefaultServerMux라는 용어는 ListenAndServer부분에 nil이 들어가는 서버를 말합니다.

package main

import (
	"fmt"
	"net/http"
	"strconv"
)

func basic(w http.ResponseWriter, r *http.Request) {
	values := r.URL.Query()    // 쿼리 인수를 받게 됩니다.
	name := values.Get("name") //특정 키값이 있는지를 확인합니다.

	if name == "" {
		name = "world" // 만약 키값이 없다면 새로 만들어 줍니다.
	}

	id, _ := strconv.Atoi(values.Get("id")) // 쿼리 인자에서 키값이 id인 값을 가져오고 int타입으로 변환시켜 줍니다.

	fmt.Fprintf(w, "hello %s! id: %d", name, id) //그후 화면에 출력합니다.
}

func test(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "이곳은 / 입니다.")
}

func main() {

	mux := http.NewServeMux()

	mux.HandleFunc("/bar", basic)

	mux.HandleFunc("/", test)

	http.ListenAndServe(":3000", mux)
}

두개의 URL을 처리할수 있는 서버입니다.

두 경우 모두 이전에 사용하였던 코드 그대로 사용을 하였고 문제 없이 작동을 하고 있습니다.

🔨 파일을 제공하는 서버 만들어 보기

굉장히 간단하지만 Node.js에서도 안해보았던 작업을 해보았습니다.

제목 그대로 파일을 제공하는 서버를 구축할수 있는 방법 입니다.

package main

import (
	"net/http"
)

func main() {

	mux := http.NewServeMux()

	mux.Handle("/", http.FileServer(http.Dir("폴더명")))

	http.ListenAndServe(":3000", mux)

}

일단 기본 셋팅을 위해서 같은 경로에 폴더가 필요합니다.

이후 해당 폴더에 접근을 한뒤에 폴더 안에 있는 이미지 파일 이름을 url에 입력해 주면 됩니다.

  • 예를들면 localhost:3000/img.jpg

🔨 Json데이터 전송 서버

package main

import (
	"encoding/json"
	"fmt"
	"net/http"
)

type Student struct {
	Name  string
	Age   int
	Score int
}

func MakeWebHandler() http.Handler {
	mux := http.NewServeMux()
	mux.HandleFunc("/student", StudentHandler)
	return mux
}

func StudentHandler(w http.ResponseWriter, r *http.Request) {
	var student = Student{"aaa", 16, 8}
	data, _ := json.Marshal(student)

	w.Header().Add("contetnt-type", "application/json")
	w.WriteHeader(http.StatusOK)
	fmt.Fprint(w, string(data))
}

func main() {

	http.ListenAndServe(":3000", MakeWebHandler())

}

이번에는 이전과 다른 방식으로 서버를 구현해 보았습니다.

  • ListenAndServer의 두번쨰 인자로 함수를 넘겨주는 방식입니다.

이전과는 다르게 Header부분에 어떠한 데이터를 넘겨주는지 타입을 정해주게 됩니다.

  • 이전까지 Node.js에서는 따로 추가해 주지 않았는데 golang에서는 따로 추가해 주었습니다.

객체 형식의 데이터를 json으로 넘기기 위해서 일단 []byte로 변환을 시켜 줍니다.

  • json.Marshal()에서 이러한 역할을 처리하고 있습니다.

이후 string으로 변환해 준뒤에 출력에 담아서 보내게 됩니다.

profile
[기술 블로그가 아닌 하루하루 기록용 블로그]

0개의 댓글