Подключение Workers с помощью привязок сервисов

CloudflareBeginner
Практиковаться сейчас

Введение

API поддержки должен обращаться к каталогу, которым владеет другой Worker. Вы подключите общедоступный API к предоставленному внутреннему каталогу, воспроизведёте и исправите отсутствующую привязку, а затем развернёте оба сервиса так, чтобы каталог оставался без общедоступной конечной точки.

Используйте собственную учебную учётную запись Cloudflare и знания об авторизации, конфигурации и развёртывании, полученные в предыдущих лабораторных работах. Эта независимая виртуальная машина запускается в каталоге /home/labex/project/service-binding с Node.js 22.22.0, локальным для проекта Wrangler 4.131.1 и синтетическими тестовыми данными каталога. Предыдущая виртуальная машина и ресурсы не используются повторно. Для выполнения упражнения не нужны купленный домен, база данных или платный тариф; небольшое количество запросов учитывается в обычном использовании учётной записи.

Оставьте один терминал открытым. Вы запустите два локальных процесса, создадите два временных облачных Worker с уникальными именами, проверите их соединение, удалите вызывающий Worker и зависимость, а перед завершением виртуальной машины выйдете из системы.

Воспроизведение отсутствующей привязки сервиса

На этом этапе вы создадите общедоступный API, у которого зависимость от каталога намеренно не настроена. Отдельный предоставленный Worker владеет двумя синтетическими записями каталога. Пока оба процесса работают только в этой виртуальной машине.

cd /home/labex/project/service-binding
node --version
npx wrangler --version
cat catalog/index.js

Ожидаемые версии — Node v22.22.0 и Wrangler 4.131.1. При настройке были установлены локальные зависимости проекта; на другой машине используйте npm ci с lock-файлом этого проекта. Тестовый обработчик возвращает общедоступную метку сервиса, две записи и необязательное синтетическое значение запроса probe, с помощью которого можно отслеживать запрос. Он ничего не сохраняет.

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

WORKER_NAME="labex-binding-$(openssl rand -hex 6)"
cat > wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-09-14",
  "workers_dev": true,
  "preview_urls": false,
  "services": []
}
CONFIG
cat > catalog/wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME-catalog",
  "main": "index.js",
  "compatibility_date": "2026-09-14",
  "workers_dev": false,
  "preview_urls": false,
  "routes": [],
  "vars": {"SERVICE_ID": "$WORKER_NAME-catalog"}
}
CONFIG

Для каталога отключены и workers.dev, и URL предварительного просмотра; маршруты отсутствуют. При локальной разработке всё равно открывается loopback-порт для тестирования, но это не создаёт общедоступную облачную конечную точку. Пустой список services в общедоступном API — это ошибка, которую вы будете диагностировать.

Запишите обработчик общедоступного API. Маршрут /health работает независимо от каталога. Перед обращением к /catalog обработчик проверяет наличие привязки. catalog.internal — это полностью определённый URL-заполнитель, а не DNS-имя, которое нужно регистрировать: env.CATALOG выбирает целевой Worker. Мы создаём новый GET-запрос только с предусмотренным значением запроса, не передавая произвольные заголовки клиента.

cat > src/index.js <<'JS'
export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    if (url.pathname === '/health' && request.method === 'GET') {
      return Response.json({status: 'ok'});
    }
    if (url.pathname !== '/catalog') return Response.json({error: 'not_found'}, {status: 404});
    if (request.method !== 'GET') {
      return Response.json({error: 'method_not_allowed'}, {status: 405, headers: {Allow: 'GET'}});
    }
    if (!env.CATALOG) return Response.json({error: 'catalog_binding_missing'}, {status: 503});
    // This hostname completes the Request URL. The binding selects the target Worker.
    const target = new URL('https://catalog.internal/catalog');
    target.searchParams.set('probe', url.searchParams.get('probe') || '');
    try {
      return await env.CATALOG.fetch(new Request(target, {method: 'GET'}));
    } catch {
      return Response.json({error: 'catalog_unavailable'}, {status: 502});
    }
  }
};
JS

Запустите предоставленный каталог и API как отдельные фоновые задания, используя разные HTTP-порты и порты инспектора. Журналы показывают запуск процессов, а & возвращает приглашение оболочки.

npx wrangler dev --config catalog/wrangler.jsonc --ip 127.0.0.1 --port 8081 --inspector-port 9230 > catalog.log 2>&1 &
npx wrangler dev --config wrangler.jsonc --ip 127.0.0.1 --port 8080 --inspector-port 9231 > api.log 2>&1 &
cat catalog.log
cat api.log

Дождитесь готовности обоих процессов по сообщениям в журналах. При необходимости повторяйте cat, затем проверьте ответы:

curl -i http://127.0.0.1:8081/catalog
curl -i http://127.0.0.1:8080/health
curl -i http://127.0.0.1:8080/catalog

Каталог должен вернуть статус 200 и две записи; health — статус 200 и {"status":"ok"}; маршрут каталога API — статус 503 и {"error":"catalog_binding_missing"}. Зависимость работает, но у вызывающего Worker нет настроенной возможности обращаться к ней. Пока привязка отсутствует, выполните проверку состояния.

Объявление и проверка внутреннего соединения

На этом этапе вы исправите конфигурацию, не изменяя код API. Просмотрите фактические фоновые задания и остановите только процесс API; в примере предполагается, что это задание 2.

jobs
kill %2
cat > wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-09-14",
  "workers_dev": true,
  "preview_urls": false,
  "services": [{"binding": "CATALOG", "service": "$WORKER_NAME-catalog"}]
}
CONFIG

binding — это имя свойства, доступного как env.CATALOG. service — точное имя целевого Worker из его конфигурации. Несовпадение в любой из этих частей — отдельная проблема: отсутствие свойства вызывает явный ответ 503, а недоступный целевой Worker может вызвать ответ 502 или ошибку запуска/развёртывания. Не заменяйте вызов привязки общедоступным URL.

npx wrangler dev --config wrangler.jsonc --ip 127.0.0.1 --port 8080 --inspector-port 9231 > api.log 2>&1 &
cat api.log

Дождитесь готовности и проверьте таблицу привязок. Wrangler находит запущенный каталог по имени и сообщает состояние соединения. Если соединение отсутствует, проверьте процесс каталога и оба настроенных имени, затем повторите попытку.

curl -i "http://127.0.0.1:8080/catalog?probe=local-check"
curl -i -X POST http://127.0.0.1:8080/catalog
curl -i http://127.0.0.1:8080/missing

Первый ответ должен иметь статус 200 и содержать точную метку сервиса каталога, обе записи и probe: local-check. Проверка метода возвращает статус 405, а неизвестный маршрут — статус 404. Выполняйте проверку при работающих обоих серверах: она отправляет новый probe через общедоступный API и проверяет весь контракт.

Привязки относятся к конфигурациям окружений. Если позднее вы будете использовать --env preview, объявите полный массив services в разделе env.preview и укажите нужный развёрнутый целевой Worker; привязки сервисов не наследуются из верхнего уровня. В этой лабораторной работе используется одно безымянное окружение, и параметр --env не передаётся. См. раздел Окружения Wrangler и интерфейс привязки HTTP-сервиса.

Развёртывание внутреннего сервиса и общедоступного API

На этом этапе вы развернёте то же соединение в собственной учебной учётной записи. Остановите оба фактически запущенных локальных задания, показанных командой jobs; в примере предполагается, что это задания 1 и 2.

jobs
kill %1 %2
npx wrangler login --device --browser=false --scopes account:read user:read workers_scripts:write workers_tail:read

Откройте показанную ссылку для устройства в браузере, где выполнен вход, введите текущий код, просмотрите разрешения Wrangler и Background Access, а затем выберите только свою учебную учётную запись, как было показано ранее. Дождитесь завершения команды в терминале.

npx wrangler whoami --json

Убедитесь, что loggedIn: true, а также проверьте фактические имя и ID учётной записи, даже если отображается только одна учётная запись. Замените YOUR_ACCOUNT_ID в обеих следующих командах на этот же ID; не изменяйте исходные сгенерированные имена и привязку.

cat > catalog/wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME-catalog",
  "main": "index.js",
  "compatibility_date": "2026-09-14",
  "account_id": "YOUR_ACCOUNT_ID",
  "workers_dev": false,
  "preview_urls": false,
  "routes": [],
  "vars": {"SERVICE_ID": "$WORKER_NAME-catalog"}
}
CONFIG
cat > wrangler.jsonc <<CONFIG
{
  "name": "$WORKER_NAME",
  "main": "src/index.js",
  "compatibility_date": "2026-09-14",
  "account_id": "YOUR_ACCOUNT_ID",
  "workers_dev": true,
  "preview_urls": false,
  "services": [{"binding": "CATALOG", "service": "$WORKER_NAME-catalog"}]
}
CONFIG

Сначала разверните целевой Worker, чтобы объявленная зависимость общедоступного Worker уже существовала. Это два независимых развёртывания, а не один атомарный выпуск.

npx wrangler deploy --config catalog/wrangler.jsonc
npx wrangler deploy --config wrangler.jsonc

У каталога не должно быть общедоступного маршрута. API выведет URL workers.dev и свою привязку CATALOG. Скопируйте точный URL API в переменную ниже и используйте уже существующий поддомен workers.dev учётной записи. Если это первая настройка учётной записи, выполните предложение Wrangler выбрать доступный поддомен, не изменяя существующий поддомен.

API_URL="https://YOUR_WORKER.YOUR_SUBDOMAIN.workers.dev"
curl -i "$API_URL/health"
curl -i "$API_URL/catalog?probe=remote-check"

Ожидайте статус 200 для health и результат каталога со значением probe: remote-check. При первом развёртывании или распространении имени хоста может потребоваться короткая повторная попытка; постоянные ответы 503 или 502 требуют проверки конфигурации привязки и развёртывания целевого Worker.

Откройте ту же учебную учётную запись в Dashboard, перейдите в Compute → Workers & Pages и найдите оба точных имени. Откройте вкладку Bindings общедоступного API. На схеме будет показана привязка CATALOG; в расположенной ниже таблице сравните Name (CATALOG) и Value (соответствующий Worker с суффиксом -catalog). Имя привязки становится env.CATALOG в обработчике, а её значение указывает на развёрнутую зависимость.

Общедоступный API с привязкой сервиса CATALOG, направленной на соответствующий внутренний Worker каталога

Перейдите по ссылке на Worker каталога в этой таблице и выберите вкладку Domains. Убедитесь, что верхняя цепочка навигации теперь заканчивается на -catalog. В разделе Worker URL переключатели Production и Preview должны быть выключены. В разделе Custom Domains and Routes не должно быть записей, как показано ниже.

Внутренний Worker каталога с отключёнными production- и preview-URL, без пользовательских доменов и маршрутов

Это примеры имён; используйте сгенерированный суффикс и поддомен учётной записи. Выключенный переключатель означает, что отображаемый адрес не является включённой общедоступной точкой входа. Рабочий запрос API выше достигает этого Worker через привязку сервиса. Оставьте эту проверку только для чтения: не включайте общедоступную конечную точку, не добавляйте маршрут и не дублируйте привязку, чтобы внутренний вызов заработал. Используйте проверку: она отдельно проверяет владение учётной записью, развёрнутую привязку сервиса, настройки конечных точек и удалённый ответ с новым probe. Отключение этих конечных точек не мешает авторизованным операторам учётной записи привязывать сервис или изменять его; это не система входа пользователей.

Удаление вызывающего Worker перед его зависимостью

На этом этапе вы удалите два временных облачных Worker, пока у вас ещё есть авторизация. Файлы конфигурации — это ваш список ресурсов. Перед удалением проверьте сгенерированные имена и ID учётной записи.

cat wrangler.jsonc
cat catalog/wrangler.jsonc

Сначала удалите общедоступный вызывающий Worker, затем внутренний каталог. Это не позволит оставить развёрнутый вызывающий Worker, указывающий на удалённый сервис. При каждом запросе проверьте точное имя лабораторной работы и нажмите единственную клавишу y.

npx wrangler delete --config wrangler.jsonc
npx wrangler delete --config catalog/wrangler.jsonc

Wrangler 4.131.1 может сообщить об ошибке аутентификации устаревшего Workers Sites KV после удаления скрипта. Не расширяйте разрешения и не считайте это сообщение доказательством удаления. Обновите раздел Workers & Pages и выполните проверку: успешный авторизованный список ресурсов должен показывать отсутствие обоих точных имён. Ошибки сети или аутентификации не позволяют сделать вывод. Не затрагивайте другие Workers, учётную запись и существующий поддомен.

Отключение виртуальной машины лабораторной работы

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

npx wrangler logout
npx wrangler whoami --json

Ожидайте явное значение "loggedIn": false. Команда проверки статуса без аутентификации может завершиться с ненулевым кодом; важным подтверждением является её структурированный результат. Выполните проверку, а затем завершите работу виртуальной машины. Вход в Dashboard через браузер выполняется отдельно и может оставаться активным для другой лабораторной работы. Завершение работы виртуальной машины не заменяет удаление облачных ресурсов или выход из системы.

Итоги

Вы обнаружили работающую зависимость, отсутствующую в привязках вызывающего Worker, объявили её точное имя сервиса и отправляли запросы через env.CATALOG.fetch(). Локальные и развёрнутые проверки вернули идентификатор и данные каталога. Вы проверили развёрнутое соединение, оставили общедоступные конечные точки внутреннего сервиса отключёнными, затем удалили вызывающий Worker перед его зависимостью и отключили виртуальную машину.

Привязки сервисов явно задают внутренние соединения между Workers. Именованные окружения требуют собственных объявлений, а локальное соединение само по себе не подтверждает удалённое владение ресурсом или настройку конечной точки.