저는 Nginx와 같은 CDN 또는 HTTP 서버를 통해 리소스가 별도로 제공되는 일반 웹 애플리케이션과 달리 Go에서 작은 독립형 웹 애플리케이션을 만들고 싶었습니다.
그러나 성능이 중요한 문제가 아니거나 응용 프로그램이 낮은 트래픽을 대상으로 하는 경우 독립 실행형 응용 프로그램을 사용하면 실행 가능한 바이너리일 뿐이므로 배포 및 배포가 단순화됩니다.
Go 애플리케이션에 리소스를 삽입하는 데 사용할 수 있는 여러 패키지가 있습니다.
각 라이브러리의 세부 사항을 자세히 다루지는 않겠지만 사용 편의성과 적극적인 지원으로 인해 bindata 접근 방식을 선호합니다.
먼저 프로젝트의 frontend/
디렉터리 내에 index.html
생성해 보겠습니다.
<html> <body> Hello, World! </body> </html>
이제 테스트할 프로젝트 설정과 정적 리소스가 있으므로 다음 명령을 사용하여 bindata를 설치해 보겠습니다.
go get -u github.com/jteeuwen/go-bindata/...
웹 애플리케이션의 백엔드 코드를 실행할 준비가 되었습니다. main.go
파일을 만들고 다음 코드를 복사합니다.
package main import ( "bytes" "io" "net/http" ) //go:generate go-bindata -prefix "frontend/" -pkg main -o bindata.go frontend/... func static_handler(rw http.ResponseWriter, req *http.Request) { var path string = req.URL.Path if path == "" { path = "index.html" } if bs, err := Asset(path); err != nil { rw.WriteHeader(http.StatusNotFound) } else { var reader = bytes.NewBuffer(bs) io.Copy(rw, reader) } } func main() { http.Handle("/", http.StripPrefix("/", http.HandlerFunc(static_handler))) http.ListenAndServe(":3000", nil) }
이 코드에서 중요한 줄은 다음과 같습니다.
//go:generate go-bindata -prefix "frontend/" -pkg main -o bindata.go frontend/...
위의 줄을 사용하면 go generate
호출될 때 go-bindata
명령을 실행할 수 있습니다. 버전 1.4부터는 생성 단계에서 사용자 지정 명령을 실행할 수 있습니다. //go:generate command argument...
go 파일에 추가하기만 하면 됩니다.
go-bindata
명령줄에는 여러 매개변수가 있으므로 사용 방법에 대한 설명서를 확인하세요. 우리의 경우에는 다음과 같이 말합니다.
-prefix "frontend/"
정적 경로 이름의 일부를 정의합니다.
-pkg main
생성된 코드에 사용되는 패키지 이름을 정의합니다.
-o bindata.go
생성된 파일의 이름을 정의합니다.
go generate
명령을 실행하면 bindata.go
라는 이름의 생성된 파일이 표시됩니다. 프로젝트의 구조는 다음과 같아야 합니다.
. │ ├── bindata.go (auto-generated file) ├── frontend │ └── index.html └── main.go
정적 파일을 제공하기 위한 로직은 요청을 수신하고 경로가 정적 경로와 일치하는지 확인하는 static_handler
함수에 있습니다. 확인은 bindata.go
사용자가 자동으로 내보낸 Asset
기능을 사용하여 수행됩니다. 리소스가 존재하지 않으면 404
를 반환하고, 그렇지 않으면 리소스의 내용을 반환합니다.
나머지 코드는 웹 애플리케이션을 생성하고 /
에 대해 들어오는 모든 요청과 일치하도록 static_handler
템플릿을 바인딩하는 데 사용됩니다. 이 코드를 이해하는 데 어려움이 있으면 http package
에 대한 공식 Go 문서를 확인하세요.
Go가 패키지를 처리하는 방법을 빠르게 상기시키기 위해 식별자 이름의 첫 글자가 대문자로 시작하는 경우 모든 식별자는 동일한 이름을 가진 다른 패키지로 자동으로 내보내집니다.
이 규칙에 따라 bindata.go
파일은 main
패키지에 대한 Asset
기능을 제공합니다. 그러면 지정된 이름에 대한 자산이 로드되고 반환됩니다. 리소스를 찾을 수 없거나 로드할 수 없으면 오류를 반환합니다.