11.5. Go 함수 개발

중요

Go를 사용하는 OpenShift Serverless Functions는 기술 프리뷰 기능 전용입니다. 기술 프리뷰 기능은 Red Hat 프로덕션 서비스 수준 계약(SLA)에서 지원되지 않으며 기능적으로 완전하지 않을 수 있습니다. 따라서 프로덕션 환경에서 사용하는 것은 권장하지 않습니다. 이러한 기능을 사용하면 향후 제품 기능을 조기에 이용할 수 있어 개발 과정에서 고객이 기능을 테스트하고 피드백을 제공할 수 있습니다.

Red Hat 기술 프리뷰 기능의 지원 범위에 대한 자세한 내용은 기술 프리뷰 기능 지원 범위를 참조하십시오.

Go 함수 프로젝트를 생성한 후에는 제공된 템플릿 파일을 수정하여 비즈니스 로직을 기능에 추가할 수 있습니다. 여기에는 함수 호출 구성 및 반환된 헤더 및 상태 코드가 포함됩니다.

11.5.1. 사전 요구 사항

11.5.2. 함수 템플릿 구조

Knative(kn) CLI를 사용하여 Go 함수를 생성할 때 프로젝트 디렉터리는 일반적인 Go 프로젝트와 유사합니다. 유일한 예외는 이미지를 지정하는 데 사용되는 추가 func.yaml 구성 파일입니다.

Go 함수에는 몇 가지 제한 사항이 있습니다. 유일한 요구 사항은 프로젝트를 function 모듈에 정의해야 하며, 함수 Handle()을 내보내야 한다는 것입니다.

httpevent 트리거 함수 모두 동일한 템플릿 구조를 갖습니다.

템플릿 구조

fn
├── README.md
├── func.yaml 1
├── go.mod 2
├── go.sum
├── handle.go
└── handle_test.go

1
func.yaml 구성 파일은 이미지 이름과 레지스트리를 결정하는 데 사용됩니다.
2
추가 로컬 Go 파일을 포함할 수 있는 go.mod 파일에 필요한 종속 항목을 추가할 수 있습니다. 프로젝트가 배포용으로 빌드되면 이러한 종속성이 결과로 생성된 런타임 컨테이너 이미지에 포함됩니다.

종속성 추가 예

$ go get gopkg.in/yaml.v2@v2.4.0

11.5.3. Go 함수 호출 정보

Knative(kn) CLI를 사용하여 함수 프로젝트를 생성할 때 CloudEvents에 응답하는 프로젝트 또는 간단한 HTTP 요청에 응답하는 프로젝트를 생성할 수 있습니다. Go 함수는 HTTP 요청 또는 CloudEvent에 의해 트리거되는지 여부에 따라 다양한 방법을 사용하여 호출됩니다.

11.5.3.1. HTTP 요청에 의해 트리거된 함수

들어오는 HTTP 요청이 수신되면 표준 Go Context 를 첫 번째 매개변수로 사용하여 함수를 호출한 다음 http.ResponseWriterhttp.Request 매개변수를 사용합니다. 표준 Go 기술을 사용하여 요청에 액세스하고 함수에 대한 해당 HTTP 응답을 설정할 수 있습니다.

HTTP 응답의 예

func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
  // Read body
  body, err := ioutil.ReadAll(req.Body)
  defer req.Body.Close()
  if err != nil {
	http.Error(res, err.Error(), 500)
	return
  }
  // Process body and function logic
  // ...
}

11.5.3.2. 클라우드 이벤트에서 트리거한 함수

들어오는 클라우드 이벤트가 수신되면 CloudEvents Go SDK 에서 이벤트를 호출합니다. 호출은 이벤트 유형을 매개 변수로 사용합니다.

지원되는 함수 서명 목록에 표시된 대로 Go Context 를 함수 계약의 선택적 매개변수로 활용할 수 있습니다.

지원되는 함수 서명

Handle()
Handle() error
Handle(context.Context)
Handle(context.Context) error
Handle(cloudevents.Event)
Handle(cloudevents.Event) error
Handle(context.Context, cloudevents.Event)
Handle(context.Context, cloudevents.Event) error
Handle(cloudevents.Event) *cloudevents.Event
Handle(cloudevents.Event) (*cloudevents.Event, error)
Handle(context.Context, cloudevents.Event) *cloudevents.Event
Handle(context.Context, cloudevents.Event) (*cloudevents.Event, error)

11.5.3.2.1. CloudEvent 트리거 예

데이터 속성에 JSON 문자열이 포함된 클라우드 이벤트가 수신됩니다.

{
  "customerId": "0123456",
  "productId": "6543210"
}

이 데이터에 액세스하려면 클라우드 이벤트 데이터에서 속성을 매핑하는 구조를 정의하고 들어오는 이벤트에서 데이터를 검색해야 합니다. 다음 예제에서는 Purchase 구조를 사용합니다.

type Purchase struct {
  CustomerId string `json:"customerId"`
  ProductId  string `json:"productId"`
}
func Handle(ctx context.Context, event cloudevents.Event) (err error) {

  purchase := &Purchase{}
  if err = event.DataAs(purchase); err != nil {
	fmt.Fprintf(os.Stderr, "failed to parse incoming CloudEvent %s\n", err)
	return
  }
  // ...
}

또는 Go encoding/json 패키지를 사용하여 바이트 배열 형식으로 클라우드 이벤트에 직접 JSON으로 액세스할 수 있습니다.

func Handle(ctx context.Context, event cloudevents.Event) {
  bytes, err := json.Marshal(event)
  // ...
}

11.5.4. Go 함수 반환 값

HTTP 요청에 의해 트리거된 함수는 응답을 직접 설정할 수 있습니다. Go http.ResponseWriter 를 사용하여 이 작업을 수행하도록 함수를 구성할 수 있습니다.

HTTP 응답의 예

func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
  // Set response
  res.Header().Add("Content-Type", "text/plain")
  res.Header().Add("Content-Length", "3")
  res.WriteHeader(200)
  _, err := fmt.Fprintf(res, "OK\n")
  if err != nil {
	fmt.Fprintf(os.Stderr, "error or response write: %v", err)
  }
}

클라우드 이벤트에 의해 트리거한 함수는 이벤트를 Knative Eventing 시스템으로 푸시하기 위해 아무것도 반환하지 않거나 error 또는 CloudEvent를 반환할 수 있습니다. 이 경우 클라우드 이벤트의 고유 ID, 적절한 SourceType을 설정해야 합니다. 데이터는 정의된 구조 또는 map에서 채워질 수 있습니다.

CloudEvent 응답 예

func Handle(ctx context.Context, event cloudevents.Event) (resp *cloudevents.Event, err error) {
  // ...
  response := cloudevents.NewEvent()
  response.SetID("example-uuid-32943bac6fea")
  response.SetSource("purchase/getter")
  response.SetType("purchase")
  // Set the data from Purchase type
  response.SetData(cloudevents.ApplicationJSON, Purchase{
	CustomerId: custId,
	ProductId:  prodId,
  })
  // OR set the data directly from map
  response.SetData(cloudevents.ApplicationJSON, map[string]string{"customerId": custId, "productId": prodId})
  // Validate the response
  resp = &response
  if err = resp.Validate(); err != nil {
	fmt.Printf("invalid event created. %v", err)
  }
  return
}

11.5.5. Go 함수 테스트

Go 함수는 컴퓨터에서 로컬로 테스트할 수 있습니다. kn func create 를 사용하여 함수를 생성할 때 생성되는 기본 프로젝트에는 몇 가지 기본 테스트가 포함된 handle_test.go 파일이 있습니다. 이러한 테스트는 필요에 따라 확장할 수 있습니다.

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
  • Knative(kn) CLI가 설치되어 있습니다.
  • kn func create 를 사용하여 함수를 생성했습니다.

프로세스

  1. 함수의 테스트 폴더로 이동합니다.
  2. 테스트를 실행합니다.

    $ go test

11.5.6. 다음 단계