В этом уроке мы построим приложение TODO List в HTML, CSS и JavaScript, с поворотом: все данные должны храниться внутри недавно забитых работников KV, и само приложение должно быть подано непосредственно из сети CloudFlare. , используя работники CloudFlare.
Для начала давайте разберем этот проект на пару различных дискретных шагов. В частности, это может помочь сосредоточиться на ограничении работы с работниками KV, поскольку обработка данных, как правило, является наиболее сложной частью построения приложения:
- Создайте структуру данных TODOS
- Напишите Todos в работников KV
- Получить тодо от работников KV
- Верните HTML -страницу клиенту, включая Todos (если они существуют)
- Разрешить создание нового Todos в пользовательском интерфейсе
- Разрешить завершение тодоса в пользовательском интерфейсе
- Обработка обновлений TODO
Этот заказ задачи довольно удобен, потому что он почти идеально разделен на две части: во-первых, понимание облачных блюд/AP-level, которые мы должны знать о работниках и KV, и во -вторых, фактически создание пользовательского интерфейса для работы с данными.
Понимание работников
С точки зрения реализации, большая часть этого проекта сосредоточена вокруг KV – хотя это может быть так, полезно сломать Что Рабочие точно.
Сервисные работники – это фоновые сценарии, которые работают в вашем браузере, наряду с вашим заявлением. Работники CloudFlare-та же концепция, но сверхмощные: ваши работники работают в сети CloudFlare Edge, между вашим приложением и браузером клиента. Это открывает огромное количество возможностей для интересных интеграций, особенно учитывая масштаб сети по всему миру. Вот некоторые из использования, которые я думаю, самые интересные:
- Пользовательские правила безопасности/фильтра для блокировки плохих актеров, прежде чем они достигнут происхождения
- Замена/увеличение содержания вашего веб -сайта на основе контента запроса (то есть пользовательских агентов и других заголовков)
- Запросы на кэширование для повышения производительности или использования CloudFlare KV для оптимизации высокопроизводительных задач в вашем приложении
- Создание приложения прямо на грани, полностью удаление зависимости от серверов происхождения
Для этого проекта мы сильно склонимся к последнему конце этого списка, создав приложение, с которым клиенты общаются, обслуживаемые в сети Cloudflare Edge. Это означает, что он будет доступен по всему миру, с низкой задержкой, при этом позволяя легко использовать приложения для строительства непосредственно в JavaScript.
Настройка холста
Для начала я хотел подойти к этому проекту с минимума: нет фреймворков, утилит JS или чего -то в этом роде. В частности, меня больше всего интересовало написание проекта с нуля и обслуживания его непосредственно с края. Обычно я развернул сайт на что -то вроде GitHub Pages , но избежать потребности в происхождении сервера в целом кажется действительно мощной (и исполнительской идеей) – давайте попробуем!
Я также подумал об использовании ToDomvc Как план для создания функциональности для приложения, но даже Ваниль JS Версия – довольно впечатляющее количество код Включая несколько пакетов узлов – это был не совсем краткий кусок кода, чтобы просто сбросить в самого работника.
Вместо этого я решил подойти к началу этого проекта, создав простую, пустую HTML -страницу и включив ее внутри работника. Для начала мы наметим что -нибудь на месте, как это:
Todos
Todos
Держитесь за этот код – мы добавим его позже, внутри сценария работников. Для целей учебника я буду служить этому проекту в todo.kristianfreeman.com , А. Мой личный веб -сайт уже был размещен на Cloudflare, и с тех пор, как я буду служить, пришло время создать моего первого работника.
Создание работника
Внутри своей учетной записи CloudFlare я запрыгнул на вкладку «Рабочие» и запустил редактор работников.
Это одна из моих любимых функций редактора – работа с вашим реальным веб -сайтом, понимание Как Работник будет взаимодействовать с вашим существующим проектом.
Процесс написания работника должен быть знаком всем, кто работал с Fetch Библиотека раньше. Короче говоря, код по умолчанию для работника зацепляет в Fetch Событие, передавая Запрос этого события в пользовательскую функцию, HandLeRequest :
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
Внутри HandLeRequest , мы делаем фактический запрос, используя Fetch и вернуть ответ клиенту. Короче говоря, у нас есть место, чтобы перехватить тело отклика, но по умолчанию мы позволяем ему пройти через:
async function handleRequest(request) {
console.log('Got request', request)
const response = await fetch(request)
console.log('Got response', response)
return response
}
Итак, учитывая это, с чего мы начинаем на самом деле Делать вещи с нашим работником?
В отличие от кода по умолчанию, предоставленному вам в интерфейсе работников, мы хотим пропустить входящий запрос: вместо этого мы построим новый Ответ и подайте его прямо с края:
async function handleRequest(request) {
const response = new Response("Hello!")
return response
}
Учитывая эту очень небольшую функциональность, которую мы добавили к работнику, давайте развернем его. Переходя в вкладку «Маршруты» редактора работников, я добавил маршрут https://todo.kristianfreeman.com/* и прикрепил его к Cloudflare-Worker-Todos сценарий
После привязанности я развернул работника и вуаля! Посещение todo.kristianfreeman.com В браузер дает мне мой простой “Привет!” Ответ обратно.
Написание данных в KV
Следующим шагом является заполнение нашего списка TODO фактическими данными. Для этого мы воспользуемся работниками CloudFlare KV – это простой магазин ключей, к которому вы можете получить доступ внутри своего сценария работника для чтения (и записать, хотя это менее распространено).
Чтобы начать с KV, нам нужно настроить «пространство имен». Все наши кэшированные данные будут храниться внутри этого пространства имен, и даваем лишь немного конфигурации, мы можем получить доступ к этому пространству имен внутри скрипта с предопределенной переменной.
Я создам новое пространство имен под названием Kristian_todos , и в редакторе работника я выставлю пространство имен, привязав его к переменной Kristian_todos Анкет
Учитывая присутствие Kristian_todos В моем сценарии пришло время понять KV API. На момент написания, пространство имен KV имеет три основных метода, которые вы можете использовать для взаимодействия с вашим: получить , положить , а также Удалить Анкет Довольно просто!
Давайте начнем хранение данных, определив первоначальный набор данных, которые мы поместим внутри кэша, используя положить метод Я решил определить объект, DefaultData , вместо простого массива Todos: мы можем захотеть сохранить метаданные и другую информацию внутри этого объекта кэша позже. Учитывая этот объект данных, я буду использовать Json.stringify Чтобы положить простую строку в кеш:
async function handleRequest(request) {
// ...previous code
const defaultData = {
todos: [
{
id: 1,
name: 'Finish the Cloudflare Workers blog post',
completed: false
}
]
}
KRISTIAN_TODOS.put("data", JSON.stringify(defaultData))
}
Работник KV Store – это в конце концов Последовательный: написание в кеш означает, что он станет доступным в итоге , Но можно попытаться прочитать значение обратно из кэша сразу после написания его, только чтобы обнаружить, что кэш еще не обновлен.
Учитывая наличие данных в кэше и предположение о том, что наш кэш в конечном итоге согласован, мы должны немного настроить этот код: во -первых, мы должны на самом деле прочитать из кэша, отступать значение и использовать его в качестве источника данных, если существуют. Если это не так, мы обратимся к DefaultData , установить его как источник данных пока (Помните, это должно быть установлено в будущем … в конце концов ), а также устанавливает его в кэше для будущего использования. После разрыва кода на несколько функций для простоты, результат выглядит так:
const defaultData = {
todos: [
{
id: 1,
name: 'Finish the Cloudflare Workers blog post',
completed: false
}
]
}
const setCache = data => KRISTIAN_TODOS.put("data", data)
const getCache = () => KRISTIAN_TODOS.get("data")
async function getTodos(request) {
// ... previous code
let data;
const cache = await getCache()
if (!cache) {
await setCache(JSON.stringify(defaultData))
data = defaultData
} else {
data = JSON.parse(cache)
}
}
Рендеринг данных из KV
Учитывая присутствие данные В нашем коде, который является кэшированным объектом данных для нашего приложения, мы фактически должны взять эти данные и сделать их доступными на экране.
В нашем сценарии работников мы сделаем новую переменную, html и используйте его, чтобы создать статический шаблон HTML, который мы можем служить клиенту. В HandleRequest , мы можем построить новый Ответ (С помощью заголовка
const html = `
Todos
Todos
`
async function handleRequest(request) {
const response = new Response(html, {
headers: { 'Content-Type': 'text/html' }
})
return response
}
У нас есть статический сайт HTML, и теперь мы можем начать заполнять его данными! В тело , мы добавим уль тег с идентификатором Тодос :
Todos
Учитывая это тело, мы также можем добавить сценарий после тело, которое принимает Тодос Массив, проходит через него, и для каждого тодо в массиве создает li элемент и добавляет его к Тодос список:
Наша статическая страница может принять в window.todos и рендеринг HTML на основе этого, но мы на самом деле не прошли ни в каких данных из KV. Для этого нам нужно сделать пару изменений.
Во -первых, наш html переменная изменится на функция Анкет Функция приведет к аргументу, Тодос , который будет заполнять window.todos переменная в приведенном выше примере кода:
const html = todos => `
`
const defaultData = { todos: [] }
const setCache = (key, data) => KRISTIAN_TODOS.put(key, data)
const getCache = key => KRISTIAN_TODOS.get(key)
async function getTodos(request) {
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
let data
const cache = await getCache(cacheKey)
if (!cache) {
await setCache(cacheKey, JSON.stringify(defaultData))
data = defaultData
} else {
data = JSON.parse(cache)
}
const body = html(JSON.stringify(data.todos || []))
return new Response(body, {
headers: { 'Content-Type': 'text/html' },
})
}
const putInCache = (cacheKey, body) => {
const accountId = '$accountId'
const namespaceId = '$namespaceId'
return fetch(
`https://api.cloudflare.com/client/v4/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${cacheKey}`,
{
method: 'PUT',
body,
headers: {
'X-Auth-Email': '$cloudflareEmail',
'X-Auth-Key': '$cloudflareApiKey',
},
},
)
}
async function updateTodos(request) {
const body = await request.text()
const ip = request.headers.get('CF-Connecting-IP')
const cacheKey = `data-${ip}`
try {
JSON.parse(body)
await putInCache(cacheKey, body)
return new Response(body, { status: 200 })
} catch (err) {
return new Response(err, { status: 500 })
}
}
async function handleRequest(request) {
if (request.method === 'PUT') {
return updateTodos(request)
} else {
return getTodos(request)
}
}
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
Хотите попробовать самостоятельно? Подпишитесь на Работники Cloudflare И дайте ему шанс! Я хотел бы услышать, как это происходит:)
Вы можете найти исходный код для этого проекта, а также readme с инструкциями по развертыванию, на GitHub Анкет
Оригинал: "https://dev.to/cloudflareworkers/building-a-to-do-list-application-with-cloudflare-workers-and-kv-504d"