Yandex Cloud
Поиск
Связаться с намиПодключиться
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
    • Популярные
    • Инфраструктура и сеть
    • Платформа данных
    • Контейнеры
    • Инструменты разработчика
    • Бессерверные вычисления
    • Безопасность
    • Мониторинг и управление ресурсами
    • Машинное обучение
    • Бизнес-инструменты
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Облако для интеграторов
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Контент-программа
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Истории успеха
    • Тарифы Yandex Cloud
    • Промоакции и free tier
    • Правила тарификации
  • Документация
  • Блог
Проект Яндекса
© 2025 ООО «Яндекс.Облако»
Yandex Object Storage
    • Все руководства
    • Получение статистики запросов к объекту с использованием S3 Select
    • Получение статистики посещения сайта с использованием S3 Select
    • Получение статистики запросов к объектам с использованием Yandex Query
    • Анализ поресурсной детализации расходов
    • Шифрование на стороне сервера
    • Интеграция L7-балансировщика с CDN и Object Storage
    • Сине-зеленое и канареечное развертывание версий сервиса
    • Анализ логов с использованием DataLens
    • Монтирование бакетов к файловой системе хостов Yandex Data Processing
    • Использование Object Storage в Yandex Data Processing
    • Импорт данных из Object Storage, обработка и экспорт в Managed Service for ClickHouse®
    • Подключение бакета как диска в Windows
    • Миграция данных из Yandex Data Streams с помощью Yandex Data Transfer
    • Использование гибридного хранилища в Yandex Managed Service for ClickHouse®
    • Загрузка данных из Yandex Managed Service for OpenSearch в Yandex Object Storage с помощью Yandex Data Transfer
    • Автоматическое копирование объектов из бакета в бакет
    • Регулярное асинхронное распознавание аудиофайлов в бакете
    • Обучение модели в Yandex DataSphere на данных из Object Storage
    • Подключение к Object Storage из VPC
    • Перенос данных в Yandex Managed Service for PostgreSQL с использованием Yandex Data Transfer
    • Загрузка данных в Yandex Managed Service for Greenplum® с помощью Yandex Data Transfer
    • Загрузка данных в Yandex Managed Service for ClickHouse® с помощью Yandex Data Transfer
    • Загрузка данных в Yandex Managed Service for YDB с помощью Yandex Data Transfer
    • Обмен данными между Yandex Managed Service for ClickHouse® и Yandex Data Processing
    • Загрузка данных из Yandex Managed Service for YDB с помощью Yandex Data Transfer
    • Хостинг статического сайта на фреймворке Gatsby в Object Storage
    • Миграция базы данных из Managed Service for PostgreSQL в Object Storage
    • Обмен данными между Yandex Managed Service for ClickHouse® и Yandex Data Processing
    • Импорт данных из Yandex Managed Service for PostgreSQL в Yandex Data Processing с помощью Sqoop
    • Импорт данных из Yandex Managed Service for MySQL® в Yandex Data Processing с помощью Sqoop
    • Миграция данных из Yandex Object Storage в Yandex Managed Service for MySQL® с помощью Yandex Data Transfer
    • Миграция базы данных из Yandex Managed Service for MySQL® в Yandex Object Storage
    • Выгрузка данных Greenplum® в холодное хранилище Yandex Object Storage
    • Загрузка данных из Яндекс Директ в витрину Yandex Managed Service for ClickHouse® с использованием Yandex Cloud Functions, Yandex Object Storage и Yandex Data Transfer
    • Миграция данных из Elasticsearch в Yandex Managed Service for OpenSearch
    • Загрузка состояний Terraform в Object Storage
    • Блокировка состояний Terraform с помощью Managed Service for YDB
    • Визуализация данных Yandex Query
    • Публикация обновлений для игр
    • Резервное копирование ВМ с помощью Хайстекс Акура
    • Резервное копирование в Object Storage с помощью CloudBerry Desktop Backup
    • Резервное копирование в Object Storage через Duplicati
    • Резервное копирование в Object Storage с помощью Bacula
    • Резервное копирование в Object Storage с помощью Veeam Backup
    • Резервное копирование в Object Storage с помощью Veritas Backup Exec
    • Резервное копирование кластера Managed Service for Kubernetes в Object Storage
    • Разработка пользовательской интеграции в API Gateway
    • Сокращатель ссылок
    • Хранение журналов работы приложения
    • Разработка навыка Алисы и сайта с авторизацией
    • Создание интерактивного serverless-приложения с использованием WebSocket
    • Развертывание веб-приложения с использованием Java Servlet API
    • Разработка Telegram-бота
    • Репликация логов в Object Storage с помощью Fluent Bit
    • Репликация логов в Object Storage с помощью Data Streams
    • Загрузка аудитных логов в SIEM ArcSight
    • Загрузка аудитных логов в SIEM Splunk
    • Создание сервера MLFlow для логирования экспериментов и артефактов
    • Работа с данными с помощью Yandex Query
    • Федеративные запросы к данным с помощью Query
    • Распознавание архива изображений в Vision OCR
    • Конвертация видео в GIF на Python
    • Автоматизация задач с помощью Managed Service for Apache Airflow™
    • Обработка файлов детализации в сервисе Yandex Cloud Billing
    • Развертывание веб-приложения с JWT-авторизацией в API Gateway и аутентификацией в Firebase
    • Поиск событий Yandex Cloud в Yandex Query
    • Поиск событий Yandex Cloud в Object Storage
    • Создание внешней таблицы на базе таблицы из бакета с помощью конфигурационного файла
    • Миграция базы данных из Google BigQuery в Managed Service for ClickHouse®
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • Логи бакета
  • История изменений
  • Вопросы и ответы
  • Обучающие курсы

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

  • Подготовьте облако к работе
  • Необходимые платные ресурсы
  • Настройте хостинг страницы сокращателя
  • Создайте сервисный аккаунт
  • Создайте БД в Managed Service for YDB
  • Настройте функцию в Cloud Functions
  • Опубликуйте сервис через API Gateway
  • Проверьте работу сокращателя
  • Как удалить созданные ресурсы
  1. Практические руководства
  2. Сокращатель ссылок

Сокращатель ссылок

Статья создана
Yandex Cloud
Улучшена
Dmitry A.
Обновлена 6 февраля 2025 г.
  • Подготовьте облако к работе
    • Необходимые платные ресурсы
  • Настройте хостинг страницы сокращателя
  • Создайте сервисный аккаунт
  • Создайте БД в Managed Service for YDB
  • Настройте функцию в Cloud Functions
  • Опубликуйте сервис через API Gateway
  • Проверьте работу сокращателя
  • Как удалить созданные ресурсы

С помощью этого сценария вы создадите сервис для сокращения URL, используя serverless-технологии, доступные в Yandex Cloud.

Сервис принимает обращения пользователей через публичный API-шлюз. Пользователь получает с хостинга HTML-страницу с полем для ввода URL. Функция отправляет введенный URL на хранение в serverless-базу данных, сокращает его и возвращает пользователю. При обращении пользователя по сокращенному URL, функция находит в БД полный URL и перенаправляет на него запрос пользователя.

Чтобы настроить и протестировать сервис:

  1. Подготовьте облако к работе.
  2. Настройте хостинг страницы сокращателя.
  3. Создайте сервисный аккаунт.
  4. Создайте БД в Yandex Managed Service for YDB.
  5. Настройте функцию в Yandex Cloud Functions.
  6. Опубликуйте сервис через Yandex API Gateway.
  7. Проверьте работу сокращателя.

Если созданные ресурсы вам больше не нужны, удалите их.

Подготовьте облако к работеПодготовьте облако к работе

Зарегистрируйтесь в Yandex Cloud и создайте платежный аккаунт:

  1. Перейдите в консоль управления, затем войдите в Yandex Cloud или зарегистрируйтесь.
  2. На странице Yandex Cloud Billing убедитесь, что у вас подключен платежный аккаунт, и он находится в статусе ACTIVE или TRIAL_ACTIVE. Если платежного аккаунта нет, создайте его и привяжите к нему облако.

Если у вас есть активный платежный аккаунт, вы можете создать или выбрать каталог, в котором будет работать ваша инфраструктура, на странице облака.

Подробнее об облаках и каталогах.

Необходимые платные ресурсыНеобходимые платные ресурсы

В стоимость ресурсов для сценария входят:

  • Плата за использование хранилища (см. тарифы Yandex Object Storage).
  • Плата за обращения к базе данных (см. тарифы Managed Service for YDB).
  • Плата за вызовы функции (см. тарифы Cloud Functions).
  • Плата за запросы к API-шлюзу (см. тарифы API Gateway).

Настройте хостинг страницы сокращателяНастройте хостинг страницы сокращателя

Чтобы создать бакет, разместить в нем HTML-страницу вашего сервиса и настроить бакет для хостинга статических сайтов:

Консоль управления
  1. В консоли управления выберите свой рабочий каталог.

  2. Выберите сервис Object Storage.

  3. Нажмите кнопку Создать бакет.

  4. На странице создания бакета:

    1. Введите имя бакета.

      Важно

      Имена бакетов уникальны для всего Object Storage, т. е. нельзя создать два бакета с одинаковыми именами даже в разных каталогах разных облаков.

    2. Задайте максимальный размер 1 ГБ.

    3. Выберите доступ на чтение объектов Публичный.

    4. Нажмите кнопку Создать бакет для завершения операции.

  5. Скопируйте HTML-код и вставьте его в файл index.html:

    HTML-код
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <title>Сокращатель URL</title>
      <!-- предостережет от лишнего GET запроса на адрес /favicon.ico -->
      <link rel="icon" href="data:;base64,iVBORw0KGgo=">
    </head>
    
    <body>
      <h1>Добро пожаловать</h1>
      <form action="javascript:shorten()">
        <label for="url">Введите ссылку:</label><br>
        <input id="url" name="url" type="text"><br>
        <input type="submit" value="Сократить">
      </form>
      <p id="shortened"></p>
    </body>
    
    <script>
      function shorten() {
        const link = document.getElementById("url").value
        fetch("/shorten", {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: link
        })
        .then(response => response.json())
        .then(data => {
          const url = data.url
          document.getElementById("shortened").innerHTML = `<a href=${url}>${url}</a>`
        })
        .catch(error => {
          document.getElementById("shortened").innerHTML = `<p>Произошла ошибка ${error}, попробуйте еще раз</p>`
        })
      }
    </script>
    
    </html>
    
  6. Нажмите на имя созданного бакета.

  7. Нажмите кнопку Загрузить объекты.

  8. Укажите подготовленный ранее файл index.html.

  9. Нажмите кнопку Загрузить.

  10. На панели слева выберите Настройки.

  11. На вкладке Веб-сайт:

    • Выберите Хостинг.
    • Укажите главную страницу сайта — index.html.
  12. Нажмите кнопку Сохранить.

Создайте сервисный аккаунтСоздайте сервисный аккаунт

Чтобы создать сервисный аккаунт для взаимодействия компонентов сервиса:

Консоль управления
  1. Перейдите в свой рабочий каталог.

  2. В списке сервисов выберите Identity and Access Management.

  3. Нажмите кнопку Создать сервисный аккаунт.

  4. Введите имя сервисного аккаунта serverless-shortener.

  5. Нажмите Добавить роль и выберите роль editor.

  6. Нажмите кнопку Создать.

  7. Нажмите на имя созданного сервисного аккаунта.

    Сохраните идентификатор созданного сервисного аккаунта, он понадобится на следующих шагах.

Создайте БД в Managed Service for YDBСоздайте БД в Managed Service for YDB

Чтобы создать базу данных Managed Service for YDB и настроить ее для хранения ссылок:

Консоль управления
  1. Перейдите в свой рабочий каталог.

  2. В списке сервисов выберите Managed Service for YDB.

  3. Нажмите кнопку Создать базу данных.

  4. Введите имя базы for-serverless-shortener.

  5. Выберите тип базы данных Serverless.

  6. Нажмите кнопку Создать базу данных.

  7. Дождитесь запуска базы данных.

    В процессе создания база будет иметь статус Provisioning, а когда станет готова к использованию — статус изменится на Running.

  8. Нажмите на имя созданной БД.

    Сохраните значение поля Эндпоинт, оно понадобится на следующих шагах.

  9. На панели слева выберите вкладку Навигация.

  10. Нажмите кнопку Новый SQL-запрос.

  11. Скопируйте SQL-запрос и вставьте его в поле Запрос:

    CREATE TABLE links
    (
      id Utf8,
      link Utf8,
      PRIMARY KEY (id)
    );
    
  12. Нажмите кнопку Выполнить.

Настройте функцию в Cloud FunctionsНастройте функцию в Cloud Functions

Чтобы создать и настроить функцию сокращения URL:

Консоль управления
  1. Перейдите в свой рабочий каталог.

  2. В списке сервисов выберите Cloud Functions.

  3. Нажмите кнопку Создать функцию.

  4. Введите имя for-serverless-shortener.

  5. Нажмите кнопку Создать.

  6. В выпадающем списке Python выберите среду выполнения python312.

  7. Нажмите кнопку Продолжить.

  8. Скопируйте код функции и вставьте его в файл index.py в блоке Код функции.

    Код функции
    import ydb
    
    import urllib.parse
    import hashlib
    import base64
    import json
    import os
    
    
    def decode(event, body):
      # Тело запроса может быть закодировано.
      is_base64_encoded = event.get('isBase64Encoded')
      if is_base64_encoded:
        body = str(base64.b64decode(body), 'utf-8')
      return body
    
    def response(statusCode, headers, isBase64Encoded, body):
      return {
        'statusCode': statusCode,
        'headers': headers,
        'isBase64Encoded': isBase64Encoded,
        'body': body,
      }
    
    def get_config():
      endpoint = os.getenv("endpoint")
      database = os.getenv("database")
      if endpoint is None or database is None:
        raise AssertionError("Нужно указать обе переменные окружения")
      credentials = ydb.iam.MetadataUrlCredentials()
      return ydb.DriverConfig(endpoint, database, credentials=credentials)
    
    def execute(config, query, params):
      with ydb.Driver(config) as driver:
        try:
          driver.wait(timeout=5, fail_fast=True)
        except TimeoutError:
          print("Connect failed to YDB")
          print("Last reported errors by discovery:")
          print(driver.discovery_debug_details())
          return None
    
        session = driver.table_client.session().create()
        prepared_query = session.prepare(query)
        return session.transaction(ydb.SerializableReadWrite()).execute(
          prepared_query,
          params,
          commit_tx=True
        )
    
    
    def insert_link(id, link):
      config = get_config()
      query = """
        DECLARE $id AS Utf8;
        DECLARE $link AS Utf8;
    
        UPSERT INTO links (id, link) VALUES ($id, $link);
        """
      params = {'$id': id, '$link': link}
      execute(config, query, params)
    
    def find_link(id):
      print(id)
      config = get_config()
      query = """
        DECLARE $id AS Utf8;
    
        SELECT link FROM links where id=$id;
        """
      params = {'$id': id}
      result_set = execute(config, query, params)
    
      if not result_set or not result_set[0].rows:
        return None
    
      return result_set[0].rows[0].link
    
    def shorten(event):
      body = event.get('body')
    
      if body:
        body = decode(event, body)
        original_host = event.get('headers').get('Origin')
        link_id = hashlib.sha256(body.encode('utf8')).hexdigest()[:6]
        # В ссылке могут быть закодированные символы, например, %. Это помешает работе API Gateway при редиректе,
        # поэтому следует избавиться от них вызовом urllib.parse.unquote.
        insert_link(link_id, urllib.parse.unquote(body))
        return response(200, {'Content-Type': 'application/json'}, False, json.dumps({'url': f'{original_host}/r/{link_id}'}))
      return response(400, {}, False, 'В теле запроса отсутствует параметр url')
    
    def redirect(event):
      link_id = event.get('pathParams').get('id')
      redirect_to = find_link(link_id)
    
      if redirect_to:
        return response(302, {'Location': redirect_to}, False, '')
    
      return response(404, {}, False, 'Данной ссылки не существует')
    
    # Эти проверки нужны, поскольку функция у нас одна.
    # В идеале сделать по функции на каждый путь в API Gateway.
    def get_result(url, event):
      if url == "/shorten":
        return shorten(event)
      if url.startswith("/r/"):
        return redirect(event)
    
      return response(404, {}, False, 'Данного пути не существует')
    
    def handler(event, context):
      url = event.get('url')
      if url:
        # Из API Gateway URL может прийти со знаком вопроса на конце.
        if url[-1] == '?':
          url = url[:-1]
        return get_result(url, event)
    
      return response(404, {}, False, 'Эту функцию следует вызывать при помощи API Gateway.')
    
  9. В блоке Код функции создайте файл requirements.txt и вставьте в него следующий текст:

    ydb
    
  10. Укажите точку входа index.handler.

  11. Задайте таймаут 5.

  12. Выберите сервисный аккаунт serverless-shortener.

  13. Добавьте переменные окружения:

    • endpoint — введите первую часть сохраненного ранее поля Эндпоинт (часть до вхождения /?database=). Например, grpcs://ydb.serverless.yandexcloud.net:2135.
    • database — введите вторую часть сохраненного ранее поля Эндпоинт (часть после вхождения /?database=). Например, /ru-central1/r1gra875baom********/g5n22e7ejfr1********.
  14. Нажмите кнопку Сохранить изменения.

  15. В блоке Обзор включите опцию Публичная функция.

Сохраните идентификатор созданной функции, он понадобится на следующих шагах.

Опубликуйте сервис через API GatewayОпубликуйте сервис через API Gateway

Чтобы опубликовать сервис через API Gateway:

Консоль управления
  1. Перейдите в свой рабочий каталог.

  2. В списке сервисов выберите API Gateway.

  3. Нажмите кнопку Создать API-шлюз.

  4. В поле Имя введите for-serverless-shortener.

  5. Скопируйте и вставьте следующий код в блок Спецификация:

    Спецификация
    openapi: 3.0.0
    info:
      title: for-serverless-shortener
      version: 1.0.0
    paths:
      /:
        get:
          x-yc-apigateway-integration:
            type: object_storage
            bucket: <имя_бакета> # <-- имя бакета
            object: index.html # <-- имя html-файла
            presigned_redirect: false
            service_account: <service_account_id> # <-- ID сервисного аккаунта
          operationId: static
      /shorten:
        post:
          x-yc-apigateway-integration:
            type: cloud_functions
            function_id: <function_id> # <-- ID функции
          operationId: shorten
      /r/{id}:
        get:
          x-yc-apigateway-integration:
            type: cloud_functions
            function_id: <function_id> # <-- ID функции
          operationId: redirect
          parameters:
          - description: id of the url
            explode: false
            in: path
            name: id
            required: true
            schema:
              type: string
            style: simple
    

    Внесите правки в код спецификации:

    • Замените <service_account_id> на идентификатор созданного ранее сервисного аккаунта.
    • Замените <function_id> на идентификатор созданной ранее функции.
    • Замените <имя_бакета> на имя созданного ранее бакета.
  6. Нажмите кнопку Создать.

  7. Нажмите на имя созданного API-шлюза.

  8. Скопируйте значение url из спецификации.

    Используйте этот URL для работы с созданным сервисом.

Проверьте работу сокращателяПроверьте работу сокращателя

Чтобы проверить правильность взаимодействия компонентов сервиса:

  1. Откройте в браузере скопированный URL.

  2. В поле для ввода введите ссылку, которую вы хотите сократить.

  3. Нажмите кнопку Сократить.

    Ниже отобразится сокращенная ссылка.

  4. Перейдите по сокращенной ссылке, должна открыться та же страница, что и по ссылке до сокращения.

Как удалить созданные ресурсыКак удалить созданные ресурсы

Чтобы перестать платить за созданные ресурсы:

  1. Удалите API-шлюз.
  2. Удалите функцию.
  3. Удалите базу данных.
  4. Удалите бакет.
  5. Удалите сервисный аккаунт.

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

Предыдущая
Разработка пользовательской интеграции в API Gateway
Следующая
Хранение журналов работы приложения
Проект Яндекса
© 2025 ООО «Яндекс.Облако»