작년 중순부터 진행하던 프로젝트의 인프라는 Go언어를 기반으로 Serverless 환경이 필요 했지만,
하지만 작년 중순까지만해도 Azure Functions는 Go언어를 공식 지원하지 않았고
(작성시점에도 아직 Azure Functions 에서는 Go 언어를 공식지원하지는 않는다.)
그에 따라 그나마 자료가 많은 AWS로 프로젝트를 시작하였으나, Azure에 대한 아쉬움이 남아있었습니다.
그렇게 AWS Lambda로 개발을 진행하던 중 올해 3월경 Custom Handler 미리보기를 공개하여 이를 통한 Functions에서의 Go언어 사용이 가능해 졌습니다.
Azure Functions custom handlers (preview)
자세한 내용은 생략하고 실제로 사용해보겠습니다.
npm install -g azure-functions-core-tools@3
수기로 필요한 파일들을 만들수도 있지만 귀찮으니 초기화 명령어(func init
)를 사용해줍시다.
mkdir gofunc
cd gofunc
func init
Select a number for worker runtime:
1. dotnet
2. node
3. python
4. powershell
Choose option: 2
node
Select a number for language:
1. javascript
2. typescript
Choose option: 1
javascript
rm package.json
초기화시 런타임을 선택하라고 하지만 Custom 선택지가 없으므로 일단 node로 언어는 js로 초기화 해주고 불필요한 package.json 을 제거합니다.
이제 함수를 추가하는데 위와 마찬가지로 명령어(func new
)를 사용합니다.
$ func new
Select a number for template:
1. Azure Blob Storage trigger
2. Azure Cosmos DB trigger
3. Durable Functions activity
4. Durable Functions HTTP starter
5. Durable Functions orchestrator
6. Azure Event Grid trigger
7. Azure Event Hub trigger
8. HTTP trigger
9. IoT Hub (Event Hub)
10. Azure Queue Storage trigger
11. SendGrid
12. Azure Service Bus Queue trigger
13. Azure Service Bus Topic trigger
14. SignalR negotiate HTTP trigger
15. Timer trigger
Choose option: 8
HTTP trigger
Function name: [HttpTrigger] hello-world
rm hello-world/index.js
다양한 선택지가 있지만 HTTP trigger를 선택
이후 함수 명을 입력해주고 마찬가지로 불필요한 파일을 제거해 줍니다.
여기까지의 파일 구조는 다음과 같습니다.
│ .gitignore
│ host.json
│ local.settings.json
│
└─ hello-world
function.json
이제 다음으로 Go언어 함수를 만들어 보겠습니다.
// main.go
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"os"
)
type message struct {
Body string
}
func handleRequests() {
// 함수의 경로는 함수명과 동일하게
http.HandleFunc("/hello-world", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(message{
Body: "Hello World!",
})
})
// functions 포트 찾기(기본: 7071)
httpInvokerPort, exists := os.LookupEnv("FUNCTIONS_HTTPWORKER_PORT")
if exists {
fmt.Println("FUNCTIONS_HTTPWORKER_PORT: " + httpInvokerPort)
}
log.Println("Go server Listening...on httpInvokerPort:", httpInvokerPort)
log.Fatal(http.ListenAndServe(":"+httpInvokerPort, nil))
}
func main() {
handleRequests()
}
'FUNCTIONS_HTTPWORKER_PORT' 변수를 선언하여 로컬 테스트 할수도 있습니다.
# 빌드
go build main.go
{
"version": "2.0",
"httpWorker": {
"description": {
"defaultExecutablePath": "main.exe" // 빌드 된 바이너리
}
}
}
defaultExecutablePath
의 값을 빌드된 파일로 변경해줍니다.
이제 설정은 모두 끝났습니다 😀
func start
경로 매핑 확인
Hello World! 가 정상 출력되는것을 확인할수 있습니다.
Hello World가 끝났으니 이제 하나하나 시도해보면 되겠네요. 😏