Yandex Cloud
Поиск
Связаться с намиПодключиться
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Контейнеры
    • Инструменты разработчика
    • Бессерверные вычисления
    • Безопасность
    • Мониторинг и управление ресурсами
    • Машинное обучение
    • Бизнес-инструменты
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Истории успеха
    • Тарифы Yandex Cloud
    • Промоакции и free tier
    • Правила тарификации
  • Документация
  • Блог
Проект Яндекса
© 2025 ООО «Яндекс.Облако»
Yandex Cloud Functions
  • Сопоставление с другими сервисами Yandex Cloud
    • Обзор
    • Управление зависимостями
    • Обработчик запросов
    • Контекст вызова
    • Журналирование
    • Обработка ошибок
    • Использование SDK
  • Инструменты
  • Правила тарификации
  • Управление доступом
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • История изменений
  • Вопросы и ответы
  • Обучающие курсы

В этой статье:

  • Сигнатура Cloud Functions
  • Стандартная сигнатура Go
  • Примеры
  • Вывод структуры HTTP-запроса
  • Вывод подготовленного ответа или ошибки
  • Разбор HTTP-запроса
  • Разбор HTTP-запроса за API Gateway
  1. Разработка на Go
  2. Обработчик запросов

Обработчик запросов функции на Go

Статья создана
Yandex Cloud
Улучшена
Обновлена 21 апреля 2025 г.
  • Сигнатура Cloud Functions
  • Стандартная сигнатура Go
  • Примеры
    • Вывод структуры HTTP-запроса
    • Вывод подготовленного ответа или ошибки
    • Разбор HTTP-запроса
    • Разбор HTTP-запроса за API Gateway

Обработчик запросов — это метод, который используется для обработки каждого вызова функции на Go. При создании версии функции необходимо указать точку входа, которая состоит из имени файла и имени обработчика запросов, например index.Handler. В названии файла с обработчиком не должно быть символа . до расширения, например .handler.go.

  • Для корректной работы обработчик должен находиться в пакете main.
  • Чтобы обработчик был доступен вне модуля (файла), экспортируйте его, вводя первую букву его имени с заглавной буквы.

Примечание

В каждый момент времени один экземпляр функции обрабатывает не больше вызовов, чем задано в параметре concurrency. Это позволяет использовать глобальные переменные без необходимости обеспечивать контроль целостности данных.

Сигнатура Cloud FunctionsСигнатура Cloud Functions

При вызове обработчика среда выполнения может передавать следующие аргументы:

  1. Контекст вызова (параметр context).

    Контекст содержит необходимую информацию о версии функции. Структура этого объекта описана в разделе Контекст вызова функции на Go.
    В случае присутствия второго аргумента (тела HTTP-запроса), контекст вызова должен быть первым в списке аргументов.

  2. Тело HTTP-запроса (параметр request).

    Тело может быть представлено массивом байтов, строкой, пользовательским типом или указателем на него. В первых двух случаях представление отражает HTTP-запрос в чистом виде — либо в качестве массива байт, либо в виде строки.
    Если же аргумент обработчика имеет пользовательский тип, а тело запроса — JSON-документ, то оно будет преобразовано в объект этого типа с помощью метода json.Unmarshal.

Ни один из вышеперечисленных аргументов не является обязательным.
Если аргумент, отвечающий за тело запроса, отсутствует, то любые входные данные функции игнорируются.

Среда выполнения возвращает результат исполнения функции в виде набора данных:

  1. Тело ответа (значение response).

    Тело может быть представлено массивом байтов, строкой, пользовательским типом или указателем на него, а также пустым интерфейсом. В первых двух случаях для получения корректного ответа следует вызывать функцию с указанием параметра строки запроса ?integration=raw. Подробнее про вызов функции можно почитать в соответствующем разделе. В других случаях возвращаемое значение будет преобразовано в объект соответствующего типа с помощью метода json.Unmarshal и возвращено в виде JSON-документа.

  2. Ошибка (значение error).

    Для оповещения об ошибочном результате исполнения функции рекомендуется возвращать соответствующую ошибку. В случае, когда error != nil, тело ответа, при его наличии, игнорируется. Внимание: ошибка является обязательным возвращаемым значением. Другими словами, в случае отсутствия тела ответа, из функции должна возвращаться ошибка в качестве единственного возвращаемого значения, иначе ошибка должна быть последней в списке возвращаемых значений.

Стандартная сигнатура GoСтандартная сигнатура Go

Cloud Functions поддерживает в качестве обработчика:

  • функции с сигнатурой func (http.ResponseWriter, *http.Request);
  • объекты, которые удовлетворяют интерфейсу http.Handler.

Функция может брать значения, которые передаются в запросе, из структуры http.Request, и передавать ответ на запрос через интерфейс http.ResponseWriter.

Cloud Functions не поддерживает пути в запросах. Для корректной работы http.ServeMux функцию нужно вызывать через API-шлюз.

Пример функции:

package main

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

func Handler(rw http.ResponseWriter, req *http.Request) {
  rw.Header().Set("X-Custom-Header", "Test")
  rw.WriteHeader(200)
  name := req.URL.Query().Get("name")
  io.WriteString(rw, fmt.Sprintf("Hello, %s!", name))
}

ПримерыПримеры

Вывод структуры HTTP-запросаВывод структуры HTTP-запроса

Следующая функция получает на вход запрос с двумя полями (строкой и числом), выводит структуру запроса и контекста вызова в журнал выполнения и возвращает строчную запись JSON-документа, содержащего информацию о контексте и запросе.

Важно

Функцию необходимо вызывать с помощью Yandex Cloud CLI или с помощью HTTP-запроса с параметром ?integration=raw.

package main

import (
  "context"
  "encoding/json"
  "fmt"
)

// Входной JSON-документ будет автоматически преобразован в объект данного типа
type Request struct {
  Message string `json:"message"`
  Number  int    `json:"number"`
}

type ResponseBody struct {
  Context context.Context `json:"context"`
  Request interface{}     `json:"request"`
}

func Handler(ctx context.Context, request *Request) ([]byte, error) {
  // В логах функции будут напечатаны значения контекста вызова и тела запроса
  fmt.Println("context", ctx)
  fmt.Println("request", request)
  
  // Объект, содержащий тело ответа, преобразуется в массив байтов
  body, err := json.Marshal(&ResponseBody {
    Context: ctx,
    Request: request,
  })

  if err != nil {
    return nil, err
  }

  // Тело ответа необходимо вернуть в виде массива байтов
  return body, nil
}

Пример входных данных:

{
  "message": "Hello, world",
  "number": 24
}

В журнале будет напечатано:

context {context.Background map[lambdaRuntimeFunctionName:b09ks558ute7******** lambdaRuntimeFunctionVersion:b09ebrsp6jba******** lambdaRuntimeLogGroupName:eolitpnj15jr******** lambdaRuntimeLogStreamName:b09ebrsp6jba******** lambdaRuntimeMemoryLimit:512 lambdaRuntimeRequestID:58fc90cc-97b9-4c2b-95db-9dd0********]}
request &{Hello, world 24}

Возвращаемый JSON-документ:

{ 
  "context": {
    "Context": 0
  },
  "request": {
    "message": "Hello, world",
    "number": 24
  }
}

Вывод подготовленного ответа или ошибкиВывод подготовленного ответа или ошибки

Функция генерирует случайное число от 0 до 100 и возвращает ошибку, если это число больше или равно 50, иначе возвращает строку "Lucky one!":

package main

import (
  "fmt"
  "math/rand"
)

// Тело ответа представляет собой строку, следовательно, для корректного отображения
// ответа следует запускать функцию с параметром `?integration=raw`
func Handler() (string, error) {
  if (rand.Int31n(100) >= 50) {
    return "", fmt.Errorf("not so lucky")
  }
  
  return "Lucky one!", nil
}

Возвращаемый JSON-документ:

В случае, когда случайное число больше или равно 50:

{
  "errorMessage":"not so lucky",
  "errorType":"UserCodeError"
}

В противном случае:

"Lucky one!"

Разбор HTTP-запросаРазбор HTTP-запроса

Функция вызывается с помощью HTTP-запроса с именем пользователя, записывает в журнал метод и тело запроса и возвращает приветствие.

Важно

Не используйте для вызова функции параметр ?integration=raw. При его использовании функция не получает данных о методах, заголовках и параметрах исходного запроса.

package main

import (
  "context"
  "encoding/json"
  "fmt"
)

// Структура тела запроса (см. абзац после этого примера).
// Остальные поля нигде не используются в данном примере, поэтому можно обойтись без них
type RequestBody struct {
  HttpMethod string `json:"httpMethod"`
  Body       []byte `json:"body"`
}

// Преобразуем поле body объекта RequestBody
type Request struct {
  Name string `json:"name"`
}

type Response struct {
  StatusCode int         `json:"statusCode"`
  Body       interface{} `json:"body"`
}

func Greet(ctx context.Context, request []byte) (*Response, error) {
  requestBody := &RequestBody{}
  // Массив байтов, содержащий тело запроса, преобразуется в соответствующий объект
  err := json.Unmarshal(request, &requestBody)
  if err != nil {
    return nil, fmt.Errorf("an error has occurred when parsing request: %v", err)
  }

  // В журнале будет напечатано название HTTP-метода, с помощью которого осуществлен запрос, а также тело запроса
  fmt.Println(requestBody.HttpMethod, string(requestBody.Body))

  req := &Request{}
  // Поле body запроса преобразуется в объект типа Request для получения переданного имени
  err = json.Unmarshal(requestBody.Body, &req)
  if err != nil {
    return nil, fmt.Errorf("an error has occurred when parsing body: %v", err)
  }

  name := req.Name
  // Тело ответа необходимо вернуть в виде структуры, которая автоматически преобразуется в JSON-документ,
  // который отобразится на экране
  return &Response{
    StatusCode: 200,
    Body:       fmt.Sprintf("Hello, %s", name),
  }, nil
}

Подробнее о структуре тела запроса (type RequestBody struct) см. в разделе Структура запроса.

Пример входных данных (метод POST):

{
  "name": "Anonymous"
}

В журнале будет напечатано:

POST { "name": "Anonymous" }

Возвращаемый ответ:

Hello, Anonymous

Разбор HTTP-запроса за API GatewayРазбор HTTP-запроса за API Gateway

Функция вызывается сервисом Yandex API Gateway с сервисным аккаунтом, записывает в журнал метод и тело запроса и возвращает приветствие.

Функция декодирует тело входящего запроса при помощи json.Unmarshal().

package main

import (
	"context"
	"encoding/json"
	"fmt"
)

// Структура запроса API Gateway v1
type APIGatewayRequest struct {
	OperationID string `json:"operationId"`
	Resource    string `json:"resource"`

	HTTPMethod string `json:"httpMethod"`

	Path           string            `json:"path"`
	PathParameters map[string]string `json:"pathParameters"`

	Headers           map[string]string   `json:"headers"`
	MultiValueHeaders map[string][]string `json:"multiValueHeaders"`

	QueryStringParameters           map[string]string   `json:"queryStringParameters"`
	MultiValueQueryStringParameters map[string][]string `json:"multiValueQueryStringParameters"`

	Parameters           map[string]string   `json:"parameters"`
	MultiValueParameters map[string][]string `json:"multiValueParameters"`

	Body            string `json:"body"`
	IsBase64Encoded bool   `json:"isBase64Encoded,omitempty"`

	RequestContext interface{} `json:"requestContext"`
}

// Структура ответа API Gateway v1
type APIGatewayResponse struct {
	StatusCode        int                 `json:"statusCode"`
	Headers           map[string]string   `json:"headers"`
	MultiValueHeaders map[string][]string `json:"multiValueHeaders"`
	Body              string              `json:"body"`
	IsBase64Encoded   bool                `json:"isBase64Encoded,omitempty"`
}

type Request struct {
	Name string `json:"name"`
}

func Greet(ctx context.Context, event *APIGatewayRequest) (*APIGatewayResponse, error) {
	req := &Request{}

	// Поле event.Body запроса преобразуется в объект типа Request для получения переданного имени
	if err := json.Unmarshal([]byte(event.Body), &req); err != nil {
		return nil, fmt.Errorf("an error has occurred when parsing body: %v", err)
	}

	// В журнале будет напечатано название HTTP-метода, с помощью которого осуществлен запрос, а также путь
	fmt.Println(event.HTTPMethod, event.Path)

	// Тело ответа.
	return &APIGatewayResponse{
		StatusCode: 200,
		Body:       fmt.Sprintf("Hello, %s", req.Name),
	}, nil
}

Важно

Обращаться к функции нужно через API-шлюз.

Пример входных данных (метод POST):

{
  "name": "Anonymous"
}

В журнале будет напечатано:

POST { "name": "Anonymous" }

Возвращаемый ответ:

Hello, Anonymous

Была ли статья полезна?

Предыдущая
Управление зависимостями
Следующая
Контекст вызова
Проект Яндекса
© 2025 ООО «Яндекс.Облако»