Yandex Cloud
Поиск
Связаться с намиПопробовать бесплатно
  • Кейсы
  • Документация
  • Блог
  • Все сервисы
  • Статус работы сервисов
  • Marketplace
    • Доступны в регионе
    • Инфраструктура и сеть
    • Платформа данных
    • Искусственный интеллект
    • Безопасность
    • Инструменты DevOps
    • Бессерверные вычисления
    • Управление ресурсами
  • Все решения
    • По отраслям
    • По типу задач
    • Экономика платформы
    • Безопасность
    • Техническая поддержка
    • Каталог партнёров
    • Обучение и сертификация
    • Облако для стартапов
    • Облако для крупного бизнеса
    • Центр технологий для общества
    • Партнёрская программа
    • Поддержка IT-бизнеса
    • Облако для фрилансеров
    • Обучение и сертификация
    • Блог
    • Документация
    • Мероприятия и вебинары
    • Контакты, чаты и сообщества
    • Идеи
    • Калькулятор цен
    • Тарифы
    • Акции и free tier
  • Кейсы
  • Документация
  • Блог
Создавайте контент и получайте гранты!Готовы написать своё руководство? Участвуйте в контент-программе и получайте гранты на работу с облачными сервисами!
Подробнее о программе
Проект Яндекса
© 2026 ТОО «Облачные Сервисы Казахстан»
Yandex API Gateway
RU
  • Начало работы
    • Все практические руководства
      • Развертывание веб-приложения с использованием Java Servlet API
      • Разработка пользовательской интеграции
        • Обзор
        • Консоль управления
        • Terraform
      • Разработка CRUD API для сервиса фильмов
      • Создание интерактивного serverless-приложения с использованием WebSocket
      • Работа с API-шлюзом по протоколу WebSocket
      • Запуск контейнерного приложения в Yandex Serverless Containers
      • Развертывание веб-приложения с JWT-авторизацией в API Gateway и аутентификацией в Firebase
      • Канареечный релиз функции Cloud Functions
      • Интерактивная отладка функций Cloud Functions
  • Управление доступом
  • Инструменты
  • Правила тарификации
  • Справочник Terraform
  • Метрики Monitoring
  • Аудитные логи Audit Trails
  • Публичные материалы
  • История изменений
  • Вопросы и ответы
  • Обучающие курсы

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

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

Сокращатель ссылок с помощью консоли управления

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

Важно

Часть ресурсов, необходимых для прохождения практического руководства, доступны только в регионе Россия.

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

  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);
  • плата за операции с базой данных YDB и хранение данных (см. тарифы 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. Выберите опцию Хостинг.

  12. Укажите главную страницу сайта — index.html.

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

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

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

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

  2. В верхней части экрана перейдите на вкладку Сервисные аккаунты.

  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. Выберите Создать → Таблицу в правой части страницы.

  11. Настройте параметры таблицы:

    • Имя таблицы — links.
    • Тип таблицы — Строковая таблица.
  12. Добавьте колонки:

    • имя колонки — id, тип данных — Utf8 и установите Первичный ключ.
    • имя колонки — link, тип данных — Utf8.
  13. Нажмите кнопку Создать таблицу.

Настройте функцию в 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
    import traceback
    
    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):
        # Всегда отдаём строку в body
        if not isinstance(body, str):
            body = json.dumps(body, ensure_ascii=False)
        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("Нужно указать обе переменные окружения: endpoint и database")
        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 Exception as e:
                print("Connect failed to YDB:", e)
                print(driver.discovery_debug_details())
                raise
    
            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):
        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
    
        # Учитываем структуру результата от ydb
        return result_set[0].rows[0].link
    
    def shorten(event):
        try:
            body = event.get('body')
            if body is None:
                return response(400, {'Content-Type': 'application/json'}, False,
                                {'error': 'В теле запроса отсутствует тело'})
    
            body = decode(event, body)
    
            # Попробуем распарсить JSON с ключом url, иначе считаем body как plain string
            url_value = None
            try:
                parsed = json.loads(body)
                if isinstance(parsed, dict):
                    url_value = parsed.get('url')
                else:
                    # если отправили не-объект JSON, игнорируем
                    url_value = None
            except Exception:
                # body не JSON — считаем, что это plain URL
                url_value = body
    
            if not url_value:
                return response(400, {'Content-Type': 'application/json'}, False,
                                {'error': 'Ожидался параметр url в теле запроса'})
    
            # Очищаем URL от эвентуальных кодированных символов
            clean_url = urllib.parse.unquote(url_value).strip()
            if not clean_url:
                return response(400, {'Content-Type': 'application/json'}, False,
                                {'error': 'Пустой url'})
    
            link_id = hashlib.sha256(clean_url.encode('utf8')).hexdigest()[:6]
            insert_link(link_id, clean_url)
    
            # Возвращаем относительный путь — фронт сам допишет origin
            return response(200, {'Content-Type': 'application/json'}, False,
                            {'url': f'/r/{link_id}'})
        except Exception as e:
            print("Exception in shorten():", e)
            traceback.print_exc()
            return response(500, {'Content-Type': 'application/json'}, False,
                            {'error': 'internal server error'})
    
    def redirect(event):
        try:
            # защитно доставать path params
            path_params = event.get('pathParams') or event.get('pathParameters') or {}
            link_id = path_params.get('id')
            if not link_id:
                # возможно пришёл полный путь в event['url'] или ['path']
                url = event.get('url') or event.get('path') or ''
                if url and url.startswith('/r/'):
                    link_id = url.split('/r/')[-1].split('?')[0]
    
            if not link_id:
                return response(400, {'Content-Type': 'application/json'}, False, {'error': 'id отсутствует'})
    
            redirect_to = find_link(link_id)
    
            if redirect_to:
                return response(302, {'Location': redirect_to}, False, '')
            return response(404, {'Content-Type': 'application/json'}, False, {'error': 'Данной ссылки не существует'})
        except Exception as e:
            print("Exception in redirect():", e)
            traceback.print_exc()
            return response(500, {'Content-Type': 'application/json'}, False, {'error': 'internal server error'})
    
    def get_result(url, event):
        if url == "/shorten" or url.startswith("/shorten"):
            return shorten(event)
        if url.startswith("/r/"):
            return redirect(event)
        return response(404, {'Content-Type': 'application/json'}, False, {'error': 'Данного пути не существует'})
    
    def handler(event, context):
        url = event.get('url') or event.get('path') or ''
        if url:
            # Иногда URL из шлюза приходит с вопросительным знаком на конце
            if url.endswith('?'):
                url = url[:-1]
            return get_result(url, event)
        return response(404, {'Content-Type': 'application/json'}, False, {'error': 'Функция должна вызываться через 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=). Например, /kz1/r1gra875baom********/g5n22e7ejfr1********.
  14. Нажмите кнопку Сохранить изменения.

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

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

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

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

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

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

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

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

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

    Спецификация API-шлюза
    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> # <-- идентификатор сервисного аккаунта
          operationId: static
      /shorten:
        post:
          x-yc-apigateway-integration:
            type: cloud_functions
            function_id: <function_id> # <-- идентификатор функции
          operationId: shorten
      /r/{id}:
        get:
          x-yc-apigateway-integration:
            type: cloud_functions
            function_id: <function_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-шлюз for-serverless-shortener.
  2. Удалите функцию for-serverless-shortener.
  3. Удалите базу данных YDB for-serverless-shortener.
  4. Удалите бакет.

См. такжеСм. также

  • Сокращатель ссылок с помощью Terraform

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

Предыдущая
Обзор
Следующая
Terraform
Создавайте контент и получайте гранты!Готовы написать своё руководство? Участвуйте в контент-программе и получайте гранты на работу с облачными сервисами!
Подробнее о программе
Проект Яндекса
© 2026 ТОО «Облачные Сервисы Казахстан»