INTEGRITY Документация

Рефакторинг Worker в Pages Function

В этом руководстве вы узнаете, как переработать Worker, принимающий отправку форм, в Pages Function, которую можно разместить в вашем приложении Cloudflare Pages. Pages Functions это бессерверная функция, которая находится в том же каталоге проекта, что и ваше приложение, и развёртывается вместе с Cloudflare Pages. Она позволяет выполнять серверный код, добавляющий динамическую функциональность без запуска отдельного сервера. Вот некоторые причины, по которым может понадобиться преобразовать Worker в Pages Function:

  1. Если вы управляете serverless-функцией, от которой зависит ваше приложение Pages, и хотите поставлять эту логику без управления Worker как отдельным сервисом.
  2. Если вы переносите Worker на Pages Functions и хотите использовать возможности маршрутизации и middleware Pages Functions.

Общие шаги по рефакторингу

  1. Удалите обработчик fetch и замените его соответствующим OnRequest метод. См. Функции чтобы выбрать подходящий метод для вашей Function.
  2. Передайте context объект в качестве аргумента для нового OnRequest метод для доступа к свойствам параметра контекста: request,env,params и next.
  3. Используйте middleware для обработки логики, которая должна выполняться до или после обработчиков маршрутов. Узнайте больше о использование Middleware в документации по Functions.

Контекст

Чтобы объяснить процесс рефакторинга, в этом руководстве используется простой пример отправки формы.

Отправку форм могут обрабатывать Workers, но это также хороший сценарий использования Pages Functions, поскольку формы обычно привязаны к конкретному приложению.

Если вы уже используете Worker для обработки формы, то наверняка развернули этот Worker и указали его URL в атрибуте action вашей HTML-формы. Это значит, что при изменении логики обработки данных придётся вносить правки в код самого Worker. Если логика вашего Worker используется сразу в нескольких приложениях, Pages Functions в этом случае будет не лучшим решением.

Однако иногда полезно использовать Pages Function когда вы хотите организовать логику функций в той же директории проекта, что и приложение.

Сборка приложения с помощью Pages Functions позволяет управлять клиентской и серверной бессерверной логикой из одного места, а также упрощает написание и отладку кода.

Обработка отправленных данных форм с помощью Airtable и Workers

Одна Airtable это low-code платформа для создания совместных приложений. Она помогает настраивать рабочий процесс, взаимодействовать с командой и обрабатывать отправку форм. В этом примере вы будете использовать функцию отправки форм Airtable.

Airtable можно использовать для хранения записей в разных таблицах в рамках одной учётной записи. При создании Worker для обработки логики отправки первым шагом является использование Wrangler чтобы инициализировать новый Worker в определенной папке или в корне приложения.

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

В следующем блоке кода показан пример Worker, обрабатывающего отправку формы Airtable.

submitHandler асинхронная функция вызывается, если путь запроса равен /submit. Эта функция проверяет, что методом запроса является POST запрос, а затем разбирает данные формы и отправляет их в Airtable, используя ваши учетные данные, которые можно хранить с помощью Wrangler secret.

export default {
	async fetch(request, env, ctx) {
		const url = new URL(request.url);

		if (url.pathname === "/submit") {
			return submitHandler(request, env);
		}

		return fetch(request.url);
	},
};

async function submitHandler(request, env) {
	if (request.method !== "POST") {
		return new Response("Method not allowed", {
			status: 405,
		});
	}
	const body = await request.formData();

	const { first_name, last_name, email, phone, subject, message } =
		Object.fromEntries(body);

	const reqBody = {
		fields: {
			"First Name": first_name,
			"Last Name": last_name,
			Email: email,
			"Phone number": phone,
			Subject: subject,
			Message: message,
		},
	};

	return HandleAirtableData(reqBody, env);
}

const HandleAirtableData = (body, env) => {
	return fetch(
		`https://api.airtable.com/v0/${env.AIRTABLE_BASE_ID}/${encodeURIComponent(
			env.AIRTABLE_TABLE_NAME,
		)}`,
		{
			method: "POST",
			body: JSON.stringify(body),
			headers: {
				Authorization: `Bearer ${env.AIRTABLE_API_KEY}`,
				"Content-type": `application/json`,
			},
		},
	);
};

Проведите рефакторинг вашего Worker

Чтобы отрефакторить приведённый выше Worker, перейдите в каталог проекта Pages и создайте /functions папка. В /functions, создайте form.js файл. Этот файл будет обрабатывать отправку форм.

Затем в form.js файл экспортируйте один onRequestPost:

export async function onRequestPost(context) {
	return await submitHandler(context);
}

У каждого Worker есть addEventListener для отслеживания fetch события, но в Pages Function это не понадобится. Вместо этого вы будете export одного onRequest функция, и в зависимости от обрабатываемого HTTPS-запроса вы будете называть её соответствующим образом. См. Документация по Function чтобы выбрать подходящий метод для вашей функции.

Приведённый выше код принимает request и env в качестве аргументов, которые передают эти свойства в submitHandler функция, которая остается неизменной по сравнению с исходный Worker. Однако, поскольку Functions позволяют указывать тип HTTPS-запроса, вы можете убрать request.method проверку в вашем Worker. Теперь это обрабатывается Pages Functions путём именования onRequest обработчик.

Теперь вы добавите submitHandler функцию и передайте env параметр как свойство. Это позволит вам получить доступ к env в HandleAirtableData функция ниже. Эта функция выполняет POST запрос в Airtable, используя ваши учетные данные Airtable:

export async function onRequestPost(context) {
	return await submitHandler(context);
}

async function submitHandler(context) {
	const body = await context.request.formData();

	const { first_name, last_name, email, phone, subject, message } =
		Object.fromEntries(body);

	const reqBody = {
		fields: {
			"First Name": first_name,
			"Last Name": last_name,
			Email: email,
			"Phone number": phone,
			Subject: subject,
			Message: message,
		},
	};

	return HandleAirtableData({ body: reqBody, env: env });
}

Наконец, создайте HandleAirtableData функция. Эта функция отправляет fetch запрос в Airtable с вашими учетными данными Airtable и телом запроса:

// ..
const HandleAirtableData = async function onRequest({ body, env }) {
	return fetch(
		`https://api.airtable.com/v0/${env.AIRTABLE_BASE_ID}/${encodeURIComponent(
			env.AIRTABLE_TABLE_NAME,
		)}`,
		{
			method: "POST",
			body: JSON.stringify(body),
			headers: {
				Authorization: `Bearer ${env.AIRTABLE_API_KEY}`,
				"Content-type": `application/json`,
			},
		},
	);
};

Function можно протестировать локально с помощью Wrangler. Пройдя это руководство, вы успешно преобразовали Worker для отправки формы в Pages Function для отправки формы.