Rui  Silva

Rui Silva

1661799600

Crie Um Encurtador De URL Com Cloudflare Workers

Você já usou ferramentas como Bitly ou TinyURL para encurtar links longos? Ou você já se perguntou como esses serviços funcionam? Talvez você quisesse criar um encurtador de URL, mas nunca encontrou tempo ou as ferramentas adequadas para fazê-lo. De qualquer forma, se você está interessado neste tema, este artigo é perfeito para você.

Neste post, demonstraremos como construir um serviço básico de encurtador de URL usando Cloudflare Workers . Forneceremos informações detalhadas sobre como os serviços de encurtador de URL funcionam, apresentaremos vários recursos do Cloudflare Workers e forneceremos instruções passo a passo sobre como começar com o Cloudflare Workers.

Vamos começar!

O que são os Trabalhadores da Cloudflare?

O Cloudflare Workers é um serviço que permite implantar código sem servidor na rede Cloudflare. A rede Cloudflare, ou Edge, é uma rede de servidores web espalhados pelo mundo. Uma grande vantagem dos Cloudflare Workers é que você não precisa se preocupar em dimensionar seu código. Além disso, você não precisa se preocupar com os fusos horários em que seu código reside; seu código no Workers está espalhado pelo mundo segundos depois de implantado.

Além disso, os Cloudflare Workers vêm com um armazenamento de dados de chave-valor simples, chamado KV. Neste tutorial, usaremos uma combinação de Cloudflare Workers e armazenamento KV para criar nossa URL mais curta.

Visão geral do projeto: serviço de encurtador de URL

Começaremos criando um encurtador de URL simples e não dinâmico, onde você codifica os sites para os quais deseja redirecionar. Isso servirá como uma introdução para aprender a usar o Wrangler (ferramenta CLI oficial da Cloudflare) e demonstrará os conceitos básicos do domínio Workers.

Em seguida, vamos apimentar um pouco as coisas e adicionar suporte para URLs dinâmicos. Basicamente, vamos interagir com a loja Cloudflare Workers KV e inserir versões curtas da URL e a URL real para a qual queremos redirecionar. Os dados no armazenamento KV serão semelhantes à seguinte estrutura:

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

Por fim, implantaremos nosso código em produção e o veremos funcionar ao vivo em todo o mundo.

Já está animado? Ótimo, vamos pular!

Configurando o ambiente

Para acompanhar este artigo, você precisará do seguinte:

  • Node.js e npm
  • Peão
  • curl (ou o navegador de sua escolha) para testar o encurtador de URL

Eu uso a ferramenta asdf para gerenciar minhas dependências locais, mas você pode usar qualquer gerenciador de versão que preferir. No momento em que escrevo, aqui está minha versão do Node e do npm:

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler é uma ferramenta de linha de comando para construção e, recentemente, ganhou sua versão 2.0. Para os propósitos deste post, o Wrangler atenderá a todas as nossas necessidades. No futuro, podemos usar o Miniflare, um irmão mais robusto e rico em recursos do Wrangler . Mas, por enquanto, vamos instalar o Wrangler globalmente via npm:

$ npm install -g wrangler@2.0.21

No momento em que escrevo, a versão mais recente do Wrangler é 2.0.21, então vamos usar essa.

Legal. Agora que temos todas as dependências em vigor, podemos usar a CLI do Wrangler para gerar nosso Cloudflare Worker inicial.

Gerando o projeto

A ferramenta Wrangler CLI será muito útil aqui.

Para começar, vamos executar um comando para iniciar e configurar nosso projeto corretamente:

$ wrangler init short-it

Este comando fará algumas perguntas. Por enquanto, vamos responder sim (digitando y ) para todos eles:

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Se você respondeu positivamente a todas as perguntas do Wrangler, você terá um nome de projeto short-it, com o seguinte dentro:

  • .gitdiretório em seu projeto, o que significa que você está pronto para enviá-lo ao seu provedor Git
  • package.jsonArquivo
  • tsconfig.jsonarquivo com toda a configuração do TypeScript
  • src/index.tsarquivo com alguma lógica direta para obter uma resposta do nosso Worker

Incrível. Vamos ver se essa coisa funciona!

Vamos cdentrar no short-itdiretório e iniciar o Wrangler no modo de desenvolvimento local:

$ cd short-it
$ wrangler dev --local

Isso deve executar nosso Worker em http://localhost:8787/ . Se visitarmos o localhost, devemos ver um simples “Hello World!” mensagem:

Mensagem Olá Mundo

O trabalhador gerado está exibindo um "Hello World!" mensagem.

Yay! Nós fizemos isso funcionar. Mas como? Vamos olhar mais de perto.

Como funcionam os Cloudflare Workers?

Recebemos nossa primeira mensagem localmente do Worker gerado, mas como exatamente isso funcionou?

Vamos analisar o src/index.tsarquivo gerado para entender melhor o que está acontecendo lá.

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

O código acima inclui uma definição para nosso ambiente (a Envinterface) e alguns comentários relacionados à ENVinterface.

Como a interface está fora do escopo deste artigo, vamos ignorar essa parte do código e focar apenas na lógica principal:

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

O que acontece aqui é que nosso index.tsexport uma fetchfunção. Esta é uma interface semelhante ao Web Workers . Na verdade, é dessa interface que se origina o nome “Cloudflare Workers”. O Cloudflare Workers é semelhante ao Web Workers, exceto que é executado na infraestrutura da Cloudflare em vez de em um navegador.

No código acima, a fetchfunção retorna um novo Responseobjeto com a mensagem “Hello World!” texto. Então, quando executamos nosso Worker, essa fetchfunção é invocada. Em seguida, a função invocada fetchretorna o “Hello World!” resposta, e é isso que pegamos no navegador (ou por meio de qualquer ferramenta usada para invocar o Worker).

OK, esclarecemos o básico dos Trabalhadores da Cloudflare. Podemos seguir em frente com confiança. Se você é novo no TypeScript, não se preocupe; usaremos seus recursos apenas levemente. Imagine isso como uma integração leve ao mundo do TypeScript.

Ótimo, vamos em frente!

Adicionando um primeiro redirecionamento

Começaremos a trabalhar em nossa lógica com um início suave. Primeiro, faremos com que nosso encurtador de URL redirecione um usuário para um site diferente. Esta será a base para alterações posteriores.

Por enquanto, faremos com que o usuário acesse uma página no site https://http.cat/ quando visitar nosso Worker local.

Se você não estiver familiarizado com https://http.cat/ , é um site divertido que exibe várias imagens de gatos para diferentes status HTTP. Por exemplo, se um usuário fizer uma solicitação ao nosso Trabalhador para http://localhost:8787/404 , ele será direcionado para https://http.cat/404 .

Para conseguir esse redirecionamento, editaremos o src/index.ts, assim:

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

Agora, se visitarmos http://localhost:8787 , receberemos uma mensagem atualizada: “Hello World from our awesome Worker!”, conforme mostrado abaixo:

Olá mundo do trabalhador incrível

Trabalhador exibindo uma mensagem “Hello world” atualizada.

Mas, se tentarmos ir para http://localhost:8787/404 , seremos redirecionados para https://http.cat/404 .

Usuário redirecionado

O usuário é redirecionado para o site http.cat/404.

Ótimo, iniciamos nosso primeiro redirecionamento. Agora, vamos fazer nosso encurtador de URL realmente encurtar alguns URLs.

Encurtando o URL

Por enquanto, adicionaremos uma pequena estrutura de dados para armazenar nossos URLs encurtados. Podemos fazer assim:

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Aqui, adicionamos alguns URLs abreviados:

Você pode alterá-lo para o que quiser apenas para vê-lo funcionando. Agora, quando visito http://localhost:8787/blog , sou redirecionado para uma URL mais longa onde meu blog está localizado. Aqui está o resultado:

Redirecionamentos para o blog

Visitar /blog redireciona para a página real do blog.

Mas, se solicitarmos algum caminho, como http://localhost:8787/missing , recebemos a seguinte mensagem de erro: “Não há URL definida para o caminho: '/missing', desculpe :(“.

Mensagem de erro ausente

Visitar/ausente exibe uma mensagem de erro.

Incrível, agora estamos prontos para mover nossos URLs codificados e suas versões abreviadas para um armazenamento em algum lugar. Felizmente, estamos usando Cloudflare Workers e ele oferece um armazenamento simples de valor-chave chamado KV.

Adicionando armazenamento

Antes de realmente criarmos o KV para nosso projeto, primeiro precisamos fazer login no Cloudflare Workers via Wrangler. Isso é necessário porque o Wrangler posteriormente precisará entrar em contato com a Cloudflare para criar uma instância KV para nós.

Fazendo login na Cloudflare

Para fazer login na Cloudflare, use o seguinte comando:

$ wrangler login

Um navegador será aberto, solicitando que você faça login na Cloudflare. Não se preocupe; o plano gratuito cobre tudo o que precisamos para este tutorial, e você não precisará pagar. Vá em frente e registre-se ou faça login se você já tiver uma conta.

Em seguida, a Cloudflare perguntará se você deseja conceder autorização ao Wrangler. Após concordar, você deverá ver a seguinte tela:

Ferramenta CLI do Wrangler

A ferramenta Wrangler CLI agora está conectada corretamente.

Não deve haver nenhum soluço durante o processo de inscrição. Mas, se você ficar preso em algum ponto, você pode seguir o guia da Cloudflare sobre como criar uma conta .

Incrível! Agora que você está cadastrado e logado, vamos verificar se tudo está conectado corretamente.

Use o seguinte comando:

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

Ótimo, estamos prontos para criar um namespace KV.

Criando um namespace KV

Um namespace KV pode ser considerado como uma instância de KV na rede Cloudflare. Criaremos dois namespaces KV: um para produção onde nosso aplicativo ficará e funcionará e outro para o ambiente de visualização. Usaremos o namespace de visualização enquanto testamos e desenvolvemos nosso encurtador de URL.

Criaremos nossos namespaces KV via Wrangler com os seguintes comandos:

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

Depois que esses dois comandos são executados e ambos os namespaces são criados, precisamos dizer ao Wrangler para usar esses namespaces quando executarmos wrangler dev.

Adicionaremos informações sobre namespaces KV ao wrangler.tomlarquivo na raiz do nosso projeto. Deve ser algo assim:

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

O wrangler.tomlarquivo é um arquivo de configuração que informa wranglercertas informações sobre nosso projeto. Agora, estamos amarrados e prontos para adicionar alguns dados ao nosso KV.

Adicionando dados ao KV

Nosso próximo passo é semear os dados para o KV. Lembre-se, temos dois namespaces, então teremos que executar dois comandos para ter os dados em ambos os lugares. Vamos adicionar a /blogentrada ao KV:

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

Incrível. Agora temos uma entrada no KV. Em seguida, vamos adicionar a lógica que lê a partir do KV e redireciona o usuário.

Leitura do KV

Removeremos rapidamente nossos URLs curtos codificados antigos e adicionaremos uma chamada ao KV, assim:

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Aqui, adicionamos SHORT_URLScomo um KVNamespacetipo. Isso nos permitirá chamar métodos KV para obter os dados adequados. Em vez do objeto codificado com URLs, desta vez usamos await env.SHORT_URLS.get(pathname).

A chamada para env.SHORT_URLS.get(pathname)tenta obter a chave do KV. Se ele retornar uma promessa, devemos await. Mas, se houver um valor para determinado pathname, o usuário será redirecionado para esse URL.

Agora, quando visitarmos http://localhost:8787/blog , seremos redirecionados para a URL real do blog que colocamos no KV. Isso parecerá assim:

Ainda redireciona o blog

Visitar /blog ainda nos redireciona para a página real do blog.

Mas, se agora tentarmos visitar qualquer um dos outros URLs que codificamos, receberemos uma mensagem informando que esses URLs não têm um redirecionamento:

Redirecionamento de URL ausente

Visitar /twitter resulta em uma mensagem indicando que o URL não tem um redirecionamento.

Vamos adicionar rapidamente o URL encurtado do Twitter ao KV usando estes comandos:

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

Agora, quando atualizarmos o http://localhost:8787/twitter , devemos ser redirecionados para a conta do Twitter.

Carregando Twitter

O Twitter carrega depois que adicionamos o URL encurtado ao KV.

Incrível, agora temos dois URLs curtos: /bloge /twitter. Vamos tentar implantar nosso serviço e vê-lo em produção.

Como implantar trabalhadores do Cloudflare

A etapa de implantação do Cloudflare Workers é bastante fácil. Vamos utilizar wrangler publish, assim:

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

Agora, os serviços estão disponíveis em https://short-it.nikolalsvk.workers.dev . Yay!

Se você estiver seguindo este tutorial, seus serviços devem estar em algum lugar ao longo da URL https://short-it.YOUR_SUBDOMAIN.workers.dev , dependendo do que você selecionou para YOUR_SUBDOMAIN.

Neste ponto, nosso script Worker é implantado em todo o mundo na rede Cloudflare Edge. Isso significa que amigos e estranhos em todo o mundo podem ser redirecionados incrivelmente rápido para nossa conta do Twitter se visitarem https://short-it.nikolalsvk.workers.dev/twitter .

Empacotando

Obrigado por acompanhar a jornada de criação de um serviço simples de encurtador de URL usando Cloudflare Workers. Neste artigo, apresentamos os conceitos de um Worker dentro do contexto Cloudflare. Também demonstramos como criar e gerenciar dados no armazenamento KV da Cloudflare.

Conseguimos executar tudo isso sem problemas usando o Wrangler, que oferece uma ótima experiência ao desenvolvedor. Mas, o mais importante, conseguimos criar, testar e implantar nosso pequeno serviço que roda rápido em todos os cantos do mundo.

Conseguir isso em uma tecnologia ou serviço semelhante pode exigir muito dinheiro e esforço. No entanto, a Cloudflare oferece suporte a um generoso nível gratuito de 100.000 solicitações por dia. Assim, você pode encurtar muitos URLs e ter muitas visitas antes de entrar em um plano pago.

Todo o código deste artigo está disponível no repositório do GitHub (por favor, marque-o com uma estrela, se você gostar). O serviço de encurtador está disponível em https://short-it.nikolalsvk.workers.dev .

Se você gostou do post, considere compartilhá-lo com seus amigos e colegas de trabalho.

Até a próxima, abração!

Fonte: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

#cloudflare #url 

Crie Um Encurtador De URL Com Cloudflare Workers
曾 俊

曾 俊

1661799600

使用 Cloudflare Workers 创建 URL 缩短器

您是否曾经使用过BitlyTinyURL等工具来缩短长链接?或者,您想知道这些服务是如何工作的吗?也许您想构建一个 URL 缩短器,但从未找到时间或合适的工具来做这件事。无论如何,如果您对此主题感兴趣,那么本文非常适合您。

在这篇文章中,我们将演示如何使用Cloudflare Workers构建基本的 URL 缩短服务。我们将提供有关 URL 缩短服务如何工作的详细信息,介绍 Cloudflare Workers 的几个功能,并提供有关如何开始使用 Cloudflare Workers 的分步说明。

让我们开始吧!

什么是 Cloudflare Workers?

Cloudflare Workers 是一项服务,可让您将无服务器代码部署到 Cloudflare 网络。Cloudflare 网络或 Edge 是遍布全球的 Web 服务器网络。Cloudflare Workers 的一大优点是您不必担心扩展代码。此外,您不必担心代码所在的时区;您在 Workers 中的代码在部署后的几秒钟内就会在全球范围内传播。

最重要的是,Cloudflare Workers 带有一个简单的键值对数据存储,称为 KV。在本教程中,我们将结合使用 Cloudflare Workers 和 KV 存储来构建更短的 URL。

项目概述:URL 缩短服务

我们将首先构建一个简单的非动态 URL 缩短器,您可以在其中硬编码要重定向到的网站。这将作为学习如何使用Wrangler(Cloudflare 的官方 CLI 工具)的介绍,并将演示 Workers 领域的基本概念。

接下来,我们将增加一些趣味并添加对动态 URL 的支持。基本上,我们将与 Cloudflare Workers KV 存储进行交互,并输入 URL 的简短版本和我们想要重定向到的实际 URL。KV 存储中的数据将类似于以下结构:

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

最后,我们会将我们的代码部署到生产环境中,并在全球范围内看到它的运行情况。

你已经兴奋了吗?太好了,让我们跳进去!

设置环境

要继续阅读本文,您需要以下内容:

  • Node.js 和 npm
  • 牧马人
  • curl(或您选择的浏览器)来测试 URL 缩短器

我使用asdf 工具来管理我的本地依赖项,但您可以使用任何您喜欢的版本管理器。在撰写本文时,这是我的 Node 和 npm 版本:

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler 是一个用于构建的命令行工具,最近它有了 2.0 版本。就本文而言,牧马人将满足我们的所有需求。将来,我们可能会使用Miniflare,它是 Wrangler 的一个更强大、功能更丰富的兄弟。但是,现在,让我们通过 npm 全局安装 Wrangler:

$ npm install -g wrangler@2.0.21

在撰写本文时,最新的 Wrangler 版本是 2.0.21,所以我们将使用那个版本。

凉爽的。现在我们已经有了所有的依赖项,我们可以使用 Wrangler CLI 来生成我们的入门 Cloudflare Worker。

生成项目

Wrangler CLI 工具在这里将非常有用。

首先,让我们运行一个命令来正确启动和设置我们的项目:

$ wrangler init short-it

这个命令会问几个问题。现在,我们将为所有这些回答是(通过输入y):

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

如果您对 Wrangler 提出的所有问题的回答都是肯定的,那么您将拥有一个项目名称short-it,其中包含以下内容:

  • .git项目中的目录,这意味着您已准备好将其推送到您的 Git 提供程序
  • package.json文件
  • tsconfig.json包含所有 TypeScript 配置的文件
  • src/index.ts带有一些简单逻辑的文件以从我们的 Worker 中获得响应

惊人的。让我们看看这个东西是否有效!

让我们cd进入short-it目录并以本地开发模式启动 Wrangler:

$ cd short-it
$ wrangler dev --local

这应该在http://localhost:8787/上运行我们的 Worker 。如果我们访问 localhost,我们应该会看到一个简单的“Hello World!” 信息:

你好世界消息

Generated Worker 显示“Hello World!” 信息。

耶!我们让它工作。但是怎么做?让我们仔细看看。

Cloudflare Workers 如何工作?

我们从生成的 Worker 在本地获得了第一条消息,但它究竟是如何工作的呢?

让我们浏览生成的src/index.ts文件,以更好地了解那里发生的事情。

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

上面的代码包括我们的环境(Env接口)的定义和一些与接口相关的注释ENV

由于接口超出了本文的范围,我们将忽略这部分代码,只关注主要逻辑:

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

这里发生的是我们index.ts导出了一个fetch函数。这是一个类似于Web Workers的界面。事实上,“Cloudflare Workers”这个名字就是从这个界面来的。Cloudflare Workers 类似于 Web Workers,不同之处在于它运行在 Cloudflare 基础架构而不是浏览器上。

在上面的代码中,fetch函数返回一个Response带有“Hello World!”的新对象。文本。所以当我们运行我们的 Worker 时,fetch会调用这个函数。然后,被调用的fetch函数返回“Hello World!” 响应,这就是我们在浏览器中获取的(或通过任何用于调用 Worker 的工具)。

好的,我们已经了解了 Cloudflare Workers 的基础知识。我们可以充满信心地继续前进。如果您是 TypeScript 新手,请不要担心;我们只会轻轻地使用它的功能。将其想象为 TypeScript 世界的轻量级入门。

太好了,让我们继续前进!

添加第一个重定向

我们将从一个温和的开始着手我们的逻辑。首先,我们将让我们的 URL 缩短器将用户重定向到不同的网站。这将是以后更改的基础。

现在,当用户访问我们的本地 Worker 时,我们将让用户访问https://http.cat/网站上的一个页面。

如果你不熟悉https://http.cat/,它是一个有趣的网站,显示不同 HTTP 状态的各种猫图片。例如,如果用户向我们的 Worker 请求http://localhost:8787/404,他们将被定向到https://http.cat/404

要实现此重定向,我们将编辑src/index.ts,如下所示:

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

现在,如果我们访问http://localhost:8787,我们将收到一条更新的消息:“Hello World from our awesome Worker!”,如下所示:

来自真棒工人的你好世界

显示更新的“Hello world”消息的工作人员。

但是,如果我们尝试访问http://localhost:8787/404,我们将被重定向到https://http.cat/404

用户重定向

用户被重定向到 http.cat/404 网站。

太好了,我们的第一个重定向开始了。现在,让我们的 URL 缩短器实际上缩短了一些 URL。

缩短网址

现在,我们将添加一个小数据结构来存储我们缩短的 URL。我们可以这样做:

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

在这里,我们添加了几个缩短的 URL:

您可以将其更改为您喜欢的任何内容,以使其正常工作。现在,当我访问http://localhost:8787/blog时,我被重定向到我的博客所在的更长的 URL。结果如下:

重定向到博客

访问 /blog 会重定向到实际的博客页面。

但是,如果我们请求一些路径,例如http://localhost:8787/missing,我们会收到以下错误消息:“路径没有定义的 URL:'/missing',对不起 :(”。

错误消息丢失

访问 /missing 会显示错误消息。

太棒了,现在我们已经准备好将硬编码的 URL 及其缩短的版本移动到某个地方的存储中。幸运的是,我们正在使用 Cloudflare Workers,它提供了一种称为 KV 的简单键值存储。

添加存储

在我们为项目实际创建 KV 之前,我们首先需要通过 Wrangler 登录 Cloudflare Workers。这是必要的,因为 Wrangler 稍后需要联系 Cloudflare 以便为我们创建 KV 实例。

登录 Cloudflare

要登录 Cloudflare,请使用以下命令:

$ wrangler login

将打开一个浏览器,要求您登录 Cloudflare。不用担心; 免费计划涵盖了本教程所需的一切,并且不会要求您付款。继续注册,如果您已经有帐户,请登录。

接下来,Cloudflare 将询问您是否要授予 Wrangler 授权。同意后,您应该会看到以下屏幕:

牧马人 CLI 工具

Wrangler CLI 工具现在已正确连接。

在注册过程中不应该有任何问题。但是,如果您在任何时候遇到困难,可以按照Cloudflare 的创建帐户指南进行操作

惊人的!现在您已注册并登录,让我们检查一切是否正确连接。

使用以下命令:

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

太好了,我们已经准备好创建 KV 命名空间了。

创建 KV 命名空间

可以将 KV 命名空间视为 Cloudflare 网络上的 KV up 实例。我们将创建两个 KV 命名空间:一个用于我们的应用程序将生活和工作的生产环境,另一个用于预览环境。我们将在测试和开发 URL 缩短器时使用 preview 命名空间。

我们将使用以下命令通过 Wrangler 创建 KV 命名空间:

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

在这两个命令运行并创建了两个命名空间之后,我们需要告诉 Wrangler 在运行时使用这些命名空间wrangler dev

wrangler.toml我们将在项目根目录的文件中添加有关 KV 命名空间的信息。它应该看起来像这样:

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

wrangler.toml文件是一个配置文件,它告诉wrangler我们项目的某些信息。现在,我们已经准备好将一些数据添加到我们的 KV 中。

向 KV 添加数据

我们的下一步是将数据播种到 KV。请记住,我们有两个命名空间,所以我们必须运行两个命令才能在两个地方都有数据。让我们将/blog条目添加到 KV:

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

惊人的。现在我们在 KV 中有一个条目。接下来,让我们添加从 KV 读取并重定向用户的逻辑。

从 KV 读取

我们将快速删除旧的硬编码短 URL,并添加对 KV 的调用,如下所示:

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

在这里,我们添加SHORT_URLSKVNamespace类型。这将允许我们调用 KV 方法来获取正确的数据。这次我们使用await env.SHORT_URLS.get(pathname).

调用env.SHORT_URLS.get(pathname)尝试从 KV 获取密钥。如果它返回一个承诺,我们必须await. 但是,如果给定的 有一个值pathname,那么用户将被重定向到该 URL。

现在,当我们访问http://localhost:8787/blog时,我们将被重定向到我们放入 KV 中的实际博客 URL。它看起来像这样:

仍然重定向博客

访问 /blog 仍然会将我们重定向到实际的博客页面。

但是,如果我们现在尝试访问我们硬编码的任何其他 URL,我们将收到一条消息,指出这些 URL 缺少重定向:

URL 缺少重定向

访问 /twitter 会产生一条消息,指示该 URL 缺少重定向。

让我们使用以下命令快速将 Twitter 缩短的 URL 添加到 KV:

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

现在,当我们刷新http://localhost:8787/twitter时,我们应该会被重定向到 Twitter 帐户。

推特加载

在我们将缩短的 URL 添加到 KV 后加载 Twitter。

太棒了,现在我们有两个短 URL:/blog/twitter. 让我们尝试部署我们的服务并在生产中查看它。

部署 Cloudflare Worker

Cloudflare Workers 部署步骤相当简单。我们将使用wrangler publish,如下所示:

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

现在,这些服务在https://short-it.nikolalsvk.workers.dev上线。耶!

如果您按照本教程进行操作,您的服务应该位于 URL https://short-it.YOUR_SUBDOMAIN.workers.dev的某个位置,具体取决于您选择的内容YOUR_SUBDOMAIN

此时,我们的 Worker 脚本已部署在全球各地的 Cloudflare Edge 网络上。这意味着全球各地的朋友和陌生人访问https://short-it.nikolalsvk.workers.dev/twitter时,可以极快地重定向到我们的 Twitter 帐户。

包起来

感谢您继续使用 Cloudflare Workers 创建简单的 URL 缩短服务。在本文中,我们介绍了 Cloudflare 上下文中 Worker 的概念。我们还演示了如何在 Cloudflare 的 KV 存储中创建和管理数据。

我们能够使用 Wrangler 顺利执行所有这些工作,这提供了出色的开发人员体验。但是,最重要的是,我们设法创建、测试和部署了在世界各个角落快速运行的小型服务。

在类似的技术或服务中实现这一目标可能需要大量的金钱和努力。但是,Cloudflare 支持每天 100,000 个请求的免费套餐。因此,您可以在违反付费计划之前缩短许多 URL 并对其进行多次访问。

本文中的所有代码都可以在GitHub 存储库中找到(如果喜欢,请给它加星标)。缩短服务在https://short-it.nikolalsvk.workers.dev上线。

如果您喜欢这篇文章,请考虑与您的朋友和同事分享。

直到下一次,干杯!

来源:https ://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

#cloudflare #url 

使用 Cloudflare Workers 创建 URL 缩短器
Thai  Son

Thai Son

1661797800

Tạo Trình Rút Ngắn URL Với Cloudflare Worker

Bạn đã bao giờ sử dụng các công cụ như Bitly hoặc TinyURL để rút ngắn các liên kết dài chưa? Hoặc, bạn đã tự hỏi làm thế nào các dịch vụ này hoạt động? Có thể bạn muốn xây dựng một công cụ rút ngắn URL nhưng chưa bao giờ tìm thấy thời gian hoặc công cụ thích hợp để làm điều đó. Trong mọi trường hợp, nếu bạn quan tâm đến chủ đề này, bài viết này là hoàn hảo cho bạn.

Trong bài đăng này, chúng tôi sẽ trình bày cách tạo dịch vụ rút gọn URL cơ bản bằng Cloudflare worker . Chúng tôi sẽ cung cấp thông tin chi tiết về cách hoạt động của các dịch vụ rút gọn URL, giới thiệu một số tính năng của Cloudflare worker và hướng dẫn từng bước về cách bắt đầu với Cloudflare worker.

Bắt đầu nào!

Công nhân Cloudflare là gì?

Cloudflare worker là một dịch vụ cho phép bạn triển khai mã không máy chủ vào mạng Cloudflare. Mạng Cloudflare, hay Edge, là một mạng lưới các máy chủ web trải rộng trên toàn cầu. Một điều tuyệt vời về Cloudflare worker là bạn không phải lo lắng về việc mở rộng mã của mình. Ngoài ra, bạn không phải lo lắng về múi giờ mà mã của bạn đang sống; mã của bạn trong Công nhân được lan truyền trên toàn cầu vài giây sau khi được triển khai.

Trên hết, Cloudflare worker đi kèm với một kho dữ liệu giá trị-khóa đơn giản, được gọi là KV. Trong hướng dẫn này, chúng tôi sẽ sử dụng kết hợp Cloudflare worker và KV lưu trữ để xây dựng URL của chúng tôi ngắn hơn.

Tổng quan về dự án: Dịch vụ rút gọn URL

Chúng tôi sẽ bắt đầu bằng cách xây dựng một trình rút ngắn URL đơn giản, không động, nơi bạn mã hóa cứng các trang web mà bạn muốn chuyển hướng đến. Đây sẽ là phần giới thiệu để học cách sử dụng Wrangler (công cụ CLI chính thức của Cloudflare) và sẽ trình bày các khái niệm cơ bản trong lĩnh vực Công nhân.

Tiếp theo, chúng tôi sẽ thêm gia vị cho mọi thứ và thêm hỗ trợ cho các URL động. Về cơ bản, chúng tôi sẽ tương tác với cửa hàng Cloudflare worker KV và nhập các phiên bản ngắn của URL và URL thực mà chúng tôi muốn chuyển hướng đến. Dữ liệu trong KV store sẽ tương tự như cấu trúc sau:

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

Cuối cùng, chúng tôi sẽ triển khai mã của mình để sản xuất và xem nó hoạt động trực tiếp trên toàn cầu.

Bạn đã hào hứng chưa? Tuyệt vời, chúng ta hãy nhảy vào!

Thiết lập môi trường

Để làm theo bài viết này, bạn sẽ cần những thứ sau:

  • Node.js và npm
  • Wrangler
  • curl (hoặc trình duyệt bạn chọn) để kiểm tra trình rút gọn URL

Tôi sử dụng công cụ asdf để quản lý các phụ thuộc cục bộ của mình, nhưng bạn có thể sử dụng bất kỳ trình quản lý phiên bản nào bạn muốn. Tại thời điểm viết bài, đây là phiên bản Node và npm của tôi:

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler là một công cụ dòng lệnh để xây dựng và gần đây, nó đã có phiên bản 2.0. Với mục đích của bài đăng này, Wrangler sẽ đáp ứng mọi nhu cầu của chúng tôi. Trong tương lai, chúng tôi có thể sử dụng Miniflare, một người anh em mạnh mẽ hơn và giàu tính năng hơn của Wrangler . Tuy nhiên, hiện tại, hãy cài đặt Wrangler trên toàn cầu thông qua npm:

$ npm install -g wrangler@2.0.21

Tại thời điểm viết bài, phiên bản Wrangler mới nhất là 2.0.21, vì vậy chúng tôi sẽ tiếp tục với phiên bản đó.

Mát mẻ. Bây giờ chúng ta đã có tất cả các phụ thuộc, chúng ta có thể sử dụng Wrangler CLI để tạo Cloudflare Worker khởi đầu của chúng ta.

Tạo dự án

Công cụ Wrangler CLI sẽ tỏ ra rất hữu ích ở đây.

Để bắt đầu, hãy chạy một lệnh để bắt đầu và thiết lập dự án của chúng tôi đúng cách:

$ wrangler init short-it

Lệnh này sẽ hỏi một số câu hỏi. Hiện tại, chúng tôi sẽ trả lời có (bằng cách nhập y ) cho tất cả chúng:

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Nếu bạn trả lời tích cực cho tất cả các câu hỏi từ Wrangler, thì bạn sẽ có tên dự án short-it, với nội dung sau:

  • .gitthư mục trong dự án của bạn, nghĩa là bạn đã sẵn sàng đẩy nó đến nhà cung cấp Git của mình
  • package.jsontập tin
  • tsconfig.jsontệp với tất cả cấu hình TypeScript
  • src/index.tstệp với một số logic đơn giản để nhận được phản hồi từ Nhân viên của chúng tôi

Đáng kinh ngạc. Hãy xem điều này có hiệu quả không nhé!

Hãy cdvào thư mục short-itvà khởi động Wrangler ở chế độ phát triển cục bộ:

$ cd short-it
$ wrangler dev --local

Điều này sẽ chạy Worker của chúng tôi trên http: // localhost: 8787 / . Nếu chúng ta truy cập localhost, chúng ta sẽ thấy một thông báo đơn giản "Hello World!" thông điệp:

Hello World Message

Generated Worker đang hiển thị thông báo “Hello World!” thông điệp.

Yay! Chúng tôi đã làm cho nó hoạt động. Nhưng bằng cách nào? Chúng ta hãy xem xét kỹ hơn.

Công nhân Cloudflare hoạt động như thế nào?

Chúng tôi đã nhận được thông báo cục bộ đầu tiên từ Worker được tạo, nhưng chính xác thì thông báo đó hoạt động như thế nào?

Hãy xem qua src/index.tstệp đã tạo để hiểu rõ hơn về những gì đang xảy ra ở đó.

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

Đoạn mã trên bao gồm định nghĩa cho môi trường của chúng ta ( Envgiao diện) và một số nhận xét liên quan đến ENVgiao diện.

Vì giao diện nằm ngoài phạm vi của bài viết này, chúng tôi sẽ bỏ qua phần đó của mã và chỉ tập trung vào logic chính:

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

Điều xảy ra ở đây là chúng ta index.tsxuất một fetchhàm. Đây là một giao diện tương tự như Web Worker . Trên thực tế, chính từ giao diện này mà tên gọi “Cloudflare worker” bắt nguồn. Cloudflare worker tương tự như Web worker, ngoại trừ nó chạy trên cơ sở hạ tầng Cloudflare chứ không phải trình duyệt.

Trong đoạn mã trên, fetchhàm trả về một Responseđối tượng mới với "Hello World!" chữ. Vì vậy, khi chúng tôi chạy Worker của mình, fetchhàm này sẽ được gọi. Sau đó, hàm được gọi fetchtrả về "Hello World!" và đây là những gì chúng tôi nhận được trong trình duyệt (hoặc thông qua bất kỳ công cụ nào được sử dụng để gọi Worker).

OK, chúng tôi đã làm rõ những điều cơ bản về Cloudflare worker. Chúng ta có thể tự tin bước tiếp. Nếu bạn chưa quen với TypeScript, đừng lo lắng; chúng tôi sẽ chỉ sử dụng các tính năng của nó một cách nhẹ nhàng. Hãy tưởng tượng điều này giống như một sự giới thiệu nhẹ đến thế giới của TypeScript.

Tuyệt vời, chúng ta hãy tiếp tục!

Thêm chuyển hướng đầu tiên

Chúng tôi sẽ bắt đầu làm việc trên logic của chúng tôi với một khởi đầu nhẹ nhàng. Đầu tiên, chúng tôi sẽ yêu cầu trình rút gọn URL của chúng tôi chuyển hướng người dùng đến một trang web khác. Đây sẽ là nền tảng cho những thay đổi sau này.

Hiện tại, chúng tôi sẽ yêu cầu người dùng truy cập một trang trên trang web https://http.cat/ khi họ truy cập Nhân viên địa phương của chúng tôi.

Nếu bạn chưa quen với https://http.cat/ , đây là một trang web thú vị hiển thị nhiều hình ảnh mèo khác nhau cho các trạng thái HTTP khác nhau. Ví dụ: nếu người dùng yêu cầu Nhân viên của chúng tôi đến http: // localhost: 8787/404 , họ sẽ được chuyển hướng đến https://http.cat/404 .

Để đạt được chuyển hướng này, chúng tôi sẽ chỉnh sửa src/index.ts, như sau:

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

Bây giờ, nếu chúng tôi truy cập http: // localhost: 8787 , chúng tôi sẽ nhận được một thông báo cập nhật: “Xin chào Thế giới từ Người lao động tuyệt vời của chúng tôi!”, Như được hiển thị bên dưới:

Xin chào thế giới từ người lao động tuyệt vời

Nhân viên hiển thị thông báo “Hello world” được cập nhật.

Tuy nhiên, nếu chúng tôi cố gắng truy cập http: // localhost: 8787/404 , chúng tôi sẽ được chuyển hướng đến https://http.cat/404 .

Người dùng được chuyển hướng

Người dùng được chuyển hướng đến trang web http.cat/404.

Great, we got our first redirect going. Now, let’s make our URL shortener actually shorten some URLs.

Shortening the URL

For now, we’ll add a small data structure to store our shortened URLs. We can do it like this:

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Here, we added a couple of shortened URLs:

You can change it to whatever you like just to see it working. Now, when I visit http://localhost:8787/blog, I get redirected to a longer URL where my blog is located. Here’s the result:

Chuyển hướng đến Blog

Visiting /blog redirects to the actual blog page.

But, if we request some path, like http://localhost:8787/missing, we get the following error message: “There is no defined URL for the path: ‘/missing’, sorry :(“.

Thiếu thông báo lỗi

Visiting /missing displays an error message.

Awesome, now we are ready to move our hardcoded URLs and their shortened versions to a storage somewhere. Fortunately, we’re using Cloudflare Workers, and it offers a simple key-value storage called KV.

Adding storage

Before we actually create the KV for our project, we first need to log into Cloudflare Workers via Wrangler. This is necessary because Wrangler will later need to contact Cloudflare in order to create a KV instance for us.

Logging into Cloudflare

To log into Cloudflare, use the following command:

$ wrangler login

A browser will open, asking you to log in to Cloudflare. Don’t worry; the free plan covers everything we’ll need for this tutorial, and you will not be asked for payment. Go ahead and register, or log in if you already have an account.

Next, Cloudflare will ask if you want to grant authorization to Wrangler. After you agree, you should see the following screen:

Công cụ Wrangler CLI

The Wrangler CLI tool is now properly connected.

There shouldn’t be any hiccups during the signup process. But, if you got stuck at any point, you can follow Cloudflare’s guide on creating an account.

Awesome! Now that you are signed up and logged in, let’s check whether everything is connected properly.

Use the following command:

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

Great, we’re ready to make a KV namespace.

Creating a KV namespace

A KV namespace can be thought of it as an instance of KV up on the Cloudflare network. We’ll create two KV namespaces: one for production where our app will live and work and another for the preview environment. We’ll use the preview namespace while we test and develop our URL shortener.

We’ll create our KV namespaces via Wrangler with the following commands:

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

After these two commands run and both namespaces are created, we need to tell Wrangler to use these namespaces when we run wrangler dev.

We’ll add information about KV namespaces to the wrangler.toml file at the root of our project. It should look something like this:

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

The wrangler.toml file is a configuration file that tells wrangler certain information about our project. Now, we’re strapped up and ready to add some data to our KV.

Adding data to the KV

Our next step is to seed the data to the KV. Remember, we have two namespaces so we’ll have to run two commands to have the data in both places. Let’s add the /blog entry to the KV:

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

Awesome. Now we have one entry in the KV. Next, let’s add logic that reads from the KV and redirects the user.

Reading from the KV

We’ll quickly remove our old hardcoded short URLs and add a call to the KV, like so:

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Here, we add SHORT_URLS as a KVNamespace type. This will allow us to call KV methods to get the proper data. Instead of the hardcoded object with URLs, this time we use await env.SHORT_URLS.get(pathname).

The call to env.SHORT_URLS.get(pathname) tries to get the key from the KV. If it returns a promise, we must await. But, if there’s a value for the given pathname, then the user is redirected to that URL.

Now, when we visit http://localhost:8787/blog, we will be redirected to the actual blog URL we put in the KV. It will look like this:

Blog Vẫn chuyển hướng

Visiting /blog still redirects us to the actual blog page.

But, if we now try to visit any of the other URLs we hardcoded, we’ll get a message saying that those URLs are missing a redirect:

URL thiếu chuyển hướng

Visiting /twitter results in a message indicating the URL is missing a redirect.

Let’s quickly add the Twitter shortened URL to the KV using these commands:

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

Now, when we refresh the http://localhost:8787/twitter, we should get redirected to the Twitter account.

Đang tải trên Twitter

Twitter loads after we added the shortened URL to the KV.

Awesome, now we have two short URLs: /blog and /twitter. Let’s try to deploy our service and see it in production.

Deploying Cloudflare Workers

The Cloudflare Workers deployment step is fairly easy. We’ll utilize wrangler publish, like so:

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

Now, the services are live at https://short-it.nikolalsvk.workers.dev. Yay!

If you’re following along with this tutorial, your services should live somewhere along the URL https://short-it.YOUR_SUBDOMAIN.workers.dev, depending on what you selected for YOUR_SUBDOMAIN.

At this point, our Worker script is deployed across the globe on the Cloudflare Edge network. This means that friends and strangers across the globe can get redirected blazingly fast to our Twitter account if they visit https://short-it.nikolalsvk.workers.dev/twitter.

Wrapping up

Thanks for following along on the journey of creating a simple URL shortener service using Cloudflare Workers. In this article, we introduced the concepts of a Worker inside the Cloudflare context. We also demonstrated how to create and manage data in Cloudflare’s KV storage.

We were able to execute all of this smoothly using Wrangler, which provides a great developer experience. But, most importantly, we managed to create, test, and deploy our small service that runs fast in all corners of the world.

Achieving this in a similar technology or service might require a lot of money and effort. However, Cloudflare supports a generous free tier of 100,000 requests per day. So you can shorten many URLs and have many visits on them before breaching into a paid plan.

Tất cả mã trong bài viết này đều có trong repo GitHub (vui lòng gắn dấu sao nếu bạn thích). Dịch vụ rút gọn có trực tuyến tại https://short-it.nikolalsvk.workers.dev .

Nếu bạn thích bài đăng, vui lòng xem xét chia sẻ nó với bạn bè và đồng nghiệp của bạn.

Cho đến lần sau, chúc mừng!

Nguồn: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

 #cloudflare #url 

Tạo Trình Rút Ngắn URL Với Cloudflare Worker
高橋  花子

高橋 花子

1661796000

Cloudflare Workers で URL 短縮サービスを作成する

BitlyTinyURLなどのツールを使用して長いリンクを短縮したことがありますか? または、これらのサービスがどのように機能するのか疑問に思ったことはありませんか? おそらく、URL 短縮サービスを構築したいと思っていましたが、それを行うための時間や適切なツールが見つかりませんでした。いずれにせよ、このトピックに興味がある場合は、この記事が最適です。

この投稿では、Cloudflare Workersを使用して基本的な URL 短縮サービスを構築する方法を紹介します。URL短縮サービスがどのように機能するかについての詳細な情報を提供し、Cloudflare Workersのいくつかの機能を紹介し、Cloudflare Workersを使い始める方法について順を追って説明します.

始めましょう!

Cloudflare ワーカーとは何ですか?

Cloudflare Workers は、サーバーレス コードを Cloudflare ネットワークにデプロイできるサービスです。Cloudflare ネットワークまたは Edge は、世界中に広がる Web サーバーのネットワークです。Cloudflare Workers の素晴らしい点の 1 つは、コードのスケーリングについて心配する必要がないことです。また、コードが存在するタイム ゾーンについて心配する必要はありません。Workers のコードは、デプロイされてから数秒後に世界中に広がります。

その上、Cloudflare ワーカーには、KV と呼ばれる単純なキーと値のデータ ストアが付属しています。このチュートリアルでは、Cloudflare ワーカーと KV ストレージを組み合わせて、URL を短くします。

事業概要:URL短縮サービス

まず、リダイレクト先の Web サイトをハードコーディングする、単純で非動的な URL 短縮サービスを作成します。これは、 Wrangler (Cloudflare の公式 CLI ツール) の使用方法を学習するための入門として機能し、Workers 領域の基本的な概念を示します。

次に、少しスパイスを加えて、動的 URL のサポートを追加します。基本的に、Cloudflare Workers KV ストアと対話し、短いバージョンの URL とリダイレクト先の実際の URL を入力します。KV ストアのデータは、次のような構造になります。

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

最後に、コードを本番環境にデプロイし、世界中で実際に動作することを確認します。

あなたはすでに興奮していますか?よし、飛び込もう!

環境のセットアップ

この記事を進めるには、次のものが必要です。

  • Node.js と npm
  • ラングラー
  • URL 短縮サービスをテストするための curl (または選択したブラウザー)

私はasdf ツールを使用してローカルの依存関係を管理していますが、任意のバージョン マネージャーを使用できます。執筆時点では、これが私の Node と npm のバージョンです。

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler はビルド用のコマンドライン ツールで、最近 2.0 バージョンがリリースされました。この投稿では、Wrangler がすべてのニーズを満たします。将来的には、より堅牢で機能豊富な Wrangler の兄弟である Miniflareを使用する可能性があります。しかし、ここでは、npm を介して Wrangler をグローバルにインストールしましょう。

$ npm install -g wrangler@2.0.21

執筆時点で最新の Wrangler バージョンは 2.0.21 であるため、それを使用します。

涼しい。すべての依存関係が整ったので、Wrangler CLI を使用してスターター Cloudflare Worker を生成できます。

プロジェクトの生成

ここでは、Wrangler CLI ツールが非常に役立ちます。

まず、コマンドを実行して、プロジェクトを適切に開始および設定しましょう。

$ wrangler init short-it

このコマンドは、いくつかの質問をします。ここでは、それらすべてに対して( yと入力して) yes と答えます。

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Wrangler からのすべての質問に肯定的に答えた場合はshort-it、次のようなプロジェクト名が表示されます。

  • .gitプロジェクトのディレクトリ。つまり、Git プロバイダーにプッシュする準備ができています。
  • package.jsonファイル
  • tsconfig.jsonすべての TypeScript 構成を含むファイル
  • src/index.tsワーカーから応答を取得するための簡単なロジックを含むファイル

素晴らしい。これが機能するかどうか見てみましょう!

cdディレクトリに入り、Wranglershort-itをローカル開発モードで起動します。

$ cd short-it
$ wrangler dev --local

これにより、ワーカーがhttp://localhost:8787/で実行されます。localhost にアクセスすると、単純な「Hello World!」が表示されるはずです。メッセージ:

ハローワールドメッセージ

生成されたワーカーは「Hello World!」を表示しています。メッセージ。

わーい!私たちはそれを機能させました。しかし、どのように?詳しく見てみましょう。

Cloudflare ワーカーはどのように機能しますか?

生成されたワーカーからローカルで最初のメッセージを取得しましたが、それはどのように機能したのでしょうか?

src/index.ts何が起こっているのかをよりよく理解するために、生成されたファイルを調べてみましょう。

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

上記のコードには、環境 (Envインターフェース) の定義と、インターフェースに関連するいくつかのコメントが含まれていENVます。

インターフェイスはこの記事の範囲外であるため、コードのその部分は無視して、メイン ロジックのみに焦点を当てます。

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

ここで何が起こるかというと、関数をindex.tsエクスポートするというfetchことです。これはWeb Workersに似たインターフェースです。実際、「Cloudflare Workers」という名前が由来するのは、このインターフェースからです。Cloudflare Workers は Web Workers と似ていますが、ブラウザーではなく Cloudflare インフラストラクチャで実行される点が異なります。

上記のコードでは、関数は「Hello World!」をfetch含む新しいオブジェクトを返します。Response文章。そのため、Worker を実行すると、このfetch関数が呼び出されます。次に、呼び出されたfetch関数は「Hello World!」を返します。これは、ブラウザーで (またはワーカーの呼び出しに使用される任意のツールを介して) 取得したものです。

OK、Cloudflare Workers の基本を片付けました。自信を持って進むことができます。TypeScript を初めて使用する場合でも、心配する必要はありません。その機能を軽く使用します。これを、TypeScript の世界への軽量のオンボーディングと想像してください。

よし、先に進もう!

最初のリダイレクトの追加

穏やかなスタートでロジックの作業を開始します。まず、URL 短縮サービスでユーザーを別の Web サイトにリダイレクトします。これは、後の変更の基礎となります。

ここでは、ユーザーがローカル ワーカーにアクセスしたときに、 https://http.cat/ Web サイトのページにアクセスするようにします。

https://http.cat/に慣れていない場合は、HTTP ステータスごとにさまざまな猫の写真が表示される楽しいサイトです。たとえば、ユーザーがワーカーにhttp://localhost:8787/404へのリクエストを行うと、リクエストはhttps://http.cat/404に転送されます。

このリダイレクトを実現するには、次のsrc/index.tsようにを編集します。

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここで、http://localhost:8787にアクセスすると、以下に示すように、「Hello World from our awesome Worker!」という更新されたメッセージが表示されます。

Hello World From Awesome Worker

更新された「Hello world」メッセージを表示するワーカー。

ただし、http://localhost:8787/404にアクセスしようとすると、 https://http.cat/404にリダイレクトされます。

ユーザーがリダイレクトされました

ユーザーは http.cat/404 Web サイトにリダイレクトされます。

よし、最初のリダイレクトを開始しました。では、URL 短縮機能で実際にいくつかの URL を短縮してみましょう。

URL の短縮

ここでは、短縮 URL を保存するための小さなデータ構造を追加します。次のように実行できます。

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここでは、いくつかの短縮 URL を追加しました。

動作を確認するために、好きなように変更できます。今、http://localhost:8787/blogにアクセスすると、ブログのある長い URL にリダイレクトされます。結果は次のとおりです。

ブログにリダイレクト

/blog にアクセスすると、実際のブログ ページにリダイレクトされます。

しかし、 http://localhost:8787/missingのようなパスを要求すると、次のエラー メッセージが表示されます。

エラーメッセージがありません

/missing にアクセスすると、エラー メッセージが表示されます。

これで、ハードコードされた URL とその短縮バージョンをどこかのストレージに移動する準備が整いました。幸いなことに、私たちは Cloudflare Workers を使用しており、KV と呼ばれるシンプルなキーと値のストレージを提供しています。

ストレージの追加

プロジェクトの KV を実際に作成する前に、Wrangler 経由で Cloudflare Workers にログインする必要があります。KV インスタンスを作成するために、後で Wrangler が Cloudflare に連絡する必要があるため、これが必要です。

Cloudflareへのログイン

Cloudflare にログインするには、次のコマンドを使用します。

$ wrangler login

ブラウザーが開き、Cloudflare へのログインを求められます。心配しないで; 無料プランには、このチュートリアルに必要なものがすべて含まれており、支払いを求められることはありません。先に進んで登録するか、すでにアカウントをお持ちの場合はログインしてください。

次に、Cloudflare は、Wrangler に承認を付与するかどうかを尋ねます。同意すると、次の画面が表示されます。

ラングラー CLI ツール

Wrangler CLI ツールが正しく接続されました。

サインアップ プロセス中に問題が発生することはありません。ただし、どこかで行き詰まった場合は、アカウントの作成に関する Cloudflare のガイドに従うことができます。

素晴らしい!サインアップしてログインしたので、すべてが正しく接続されているかどうかを確認しましょう。

次のコマンドを使用します。

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

これで、KV 名前空間を作成する準備が整いました。

KV 名前空間の作成

KV 名前空間は、Cloudflare ネットワーク上の KV のインスタンスと考えることができます。2 つの KV 名前空間を作成します。1 つはアプリが存在して動作する本番用で、もう 1 つはプレビュー環境用です。URL 短縮サービスをテストおよび開発する間は、プレビューの名前空間を使用します。

次のコマンドを使用して、Wrangler 経由で KV 名前空間を作成します。

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

これら 2 つのコマンドが実行され、両方の名前空間が作成されたら、実行時にこれらの名前空間を使用するように Wrangler に指示する必要がありますwrangler dev

wrangler.tomlプロジェクトのルートにあるファイルに KV 名前空間に関する情報を追加します。次のようになります。

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

このファイルは、プロジェクトに関する特定の情報wrangler.tomlを伝える構成ファイルです。wranglerこれで、KV にデータを追加する準備が整いました。

KV へのデータの追加

次のステップは、データを KV にシードすることです。2 つの名前空間があるため、2 つのコマンドを実行して両方の場所にデータを配置する必要があることを思い出してください。/blogKV にエントリを追加しましょう。

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

素晴らしい。これで、KV に 1 つのエントリができました。次に、KV から読み取ってユーザーをリダイレクトするロジックを追加しましょう。

KV からの読み取り

古いハードコードされた短い URL をすばやく削除し、次のように KV への呼び出しを追加します。

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここではSHORT_URLS、タイプとして追加しKVNamespaceます。これにより、KV メソッドを呼び出して適切なデータを取得できます。URL でハードコーディングされたオブジェクトの代わりに、今回はawait env.SHORT_URLS.get(pathname).

への呼び出しenv.SHORT_URLS.get(pathname)は、KV からキーを取得しようとします。promise を返す場合は、 する必要がありawaitます。ただし、指定された の値がある場合pathname、ユーザーはその URL にリダイレクトされます。

ここで、http://localhost:8787/blogにアクセスすると、KV に入力した実際のブログ URL にリダイレクトされます。次のようになります。

それでもブログをリダイレクト

/blog にアクセスすると、実際のブログ ページにリダイレクトされます。

しかし、ハードコーディングした他の URL にアクセスしようとすると、それらの URL にリダイレクトがないというメッセージが表示されます。

URL のリダイレクトがありません

/twitter にアクセスすると、URL にリダイレクトがないことを示すメッセージが表示されます。

次のコマンドを使用して、Twitter の短縮 URL を KV にすばやく追加しましょう。

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

ここで、http://localhost:8787/twitterを更新すると、Twitter アカウントにリダイレクトされるはずです。

読み込み中

短縮 URL を KV に追加すると、Twitter が読み込まれます。

/blogこれでとの 2 つの短い URL ができ/twitterました。サービスをデプロイして、本番環境で確認してみましょう。

Cloudflare ワーカーのデプロイ

Cloudflare Workers の展開手順はかなり簡単です。を次wrangler publishのように利用します。

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

現在、サービスはhttps://short-it.nikolalsvk.workers.devで公開されています。わーい!

このチュートリアルに従っている場合、サービスは、選択した内容に応じて、URL https://short-it.YOUR_SUBDOMAIN.workers.devYOUR_SUBDOMAINのどこかに存在するはずです。

この時点で、Worker スクリプトは Cloudflare Edge ネットワーク上で世界中に展開されています。これは、世界中の友人や見知らぬ人がhttps://short-it.nikolalsvk.workers.dev/twitterにアクセスすると、非常に高速に Twitter アカウントにリダイレクトされることを意味します。

まとめ

Cloudflare Workers を使用してシンプルな URL 短縮サービスを作成する旅を続けてくれてありがとう。この記事では、Cloudflare コンテキスト内のワーカーの概念を紹介しました。また、Cloudflare の KV ストレージでデータを作成および管理する方法も示しました。

優れた開発者エクスペリエンスを提供する Wrangler を使用して、これらすべてをスムーズに実行することができました。しかし、最も重要なことは、世界の隅々で高速に動作する小さなサービスを作成、テスト、デプロイすることができたことです。

同様の技術やサービスでこれを実現するには、多額の費用と労力が必要になる場合があります。ただし、Cloudflare は、1 日あたり 100,000 リクエストの寛大な無料利用枠をサポートしています。したがって、有料プランに違反する前に、多くの URL を短縮し、それらに多くの訪問をすることができます.

この記事のすべてのコードは、GitHub リポジトリで入手できます(気に入った場合はスターを付けてください)。短縮サービスはhttps://short-it.nikolalsvk.workers.devで公開されています。

投稿が気に入ったら、友人や同僚と共有することを検討してください。

次回まで、乾杯!

ソース: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

BitlyTinyURLなどのツールを使用して長いリンクを短縮したことがありますか? または、これらのサービスがどのように機能するのか疑問に思ったことはありませんか? おそらく、URL 短縮サービスを構築したいと思っていましたが、それを行うための時間や適切なツールが見つかりませんでした。いずれにせよ、このトピックに興味がある場合は、この記事が最適です。

この投稿では、Cloudflare Workersを使用して基本的な URL 短縮サービスを構築する方法を紹介します。URL短縮サービスがどのように機能するかについての詳細な情報を提供し、Cloudflare Workersのいくつかの機能を紹介し、Cloudflare Workersを使い始める方法について順を追って説明します.

始めましょう!

Cloudflare ワーカーとは何ですか?

Cloudflare Workers は、サーバーレス コードを Cloudflare ネットワークにデプロイできるサービスです。Cloudflare ネットワークまたは Edge は、世界中に広がる Web サーバーのネットワークです。Cloudflare Workers の素晴らしい点の 1 つは、コードのスケーリングについて心配する必要がないことです。また、コードが存在するタイム ゾーンについて心配する必要はありません。Workers のコードは、デプロイされてから数秒後に世界中に広がります。

その上、Cloudflare ワーカーには、KV と呼ばれる単純なキーと値のデータ ストアが付属しています。このチュートリアルでは、Cloudflare ワーカーと KV ストレージを組み合わせて、URL を短くします。

事業概要:URL短縮サービス

まず、リダイレクト先の Web サイトをハードコーディングする、単純で非動的な URL 短縮サービスを作成します。これは、 Wrangler (Cloudflare の公式 CLI ツール) の使用方法を学習するための入門として機能し、Workers 領域の基本的な概念を示します。

次に、少しスパイスを加えて、動的 URL のサポートを追加します。基本的に、Cloudflare Workers KV ストアと対話し、短いバージョンの URL とリダイレクト先の実際の URL を入力します。KV ストアのデータは、次のような構造になります。

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

最後に、コードを本番環境にデプロイし、世界中で実際に動作することを確認します。

あなたはすでに興奮していますか?よし、飛び込もう!

環境のセットアップ

この記事を進めるには、次のものが必要です。

  • Node.js と npm
  • ラングラー
  • URL 短縮サービスをテストするための curl (または選択したブラウザー)

私はasdf ツールを使用してローカルの依存関係を管理していますが、任意のバージョン マネージャーを使用できます。執筆時点では、これが私の Node と npm のバージョンです。

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler はビルド用のコマンドライン ツールで、最近 2.0 バージョンがリリースされました。この投稿では、Wrangler がすべてのニーズを満たします。将来的には、より堅牢で機能豊富な Wrangler の兄弟である Miniflareを使用する可能性があります。しかし、ここでは、npm を介して Wrangler をグローバルにインストールしましょう。

$ npm install -g wrangler@2.0.21

執筆時点で最新の Wrangler バージョンは 2.0.21 であるため、それを使用します。

涼しい。すべての依存関係が整ったので、Wrangler CLI を使用してスターター Cloudflare Worker を生成できます。

プロジェクトの生成

ここでは、Wrangler CLI ツールが非常に役立ちます。

まず、コマンドを実行して、プロジェクトを適切に開始および設定しましょう。

$ wrangler init short-it

このコマンドは、いくつかの質問をします。ここでは、それらすべてに対して( yと入力して) yes と答えます。

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Wrangler からのすべての質問に肯定的に答えた場合はshort-it、次のようなプロジェクト名が表示されます。

  • .gitプロジェクトのディレクトリ。つまり、Git プロバイダーにプッシュする準備ができています。
  • package.jsonファイル
  • tsconfig.jsonすべての TypeScript 構成を含むファイル
  • src/index.tsワーカーから応答を取得するための簡単なロジックを含むファイル

素晴らしい。これが機能するかどうか見てみましょう!

cdディレクトリに入り、Wranglershort-itをローカル開発モードで起動します。

$ cd short-it
$ wrangler dev --local

これにより、ワーカーがhttp://localhost:8787/で実行されます。localhost にアクセスすると、単純な「Hello World!」が表示されるはずです。メッセージ:

ハローワールドメッセージ

生成されたワーカーは「Hello World!」を表示しています。メッセージ。

わーい!私たちはそれを機能させました。しかし、どのように?詳しく見てみましょう。

Cloudflare ワーカーはどのように機能しますか?

生成されたワーカーからローカルで最初のメッセージを取得しましたが、それはどのように機能したのでしょうか?

src/index.ts何が起こっているのかをよりよく理解するために、生成されたファイルを調べてみましょう。

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

上記のコードには、環境 (Envインターフェース) の定義と、インターフェースに関連するいくつかのコメントが含まれていENVます。

インターフェイスはこの記事の範囲外であるため、コードのその部分は無視して、メイン ロジックのみに焦点を当てます。

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

ここで何が起こるかというと、関数をindex.tsエクスポートするというfetchことです。これはWeb Workersに似たインターフェースです。実際、「Cloudflare Workers」という名前が由来するのは、このインターフェースからです。Cloudflare Workers は Web Workers と似ていますが、ブラウザーではなく Cloudflare インフラストラクチャで実行される点が異なります。

上記のコードでは、関数は「Hello World!」をfetch含む新しいオブジェクトを返します。Response文章。そのため、Worker を実行すると、このfetch関数が呼び出されます。次に、呼び出されたfetch関数は「Hello World!」を返します。これは、ブラウザーで (またはワーカーの呼び出しに使用される任意のツールを介して) 取得したものです。

OK、Cloudflare Workers の基本を片付けました。自信を持って進むことができます。TypeScript を初めて使用する場合でも、心配する必要はありません。その機能を軽く使用します。これを、TypeScript の世界への軽量のオンボーディングと想像してください。

よし、先に進もう!

最初のリダイレクトの追加

穏やかなスタートでロジックの作業を開始します。まず、URL 短縮サービスでユーザーを別の Web サイトにリダイレクトします。これは、後の変更の基礎となります。

ここでは、ユーザーがローカル ワーカーにアクセスしたときに、 https://http.cat/ Web サイトのページにアクセスするようにします。

https://http.cat/に慣れていない場合は、HTTP ステータスごとにさまざまな猫の写真が表示される楽しいサイトです。たとえば、ユーザーがワーカーにhttp://localhost:8787/404へのリクエストを行うと、リクエストはhttps://http.cat/404に転送されます。

このリダイレクトを実現するには、次のsrc/index.tsようにを編集します。

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここで、http://localhost:8787にアクセスすると、以下に示すように、「Hello World from our awesome Worker!」という更新されたメッセージが表示されます。

Hello World From Awesome Worker

更新された「Hello world」メッセージを表示するワーカー。

ただし、http://localhost:8787/404にアクセスしようとすると、 https://http.cat/404にリダイレクトされます。

ユーザーがリダイレクトされました

ユーザーは http.cat/404 Web サイトにリダイレクトされます。

よし、最初のリダイレクトを開始しました。では、URL 短縮機能で実際にいくつかの URL を短縮してみましょう。

URL の短縮

ここでは、短縮 URL を保存するための小さなデータ構造を追加します。次のように実行できます。

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここでは、いくつかの短縮 URL を追加しました。

動作を確認するために、好きなように変更できます。今、http://localhost:8787/blogにアクセスすると、ブログのある長い URL にリダイレクトされます。結果は次のとおりです。

ブログにリダイレクト

/blog にアクセスすると、実際のブログ ページにリダイレクトされます。

しかし、 http://localhost:8787/missingのようなパスを要求すると、次のエラー メッセージが表示されます。

エラーメッセージがありません

/missing にアクセスすると、エラー メッセージが表示されます。

これで、ハードコードされた URL とその短縮バージョンをどこかのストレージに移動する準備が整いました。幸いなことに、私たちは Cloudflare Workers を使用しており、KV と呼ばれるシンプルなキーと値のストレージを提供しています。

ストレージの追加

プロジェクトの KV を実際に作成する前に、Wrangler 経由で Cloudflare Workers にログインする必要があります。KV インスタンスを作成するために、後で Wrangler が Cloudflare に連絡する必要があるため、これが必要です。

Cloudflareへのログイン

Cloudflare にログインするには、次のコマンドを使用します。

$ wrangler login

ブラウザーが開き、Cloudflare へのログインを求められます。心配しないで; 無料プランには、このチュートリアルに必要なものがすべて含まれており、支払いを求められることはありません。先に進んで登録するか、すでにアカウントをお持ちの場合はログインしてください。

次に、Cloudflare は、Wrangler に承認を付与するかどうかを尋ねます。同意すると、次の画面が表示されます。

ラングラー CLI ツール

Wrangler CLI ツールが正しく接続されました。

サインアップ プロセス中に問題が発生することはありません。ただし、どこかで行き詰まった場合は、アカウントの作成に関する Cloudflare のガイドに従うことができます。

素晴らしい!サインアップしてログインしたので、すべてが正しく接続されているかどうかを確認しましょう。

次のコマンドを使用します。

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

これで、KV 名前空間を作成する準備が整いました。

KV 名前空間の作成

KV 名前空間は、Cloudflare ネットワーク上の KV のインスタンスと考えることができます。2 つの KV 名前空間を作成します。1 つはアプリが存在して動作する本番用で、もう 1 つはプレビュー環境用です。URL 短縮サービスをテストおよび開発する間は、プレビューの名前空間を使用します。

次のコマンドを使用して、Wrangler 経由で KV 名前空間を作成します。

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

これら 2 つのコマンドが実行され、両方の名前空間が作成されたら、実行時にこれらの名前空間を使用するように Wrangler に指示する必要がありますwrangler dev

wrangler.tomlプロジェクトのルートにあるファイルに KV 名前空間に関する情報を追加します。次のようになります。

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

このファイルは、プロジェクトに関する特定の情報wrangler.tomlを伝える構成ファイルです。wranglerこれで、KV にデータを追加する準備が整いました。

KV へのデータの追加

次のステップは、データを KV にシードすることです。2 つの名前空間があるため、2 つのコマンドを実行して両方の場所にデータを配置する必要があることを思い出してください。/blogKV にエントリを追加しましょう。

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

素晴らしい。これで、KV に 1 つのエントリができました。次に、KV から読み取ってユーザーをリダイレクトするロジックを追加しましょう。

KV からの読み取り

古いハードコードされた短い URL をすばやく削除し、次のように KV への呼び出しを追加します。

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

ここではSHORT_URLS、タイプとして追加しKVNamespaceます。これにより、KV メソッドを呼び出して適切なデータを取得できます。URL でハードコーディングされたオブジェクトの代わりに、今回はawait env.SHORT_URLS.get(pathname).

への呼び出しenv.SHORT_URLS.get(pathname)は、KV からキーを取得しようとします。promise を返す場合は、 する必要がありawaitます。ただし、指定された の値がある場合pathname、ユーザーはその URL にリダイレクトされます。

ここで、http://localhost:8787/blogにアクセスすると、KV に入力した実際のブログ URL にリダイレクトされます。次のようになります。

それでもブログをリダイレクト

/blog にアクセスすると、実際のブログ ページにリダイレクトされます。

しかし、ハードコーディングした他の URL にアクセスしようとすると、それらの URL にリダイレクトがないというメッセージが表示されます。

URL のリダイレクトがありません

/twitter にアクセスすると、URL にリダイレクトがないことを示すメッセージが表示されます。

次のコマンドを使用して、Twitter の短縮 URL を KV にすばやく追加しましょう。

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

ここで、http://localhost:8787/twitterを更新すると、Twitter アカウントにリダイレクトされるはずです。

読み込み中

短縮 URL を KV に追加すると、Twitter が読み込まれます。

/blogこれでとの 2 つの短い URL ができ/twitterました。サービスをデプロイして、本番環境で確認してみましょう。

Cloudflare ワーカーのデプロイ

Cloudflare Workers の展開手順はかなり簡単です。を次wrangler publishのように利用します。

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

現在、サービスはhttps://short-it.nikolalsvk.workers.devで公開されています。わーい!

このチュートリアルに従っている場合、サービスは、選択した内容に応じて、URL https://short-it.YOUR_SUBDOMAIN.workers.devYOUR_SUBDOMAINのどこかに存在するはずです。

この時点で、Worker スクリプトは Cloudflare Edge ネットワーク上で世界中に展開されています。これは、世界中の友人や見知らぬ人がhttps://short-it.nikolalsvk.workers.dev/twitterにアクセスすると、非常に高速に Twitter アカウントにリダイレクトされることを意味します。

まとめ

Cloudflare Workers を使用してシンプルな URL 短縮サービスを作成する旅を続けてくれてありがとう。この記事では、Cloudflare コンテキスト内のワーカーの概念を紹介しました。また、Cloudflare の KV ストレージでデータを作成および管理する方法も示しました。

優れた開発者エクスペリエンスを提供する Wrangler を使用して、これらすべてをスムーズに実行することができました。しかし、最も重要なことは、世界の隅々で高速に動作する小さなサービスを作成、テスト、デプロイすることができたことです。

同様の技術やサービスでこれを実現するには、多額の費用と労力が必要になる場合があります。ただし、Cloudflare は、1 日あたり 100,000 リクエストの寛大な無料利用枠をサポートしています。したがって、有料プランに違反する前に、多くの URL を短縮し、それらに多くの訪問をすることができます.

この記事のすべてのコードは、GitHub リポジトリで入手できます(気に入った場合はスターを付けてください)。短縮サービスはhttps://short-it.nikolalsvk.workers.devで公開されています。

投稿が気に入ったら、友人や同僚と共有することを検討してください。

次回まで、乾杯!

ソース: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

  #cloudflare #url 

Cloudflare Workers で URL 短縮サービスを作成する
Léon  Peltier

Léon Peltier

1661794740

Créer Un Raccourcisseur D'URL Avec Cloudflare Workers

Avez-vous déjà utilisé des outils comme Bitly ou TinyURL pour raccourcir les liens longs ? Ou vous êtes-vous demandé comment ces services fonctionnent ? Peut-être avez-vous voulu créer un raccourcisseur d'URL mais n'avez jamais trouvé le temps ni les outils appropriés pour le faire. En tout cas, si ce sujet vous intéresse, cet article est parfait pour vous.

Dans cet article, nous montrerons comment créer un service de raccourcissement d'URL de base à l'aide de Cloudflare Workers . Nous fournirons des informations détaillées sur le fonctionnement des services de raccourcissement d'URL, présenterons plusieurs fonctionnalités de Cloudflare Workers et donnerons des instructions étape par étape sur la façon de démarrer avec Cloudflare Workers.

Commençons!

Qu'est-ce que Cloudflare Workers ?

Cloudflare Workers est un service qui vous permet de déployer du code sans serveur sur le réseau Cloudflare. Le réseau Cloudflare, ou Edge, est un réseau de serveurs Web répartis dans le monde entier. L'un des avantages de Cloudflare Workers est que vous n'avez pas à vous soucier de la mise à l'échelle de votre code. De plus, vous n'avez pas à vous soucier des fuseaux horaires dans lesquels vit votre code ; votre code dans Workers est réparti dans le monde entier quelques secondes après son déploiement.

En plus de cela, Cloudflare Workers est livré avec un simple magasin de données clé-valeur, appelé KV. Dans ce didacticiel, nous utiliserons une combinaison de Cloudflare Workers et de stockage KV pour raccourcir notre URL.

Présentation du projet : service de raccourcissement d'URL

Nous allons commencer par créer un raccourcisseur d'URL simple et non dynamique dans lequel vous codez en dur les sites Web vers lesquels vous souhaitez rediriger. Cela servira d'introduction à l'apprentissage de l'utilisation de Wrangler (l'outil CLI officiel de Cloudflare) et démontrera les concepts de base dans le domaine des travailleurs.

Ensuite, nous allons pimenter un peu les choses et ajouter la prise en charge des URL dynamiques. Fondamentalement, nous allons interagir avec le magasin Cloudflare Workers KV et saisir des versions courtes de l'URL et de l'URL réelle vers laquelle nous voulons rediriger. Les données du magasin KV seront similaires à la structure suivante :

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

Enfin, nous déploierons notre code en production et le verrons fonctionner en direct dans le monde entier.

Êtes-vous déjà excité? Super, allons-y !

Mise en place de l'environnement

Pour suivre cet article, vous aurez besoin des éléments suivants :

  • Node.js et npm
  • Cow-boy
  • curl (ou le navigateur de votre choix) pour tester le raccourcisseur d'URL

J'utilise l' outil asdf pour gérer mes dépendances locales, mais vous pouvez utiliser n'importe quel gestionnaire de version que vous préférez. Au moment d'écrire ces lignes, voici ma version de Node et npm :

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler est un outil de construction en ligne de commande, et récemment, il a obtenu sa version 2.0. Aux fins de cet article, Wrangler répondra à tous nos besoins. À l'avenir, nous pourrions utiliser Miniflare, un frère plus robuste et riche en fonctionnalités de Wrangler . Mais, pour l'instant, installons Wrangler globalement via npm :

$ npm install -g wrangler@2.0.21

Au moment d'écrire ces lignes, la dernière version de Wrangler est la 2.0.21, nous allons donc choisir celle-là.

Cool. Maintenant que nous avons toutes les dépendances en place, nous pouvons utiliser la CLI Wrangler pour générer notre Cloudflare Worker de démarrage.

Génération du projet

L'outil Wrangler CLI s'avérera très utile ici.

Pour commencer, exécutons une commande pour lancer et configurer correctement notre projet :

$ wrangler init short-it

Cette commande posera quelques questions. Pour l'instant, nous allons répondre oui (en tapant y ) pour chacun d'eux :

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Si vous avez répondu positivement à toutes les questions de Wrangler, alors vous aurez un nom de projet short-it, avec ce qui suit à l'intérieur :

  • .gitrépertoire dans votre projet, ce qui signifie que vous êtes prêt à le pousser vers votre fournisseur Git
  • package.jsondossier
  • tsconfig.jsonfichier avec toute la configuration TypeScript
  • src/index.tsfichier avec une logique simple pour obtenir une réponse de notre travailleur

Impressionnant. Voyons si cette chose fonctionne !

Passons cdau short-itrépertoire et démarrons Wrangler en mode développement local :

$ cd short-it
$ wrangler dev --local

Cela devrait exécuter notre Worker sur http://localhost:8787/ . Si nous visitons localhost, nous devrions voir un simple "Hello World!" message:

Message Bonjour le monde

Generated Worker affiche un "Hello World!" message.

Yay! Nous l'avons fait fonctionner. Mais comment? Regardons de plus près.

Comment fonctionne Cloudflare Workers ?

Nous avons reçu notre premier message localement du Worker généré, mais comment cela a-t-il fonctionné exactement ?

Passons en revue le src/index.tsfichier généré pour mieux comprendre ce qui s'y passe.

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

Le code ci-dessus comprend une définition de notre environnement (l' Envinterface) et quelques commentaires relatifs à l' ENVinterface.

Étant donné que l'interface n'entre pas dans le cadre de cet article, nous allons ignorer cette partie du code et nous concentrer uniquement sur la logique principale :

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

Ce qui se passe ici, c'est que notre index.tsexporte une fetchfonction. Il s'agit d'une interface similaire aux Web Workers . En fait, c'est de cette interface que provient le nom "Cloudflare Workers". Cloudflare Workers est similaire à Web Workers, sauf qu'il s'exécute sur l'infrastructure Cloudflare plutôt que sur un navigateur.

Dans le code ci-dessus, la fetchfonction renvoie un nouvel Responseobjet avec le "Hello World!" texte. Ainsi, lorsque nous exécutons notre Worker, cette fetchfonction est invoquée. Ensuite, la fetchfonction invoquée renvoie le "Hello World!" réponse, et c'est ce que nous récupérons dans le navigateur (ou via tout outil utilisé pour invoquer le Worker).

OK, nous avons clarifié les bases de Cloudflare Workers. Nous pouvons avancer en toute confiance. Si vous débutez avec TypeScript, ne vous inquiétez pas ; nous n'utiliserons ses fonctionnalités qu'à la légère. Imaginez cela comme une intégration légère dans le monde de TypeScript.

Super, allons de l'avant !

Ajouter une première redirection

Nous allons commencer à travailler sur notre logique avec un démarrage en douceur. Tout d'abord, notre raccourcisseur d'URL redirigera un utilisateur vers un autre site Web. Ce sera la base des changements ultérieurs.

Pour l'instant, nous demanderons à l'utilisateur d'accéder à une page du site Web https://http.cat/ lorsqu'il visitera notre Worker local.

Si vous n'êtes pas familier avec https://http.cat/ , c'est un site amusant qui affiche diverses images de chat pour différents statuts HTTP. Par exemple, si un utilisateur fait une demande à notre Worker sur http://localhost:8787/404 , il sera dirigé vers https://http.cat/404 .

Pour réaliser cette redirection, nous allons modifier le src/index.ts, comme ceci :

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

Maintenant, si nous visitons http://localhost:8787 , nous recevrons un message mis à jour : « Hello World from our awesome Worker ! », comme indiqué ci-dessous :

Bonjour le monde de Awesome Worker

Travailleur affichant un message "Hello world" mis à jour.

Mais si nous essayons d'accéder à http://localhost:8787/404 , nous serons redirigés vers https://http.cat/404 .

Utilisateur redirigé

L'utilisateur est redirigé vers le site Web http.cat/404.

Génial, nous avons lancé notre première redirection. Maintenant, faisons en sorte que notre raccourcisseur d'URL raccourcisse certaines URL.

Raccourcir l'URL

Pour l'instant, nous allons ajouter une petite structure de données pour stocker nos URL raccourcies. Nous pouvons le faire comme ceci :

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Ici, nous avons ajouté quelques URL raccourcies :

Vous pouvez le changer en ce que vous voulez juste pour le voir fonctionner. Maintenant, lorsque je visite http://localhost:8787/blog , je suis redirigé vers une URL plus longue où se trouve mon blog. Voici le résultat :

Redirection vers le blog

La visite de /blog redirige vers la page de blog actuelle.

Mais, si nous demandons un chemin, comme http://localhost:8787/missing , nous obtenons le message d'erreur suivant : « Il n'y a pas d'URL définie pour le chemin : '/missing', désolé :(“.

Message d'erreur manquant

Visiter / manquant affiche un message d'erreur.

Génial, nous sommes maintenant prêts à déplacer nos URL codées en dur et leurs versions raccourcies vers un stockage quelque part. Heureusement, nous utilisons Cloudflare Workers, et il offre un simple stockage clé-valeur appelé KV.

Ajouter du stockage

Avant de créer réellement le KV pour notre projet, nous devons d'abord nous connecter à Cloudflare Workers via Wrangler. Cela est nécessaire car Wrangler devra ultérieurement contacter Cloudflare afin de créer une instance KV pour nous.

Se connecter à Cloudflare

Pour vous connecter à Cloudflare, utilisez la commande suivante :

$ wrangler login

Un navigateur s'ouvrira, vous demandant de vous connecter à Cloudflare. Ne vous inquiétez pas; le plan gratuit couvre tout ce dont nous aurons besoin pour ce didacticiel, et aucun paiement ne vous sera demandé. Allez-y et inscrivez-vous, ou connectez-vous si vous avez déjà un compte.

Ensuite, Cloudflare vous demandera si vous souhaitez accorder une autorisation à Wrangler. Après avoir accepté, vous devriez voir l'écran suivant :

Outil CLI Wrangler

L'outil Wrangler CLI est maintenant correctement connecté.

Il ne devrait pas y avoir de problème pendant le processus d'inscription. Mais, si vous êtes bloqué à un moment donné, vous pouvez suivre le guide de Cloudflare sur la création d'un compte .

Impressionnant! Maintenant que vous êtes inscrit et connecté, vérifions si tout est correctement connecté.

Utilisez la commande suivante :

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

Super, nous sommes prêts à créer un espace de noms KV.

Création d'un espace de noms KV

Un espace de noms KV peut être considéré comme une instance de KV sur le réseau Cloudflare. Nous allons créer deux espaces de noms KV : un pour la production où notre application vivra et fonctionnera et un autre pour l'environnement de prévisualisation. Nous utiliserons l'espace de noms d'aperçu pendant que nous testons et développons notre raccourcisseur d'URL.

Nous allons créer nos espaces de noms KV via Wrangler avec les commandes suivantes :

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

Une fois ces deux commandes exécutées et les deux espaces de noms créés, nous devons dire à Wrangler d'utiliser ces espaces de noms lorsque nous exécutons wrangler dev.

Nous ajouterons des informations sur les espaces de noms KV au wrangler.tomlfichier à la racine de notre projet. Ça devrait ressembler a quelque chose comme ca:

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

Le wrangler.tomlfichier est un fichier de configuration qui donne wranglercertaines informations sur notre projet. Maintenant, nous sommes attachés et prêts à ajouter des données à notre KV.

Ajout de données au KV

Notre prochaine étape consiste à ensemencer les données au KV. N'oubliez pas que nous avons deux espaces de noms, nous devrons donc exécuter deux commandes pour avoir les données aux deux endroits. Ajoutons l' /blogentrée au KV :

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

Impressionnant. Maintenant, nous avons une entrée dans le KV. Ensuite, ajoutons une logique qui lit à partir du KV et redirige l'utilisateur.

Lecture du KV

Nous allons rapidement supprimer nos anciennes URL courtes codées en dur et ajouter un appel au KV, comme ceci :

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Ici, nous ajoutons SHORT_URLScomme KVNamespacetype. Cela nous permettra d'appeler les méthodes KV pour obtenir les données appropriées. Au lieu de l'objet codé en dur avec des URL, cette fois nous utilisons await env.SHORT_URLS.get(pathname).

L'appel à env.SHORT_URLS.get(pathname)essaie d'obtenir la clé du KV. S'il renvoie une promesse, nous devons await. Mais, s'il y a une valeur pour le given pathname, alors l'utilisateur est redirigé vers cette URL.

Maintenant, lorsque nous visitons http://localhost:8787/blog , nous serons redirigés vers l'URL du blog que nous avons mis dans le KV. Il ressemblera à ceci:

Redirige toujours le blog

Visiter /blog nous redirige toujours vers la page de blog actuelle.

Mais, si nous essayons maintenant de visiter l'une des autres URL que nous avons codées en dur, nous recevrons un message indiquant qu'il manque une redirection à ces URL :

URL de redirection manquante

La visite de /twitter entraîne un message indiquant qu'il manque une redirection à l'URL.

Ajoutons rapidement l'URL raccourcie de Twitter au KV à l'aide de ces commandes :

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

Maintenant, lorsque nous actualisons le http://localhost:8787/twitter , nous devrions être redirigés vers le compte Twitter.

Chargement Twitter

Twitter se charge après avoir ajouté l'URL raccourcie au KV.

Génial, nous avons maintenant deux URL courtes : /bloget /twitter. Essayons de déployer notre service et de le voir en production.

Déploiement des nœuds de calcul Cloudflare

L'étape de déploiement de Cloudflare Workers est assez simple. Nous utiliserons wrangler publish, comme ceci :

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

Désormais, les services sont en ligne sur https://short-it.nikolalsvk.workers.dev . Yay!

Si vous suivez ce didacticiel, vos services devraient se trouver quelque part le long de l'URL https://short-it.YOUR_SUBDOMAIN.workers.dev , selon ce que vous avez sélectionné pour YOUR_SUBDOMAIN.

À ce stade, notre script Worker est déployé dans le monde entier sur le réseau Cloudflare Edge. Cela signifie que des amis et des étrangers à travers le monde peuvent être redirigés très rapidement vers notre compte Twitter s'ils visitent https://short-it.nikolalsvk.workers.dev/twitter .

Emballer

Merci d'avoir suivi le parcours de création d'un service de raccourcissement d'URL simple à l'aide de Cloudflare Workers. Dans cet article, nous avons présenté les concepts de Worker dans le contexte Cloudflare. Nous avons également montré comment créer et gérer des données dans le stockage KV de Cloudflare.

Nous avons pu exécuter tout cela en douceur à l'aide de Wrangler, qui offre une excellente expérience de développement. Mais, plus important encore, nous avons réussi à créer, tester et déployer notre petit service qui fonctionne rapidement aux quatre coins du monde.

Atteindre cet objectif dans une technologie ou un service similaire peut nécessiter beaucoup d'argent et d'efforts. Cependant, Cloudflare prend en charge un généreux niveau gratuit de 100 000 requêtes par jour. Ainsi, vous pouvez raccourcir de nombreuses URL et effectuer de nombreuses visites avant de passer à un forfait payant.

Tout le code de cet article est disponible dans le référentiel GitHub (veuillez le mettre en vedette, si vous l'aimez). Le service de raccourcissement est en direct sur https://short-it.nikolalsvk.workers.dev .

Si vous avez aimé le message, pensez à le partager avec vos amis et collègues.

Jusqu'à la prochaine fois, bravo!

Source : https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

  #cloudflare #url 

Créer Un Raccourcisseur D'URL Avec Cloudflare Workers
Saul  Alaniz

Saul Alaniz

1661794260

Crea Un Acortador De URL Con Cloudflare Workers

¿Alguna vez has usado herramientas como Bitly o TinyURL para acortar enlaces largos? ¿O te has preguntado cómo funcionan estos servicios? Tal vez quería crear un acortador de URL pero nunca encontró el tiempo o las herramientas adecuadas para hacerlo. En cualquier caso, si te interesa este tema, este artículo es perfecto para ti.

En esta publicación, demostraremos cómo crear un servicio básico de acortador de URL utilizando Cloudflare Workers . Brindaremos información detallada sobre cómo funcionan los servicios de reducción de URL, presentaremos varias características de Cloudflare Workers y daremos instrucciones paso a paso sobre cómo comenzar con Cloudflare Workers.

¡Empecemos!

¿Qué son los trabajadores de Cloudflare?

Cloudflare Workers es un servicio que le permite implementar código sin servidor en la red de Cloudflare. La red Cloudflare, o Edge, es una red de servidores web repartidos por todo el mundo. Una gran ventaja de Cloudflare Workers es que no tiene que preocuparse por escalar su código. Además, no tiene que preocuparse por las zonas horarias en las que vive su código; su código en Workers se distribuye por todo el mundo segundos después de su implementación.

Además de eso, Cloudflare Workers viene con un almacén de datos clave-valor simple, llamado KV. En este tutorial, usaremos una combinación de Cloudflare Workers y almacenamiento KV para acortar nuestra URL.

Descripción general del proyecto: servicio de acortador de URL

Comenzaremos creando un acortador de URL simple y no dinámico en el que codificará los sitios web a los que desea redirigir. Esto servirá como una introducción para aprender a usar Wrangler (la herramienta CLI oficial de Cloudflare) y demostrará conceptos básicos en el ámbito de los trabajadores.

A continuación, animaremos un poco las cosas y agregaremos soporte para URL dinámicas. Básicamente, interactuaremos con la tienda Cloudflare Workers KV e ingresaremos versiones cortas de la URL y la URL real a la que queremos redirigir. Los datos en la tienda KV serán similares a la siguiente estructura:

'short-url': 'https://my-cool-website.com'
'submit': 'https://my-cool-site.org/blog/ideas/submit'

Finalmente, implementaremos nuestro código en producción y lo veremos funcionar en vivo en todo el mundo.

¿Ya estás emocionado? ¡Genial, vamos a saltar!

Configuración del entorno

Para seguir este artículo, necesitará lo siguiente:

  • Node.js y npm
  • Vaquero
  • curl (o el navegador que elijas) para probar el acortador de URL

Uso la herramienta asdf para administrar mis dependencias locales, pero puede usar el administrador de versiones que prefiera. Al momento de escribir, aquí está mi versión de Node y npm:

$ node --version
v18.5.0
$ npm --version
8.12.1

Wrangler es una herramienta de línea de comandos para construir, y recientemente obtuvo su versión 2.0. A los efectos de esta publicación, Wrangler satisfará todas nuestras necesidades. En el futuro, podríamos usar Miniflare, un hermano más robusto y rico en funciones de Wrangler . Pero, por ahora, instalemos Wrangler globalmente a través de npm:

$ npm install -g wrangler@2.0.21

En el momento de escribir este artículo, la última versión de Wrangler es la 2.0.21, así que nos quedaremos con esa.

Enfriar. Ahora que tenemos todas las dependencias en su lugar, podemos usar la CLI de Wrangler para generar nuestro Cloudflare Worker de inicio.

Generando el proyecto

La herramienta Wrangler CLI resultará muy útil aquí.

Para comenzar, ejecutemos un comando para iniciar y configurar nuestro proyecto correctamente:

$ wrangler init short-it

Este comando le hará un par de preguntas. Por ahora, vamos a responder que sí (escribiendo y ) para todos ellos:

$ wrangler init short-it
  wrangler 2.0.21
--------------------
Using npm as package manager.
 Created short-it/wrangler.toml
Would you like to use git to manage this Worker? (y/n)
 Initialized git repository at short-it
No package.json found. Would you like to create one? (y/n)
 Created short-it/package.json
Would you like to use TypeScript? (y/n)
 Created short-it/tsconfig.json
Would you like to create a Worker at short-it/src/index.ts?
  None
❯ Fetch handler
  Scheduled handler
 Created short-it/src/index.ts

added 62 packages, and audited 63 packages in 1s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities
 Installed @cloudflare/workers-types and typescript into devDependencies

To start developing your Worker, run `cd short-it && npm start`
To publish your Worker to the Internet, run `npm run deploy`

Si respondiste afirmativamente a todas las preguntas de Wrangler, entonces tendrás un nombre de proyecto short-it, con lo siguiente adentro:

  • .gitdirectorio en su proyecto, lo que significa que está listo para enviarlo a su proveedor de Git
  • package.jsonexpediente
  • tsconfig.jsonarchivo con toda la configuración de TypeScript
  • src/index.tsarchivo con una lógica sencilla para obtener una respuesta de nuestro trabajador

Impresionante. ¡Veamos si esto funciona!

Entremos cden el short-itdirectorio e iniciemos Wrangler en modo de desarrollo local:

$ cd short-it
$ wrangler dev --local

Esto debería ejecutar nuestro Worker en http://localhost:8787/ . Si visitamos localhost, deberíamos ver un simple "¡Hola mundo!" mensaje:

Mensaje de hola mundo

El trabajador generado muestra un "¡Hola mundo!" mensaje.

¡Hurra! Lo hicimos funcionar. ¿Pero cómo? Miremos más de cerca.

¿Cómo funciona Cloudflare Workers?

Recibimos nuestro primer mensaje localmente del Worker generado, pero ¿cómo funcionó exactamente?

Repasemos el src/index.tsarchivo generado para obtener una mejor comprensión de lo que está sucediendo allí.

// src/index.ts

/**
 * Welcome to Cloudflare Workers! This is your first worker.
 *
 * - Run `wrangler dev src/index.ts` in your terminal to start a development server
 * - Open a browser tab at http://localhost:8787/ to see your worker in action
 * - Run `wrangler publish src/index.ts --name my-worker` to publish your worker
 *
 * Learn more at https://developers.cloudflare.com/workers/
 */

export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

El código anterior incluye una definición para nuestro entorno (la Envinterfaz) y un par de comentarios relacionados con la ENVinterfaz.

Dado que la interfaz está fuera del alcance de este artículo, ignoraremos esa parte del código y nos centraremos únicamente en la lógica principal:

// src/index.ts

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};

Lo que sucede aquí es que nuestras index.tsexportaciones fetchfuncionan. Esta es una interfaz similar a Web Workers . De hecho, es a partir de esta interfaz que se origina el nombre “Cloudflare Workers”. Cloudflare Workers es similar a Web Workers, excepto que se ejecuta en la infraestructura de Cloudflare en lugar de en un navegador.

En el código anterior, la fetchfunción devuelve un nuevo Responseobjeto con "¡Hola mundo!" texto. Entonces, cuando ejecutamos nuestro Worker, fetchse invoca esta función. Luego, la fetchfunción invocada devuelve el mensaje "¡Hola mundo!" respuesta, y esto es lo que recogemos en el navegador (o a través de cualquier herramienta utilizada para invocar al Trabajador).

Bien, hemos aclarado los conceptos básicos de Cloudflare Workers. Podemos seguir adelante con confianza. Si es nuevo en TypeScript, no se preocupe; usaremos sus características solo a la ligera. Imagínese esto como una incorporación ligera al mundo de TypeScript.

¡Genial, sigamos adelante!

Agregar una primera redirección

Comenzaremos a trabajar en nuestra lógica con un comienzo suave. Primero, nuestro acortador de URL redirigirá a un usuario a un sitio web diferente. Esta será la base para cambios posteriores.

Por ahora, haremos que el usuario vaya a una página en el sitio web https://http.cat/ cuando visite nuestro Worker local.

Si no está familiarizado con https://http.cat/ , es un sitio divertido que muestra varias imágenes de gatos para diferentes estados de HTTP. Por ejemplo, si un usuario realiza una solicitud a nuestro Worker a http://localhost:8787/404 , será dirigido a https://http.cat/404 .

Para lograr esta redirección, editaremos el src/index.ts, así:

// src/index.ts
// ...

const basePath = "https://http.cat";

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = basePath + pathname;

    if (pathname === "/") {
      return new Response("Hello World from our awesome Worker!");
    }

    return Response.redirect(redirectURL, 301);
  },
};

Ahora, si visitamos http://localhost:8787 , obtendremos un mensaje actualizado: "¡Hola, mundo, de parte de nuestro increíble trabajador!", como se muestra a continuación:

Hola mundo de Awesome Worker

Trabajador que muestra un mensaje actualizado de "Hola mundo".

Pero, si intentamos ir a http://localhost:8787/404 , seremos redirigidos a https://http.cat/404 .

Usuario redirigido

Se redirige al usuario a la web http.cat/404.

Genial, tenemos nuestro primer redireccionamiento en marcha. Ahora, hagamos que nuestro acortador de URL realmente acorte algunas URL.

Acortar la URL

Por ahora, agregaremos una pequeña estructura de datos para almacenar nuestras URL abreviadas. Podemos hacerlo así:

const shortURLs = {
  "/blog": "https://pragmaticpineapple.com/",
  "/twitter": "https://twitter.com/nikolalsvk",
  "/github": "https://github.com/nikolalsvk",
} as Record<any, string>;

export default {
  async fetch(
    request: Request,
    _env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = shortURLs[pathname];

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Aquí, agregamos un par de URL abreviadas:

Puedes cambiarlo a lo que quieras solo para verlo funcionar. Ahora, cuando visito http://localhost:8787/blog , se me redirige a una URL más larga donde se encuentra mi blog. Aquí está el resultado:

Redirecciones al blog

Visitar /blog redirige a la página real del blog.

Pero, si solicitamos alguna ruta, como http://localhost:8787/missing , obtenemos el siguiente mensaje de error: “No hay una URL definida para la ruta: '/missing', lo siento :(“.

Falta el mensaje de error

Visiting/missing muestra un mensaje de error.

Impresionante, ahora estamos listos para mover nuestras URL codificadas y sus versiones abreviadas a un lugar de almacenamiento. Afortunadamente, usamos Cloudflare Workers y ofrece un almacenamiento de clave-valor simple llamado KV.

Agregar almacenamiento

Antes de crear el KV para nuestro proyecto, primero debemos iniciar sesión en Cloudflare Workers a través de Wrangler. Esto es necesario porque Wrangler luego deberá comunicarse con Cloudflare para crear una instancia de KV para nosotros.

Iniciar sesión en Cloudflare

Para iniciar sesión en Cloudflare, use el siguiente comando:

$ wrangler login

Se abrirá un navegador que le pedirá que inicie sesión en Cloudflare. No te preocupes; el plan gratuito cubre todo lo que necesitaremos para este tutorial y no se le pedirá que pague. Continúe y regístrese, o inicie sesión si ya tiene una cuenta.

A continuación, Cloudflare le preguntará si desea otorgar autorización a Wrangler. Después de aceptar, debería ver la siguiente pantalla:

Herramienta CLI de Wrangler

La herramienta Wrangler CLI ahora está correctamente conectada.

No debería haber contratiempos durante el proceso de registro. Pero, si se quedó atascado en algún momento, puede seguir la guía de Cloudflare para crear una cuenta .

¡Impresionante! Ahora que está registrado e iniciado sesión, verifiquemos si todo está conectado correctamente.

Usa el siguiente comando:

$ wrangler whoami
  wrangler 2.0.21
--------------------
Getting User settings...
 You are logged in with an OAuth Token, associated with the email 'nikolaseap@gmail.com'!
┌──────────────────────┬──────────────────────────────────┐
│ Account Name │ Account ID │
├──────────────────────┼──────────────────────────────────┤
│ Nikola Đuza Personal │ 98a16dfefca0e2ee27e1e79ba590d973 │
└──────────────────────┴──────────────────────────────────┘

Genial, estamos listos para crear un espacio de nombres KV.

Creación de un espacio de nombres KV

Se puede pensar en un espacio de nombres KV como una instancia de KV en la red de Cloudflare. Crearemos dos espacios de nombres KV: uno para producción donde vivirá y funcionará nuestra aplicación y otro para el entorno de vista previa. Usaremos el espacio de nombres de vista previa mientras probamos y desarrollamos nuestro acortador de URL.

Crearemos nuestros espacios de nombres KV a través de Wrangler con los siguientes comandos:

$ wrangler kv:namespace create SHORT_URLS
 Creating namespace with title "short-it-SHORT_URLS"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e" }

$ wrangler kv:namespace create SHORT_URLS --preview
  wrangler 2.0.21
--------------------
 Creating namespace with title "short-it-SHORT_URLS_preview"
 Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "SHORT_URLS", preview_id = "99a72876e5f84cf58de722b1c2080604" }

Después de que se ejecuten estos dos comandos y se creen ambos espacios de nombres, debemos decirle a Wrangler que use estos espacios de nombres cuando ejecutemos wrangler dev.

Agregaremos información sobre los espacios de nombres KV al wrangler.tomlarchivo en la raíz de nuestro proyecto. Debería verse algo como esto:

name = "short-it"
main = "src/index.ts"
compatibility_date = "2022-07-15"

kv_namespaces = [
  { binding = "SHORT_URLS", id = "029d374ebd984e19b0bb98e37ab1a95e", preview_id = "99a72876e5f84cf58de722b1c2080604" }
]

El wrangler.tomlarchivo es un archivo de configuración que dice wranglercierta información sobre nuestro proyecto. Ahora, estamos atados y listos para agregar algunos datos a nuestro KV.

Adición de datos al KV

Nuestro siguiente paso es sembrar los datos en el KV. Recuerde, tenemos dos espacios de nombres, por lo que tendremos que ejecutar dos comandos para tener los datos en ambos lugares. Agreguemos la /blogentrada al KV:

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview false
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/blog" "https://pragmaticpineapple.com/" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://pragmaticpineapple.com/" to key "/blog" on namespace 99a72876e5f84cf58de722b1c2080604.

Impresionante. Ahora tenemos una entrada en el KV. A continuación, agreguemos lógica que lea desde el KV y redireccione al usuario.

Lectura del KV

Eliminaremos rápidamente nuestras antiguas URL cortas codificadas y agregaremos una llamada al KV, así:

// src/index.ts
export interface Env {
  SHORT_URLS: KVNamespace;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    _ctx: ExecutionContext
  ): Promise<Response> {
    const url = new URL(request.url);

    const { pathname } = url;

    const redirectURL = await env.SHORT_URLS.get(pathname);

    if (!redirectURL) {
      return new Response(
        `There is no defined URL for the path: '${pathname}', sorry :(`
      );
    }

    return Response.redirect(redirectURL, 301);
  },
};

Aquí, agregamos SHORT_URLScomo un KVNamespacetipo. Esto nos permitirá llamar a los métodos KV para obtener los datos adecuados. En lugar del objeto codificado con URL, esta vez usamos await env.SHORT_URLS.get(pathname).

La llamada a env.SHORT_URLS.get(pathname)intenta obtener la clave del KV. Si devuelve una promesa, debemos await. Pero, si hay un valor para el dado pathname, entonces el usuario es redirigido a esa URL.

Ahora, cuando visitemos http://localhost:8787/blog , seremos redirigidos a la URL real del blog que pusimos en el KV. Se verá así:

Aún redirige el blog

Visitar /blog aún nos redirige a la página real del blog.

Pero, si ahora intentamos visitar cualquiera de las otras URL que codificamos, recibiremos un mensaje que dice que a esas URL les falta una redirección:

Redirección de URL faltante

Visitar /twitter da como resultado un mensaje que indica que a la URL le falta una redirección.

Agreguemos rápidamente la URL abreviada de Twitter al KV usando estos comandos:

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview false
 wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 029d374ebd984e19b0bb98e37ab1a95e.

$ wrangler kv:key put --binding SHORT_URLS "/twitter" "https://twitter.com/nikolalsvk" --preview
  wrangler 2.0.21
--------------------
Writing the value "https://twitter.com/nikolalsvk" to key "/twitter" on namespace 99a72876e5f84cf58de722b1c2080604.

Ahora, cuando actualicemos http://localhost:8787/twitter , deberíamos ser redirigidos a la cuenta de Twitter.

Cargando Twitter

Twitter se carga después de que agregamos la URL abreviada al KV.

Impresionante, ahora tenemos dos URL cortas: /blogy /twitter. Intentemos implementar nuestro servicio y verlo en producción.

Implementación de trabajadores de Cloudflare

El paso de implementación de Cloudflare Workers es bastante sencillo. Utilizaremos wrangler publish, así:

$ wrangler publish
  wrangler 2.0.21
--------------------
Retrieving cached values for userId from node_modules/.cache/wrangler
Your worker has access to the following bindings:
- KV Namespaces:
  - SHORT_URLS: 029d374ebd984e19b0bb98e37ab1a95e
Total Upload: 0.45 KiB / gzip: 0.29 KiB
Worker ID: short-it
Worker ETag: f8395cab29edf297137631b803b14c32daaae982758c23e3019b700e2468c277
Uploaded short-it (2.14 sec)
Published short-it (6.33 sec)
  short-it.nikolalsvk.workers.dev

Ahora, los servicios están activos en https://short-it.nikolalsvk.workers.dev . ¡Hurra!

Si está siguiendo este tutorial, sus servicios deberían vivir en algún lugar a lo largo de la URL https://short-it.YOUR_SUBDOMAIN.workers.dev , según lo que haya seleccionado YOUR_SUBDOMAIN.

En este punto, nuestro script Worker se implementa en todo el mundo en la red Cloudflare Edge. Esto significa que amigos y extraños de todo el mundo pueden ser redirigidos increíblemente rápido a nuestra cuenta de Twitter si visitan https://short-it.nikolalsvk.workers.dev/twitter .

Terminando

Gracias por seguir el viaje de crear un servicio simple de acortador de URL con Cloudflare Workers. En este artículo, presentamos los conceptos de Worker dentro del contexto de Cloudflare. También demostramos cómo crear y administrar datos en el almacenamiento KV de Cloudflare.

Pudimos ejecutar todo esto sin problemas con Wrangler, que brinda una excelente experiencia de desarrollador. Pero, lo más importante, logramos crear, probar e implementar nuestro pequeño servicio que funciona rápido en todos los rincones del mundo.

Lograr esto en una tecnología o servicio similar puede requerir mucho dinero y esfuerzo. Sin embargo, Cloudflare admite un generoso nivel gratuito de 100 000 solicitudes por día. Por lo tanto, puede acortar muchas URL y tener muchas visitas antes de infringir un plan pago.

Todo el código de este artículo está disponible en el repositorio de GitHub (marcalo con una estrella, si te gusta). El servicio de acortador está disponible en https://short-it.nikolalsvk.workers.dev .

Si te gustó la publicación, considera compartirla con tus amigos y compañeros de trabajo.

Hasta la próxima, ¡salud!

Fuente: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

   #cloudflare #url 

Crea Un Acortador De URL Con Cloudflare Workers

Create A URL Shortener with Cloudflare Workers

Have you ever used tools like Bitly or TinyURL to shorten long links? Or, have you wondered how these services work? Maybe you wanted to build a URL shortener but never found the time or the proper tools to do so. In any case, if you are interested in this topic, this article is perfect for you.

In this post, we’ll demonstrate how to build a basic URL shortener service using Cloudflare Workers. We’ll provide detailed information about how URL shortener services work, introduce several features of Cloudflare Workers, and give step-by-step instructions on how to get started with Cloudflare Workers.

Let’s get started!

Source: https://blog.logrocket.com/creating-url-shortener-cloudflare-workers/

#cloudflare #url 

Create A URL Shortener with Cloudflare Workers

Orrison/Cumulus: Import Laravel Vapor DNS to Cloudflare

In this Laravel tutorial, we'll learn about Orrison/cumulus, CLI tool to import/update DNS records from Laravel Vapor to Cloudflare.

Cumulus is a package to be used with the Laravel Vapor CLI. It provides a set of commands to import DNS records for your Vapor custom domain into Cloudflare.

No more having to copy each manually which takes too long and is prone to errors. Cumulus will create any missing DNS records for you as well as update any incorrect or changed records.

Keep in mind that in order for the import to work the domain must be a custom domain in your Laravel Vapor team as well as a zone in your Cloudflare account already. This package will take care of importing the DNS records for you, not adding the domains.

You will also need to have Laravel Vapor CLI installed and authenticated on your machine.

Installation

composer global require orrison/cumulus --with-all-dependencies

Usage

Cloudflare Authentication

In order to use Cumulus, you will need a valid Cloudflare API Access Token. You can get one by following the instructions in their Documentation.

The "Edit DNS Zone" template is perfect for this. You will just need set the "Zone Resources" options to either All Zones or the correct option for your use case.

Once you have your token you can run the following command to input your token. It is then stored for use in future commands.

cumulus cloudflare:login

If, for what ever reason, you would like to clear this token from local storage then you can run the following command.

cumulus cloudflare:logout

Importing DNS Records

Cumulus directly executes some commands via Laravel Vapor. So you will need to be logged in with the Vapor CLI that is either globally or per project installed. Learn about that in the Vapor Documentation.

Now that you have a valid Cloudflare API token and are logged in to a Vapor team that has access to the domain you are attempting to import, you can run the following command to import the DNS records for your domain.

cumulus records:import [THE_DOMAIN_NAME]

This will import any missing DNS records that Vapor specifies into the Cloudflare DNS zone. As well as update any incorrect or changed records.

If you would like to see what changes would be made before actually importing, you can add --dry-run to the end of the command.

The import command will attempt to "proxy" each added/updated record if it can be proxied. If you would not like the added records proxied, you can add --no-proxy to the end of the command.

Info about DNS record generation and Subdomains

Cumulus will work regardless of the environment you have assigned the custom domain to. It simply imports the correct DNS records for the domain provided. Laravel Vapor generates and stores the DNS records when a domain is assigned to a project environment and successfully deployed.

When you use a subdomain for a project environment Laravel Vapor will automatically generate the correct DNS records and store them with the root domain. So in order to import the correct DNS records for the subdomain you will need to import the root domain.

For example if you have a subdomain sub.example.com, you would run the following command to import the DNS records:

cumulus records:import example.com

Download Details: 
Author: Orrison
Source Code: https://github.com/Orrison/cumulus 

#php #laravel #cloud #cloudflare

Orrison/Cumulus: Import Laravel Vapor DNS to Cloudflare

Use Fastify Idioms for Writing Cloudflare Workers and Bun Servers

fastify-edge

An experimental lightweight worker version of Fastify.

Currently Cloudflare Workers and Bun are supported.

Install

npm i fastify-edge --save

Usage: Bun

import FastifyEdge from 'fastify-edge/bun'

const app = FastifyEdge();

app.get('/', (_, reply) => {
  reply.send('Hello World')
})

export default app;

See examples/bun.

Usage: Cloudflare Workers

import FastifyEdge from 'fastify-edge'

const app = FastifyEdge()

app.get('/', (_, reply) => {
  reply.send('Hello World')
})

See examples/cloudflare with miniflare.

Advanced Example

app.addHook('onSend', (req, reply, payload) => {
  if (req.url === '/') {
    return `${payload} World!`
  }
})

app.get('/redirect', (_, reply) => {
  reply.redirect('/')
})

app.get('/route-hook', {
  onRequest (_, reply) {
    reply.send('<b>Content from onRequest hook</b>')
  },
  handler (_, reply) {
    reply.type('text/html')
  }
})

Supported APIs

Server

  • app.addHook(hook, function)
  • app.route(settings)
  • app.get(path, handlerOrSettings)
  • app.post(path, handlerOrSettings)
  • app.put(path, handlerOrSettings)
  • app.delete(path, handlerOrSettings)
  • app.options(path, handlerOrSettings)

Request

req.urlReturns the request URL path (URL.pathname + URL.search).
req.originReturns the request URL origin (e.g., http://localhost:3000).
req.hostnameReturns the request URL hostname (e.g., localhost).
req.protocolReturns the request URL protocol (e.g., http or https).
req.queryMaps to the fetch request URL's searchParams object through a Proxy.
req.bodyThe consumed body following the parsing pattern from this example.
req.paramsThe parsed route params from the internal Radix-tree router, radix3.
req.headersMaps to the fetch request headers object through a Proxy.
req.rawThe raw fetch request object.

Reply

reply.code(code)Sets the fetch response status property.
reply.header(key, value)Adds an individual header to the fetch response headers object.
reply.headers(object)Adds multiple headers to the fetch response headers object.
reply.getHeader(key)Retrieves an individual header from fetch response headers object.
reply.getHeaders()Retrieves all headers from fetch response headers object.
reply.removeHeader(key)Remove an individual header from fetch response headers object.
reply.hasHeader(header)Asserts presence of an individual header in the fetch response headers object.
reply.redirect(code, dest)
reply.redirect(dest)
Sets the status and redirect location for the fetch response object.
Defaults to the HTTP 302 Found response code.
reply.type(contentType)Sets the content-type header for the fetch response object.
reply.send(data)

Sets the body for the fetch response object.
 

Can be a string, an object, a buffer or a stream.

Objects are automatically serialized as JSON.

Supported hooks

The original Fastify onRequest, onSend and onResponse are supported.

Diverging from Fastify, they're all treated as async functions.

They can be set at the global and route levels.

Limitations

  • No support for preHandler, preParsing and preValdation hooks.
  • No support for Fastify's plugin system (yet).
  • No support for Fastify's logging and validation facilities.
  • Still heavily experimental, more equivalent APIs coming soon.

Download Details: 

Author: Galvez
Source Code: https://github.com/galvez/fastify-edge 

#javascript #edge #cloudflare 

Use Fastify Idioms for Writing Cloudflare Workers and Bun Servers

Nbit: A Zero-dependency, Strongly-typed Web Framework for Bun, Node

nbit

A simple, declarative, type-safe way to build web services and REST APIs for Bun, Node and Cloudflare Workers.

Examples

See some quick examples below and be sure to check out the live demo.

Bun

import { createApplication } from '@nbit/bun';

const { defineRoutes, attachRoutes } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

Bun.serve({
  port: 3000,
  fetch: attachRoutes(routes),
});

Node

import http from 'http';
import { createApplication } from '@nbit/node';

const { defineRoutes, attachRoutes } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

const server = http.createServer(attachRoutes(routes));

server.listen(3000, () => {
  console.log(`Server running at http://localhost:3000/`);
});

Cloudflare Workers

import { createApplication } from '@nbit/cfw';

const { defineRoutes, attachRoutes } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

export default {
  fetch: attachRoutes(routes),
};

Node with Express

import express from 'express';
import { createApplication } from '@nbit/express';

const { defineRoutes, attachRoutes } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

const app = express();
const middleware = attachRoutes(routes);
app.use(middleware);

app.listen(3000, () => {
  console.log(`Server running at http://localhost:3000/`);
});

Node with Apollo GraphQL

// Adapted from: https://www.apollographql.com/docs/apollo-server/api/apollo-server/#framework-specific-middleware-function
import http from 'http';
import express from 'express';
import { ApolloServer } from 'apollo-server-express';
import { createApplication } from '@nbit/express';

const { defineRoutes, attachRoutes } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

async function startApolloServer() {
  const app = express();
  const httpServer = http.createServer(app);
  const apolloServer = new ApolloServer({
    /* ... */
  });

  await apolloServer.start();

  // Additional middleware can be mounted at this point to run before Apollo.
  app.use(attachRoutes(routes));

  // Mount Apollo middleware here.
  apolloServer.applyMiddleware({ app });

  httpServer.listen(3000, () => {
    console.log(`Server running at http://localhost:3000/`);
  });
}

Objectives

  • Simplicity - providing a clean, minimal declarative API for routing and request handling based on web standards
  • Strong type guarantees - extensively leverages modern TypeScript features not just for type safety but for an all-around great developer experience
  • Testability - route handlers should be as easy to test as they are to write
  • First-class support for Bun, Node and Cloudflare workers
  • Nano-sized with no dependencies

Core Features

  • Declarative request routing
  • Effortless body parsing
  • A type-safe approach to middleware (inspired by Apollo Server's context)
  • File Serving (with content-type selection, caching headers, ETag, etc)
  • Sensible, convenient defaults and conventions
  • Extensive use of TypeScript (e.g. type inference for route params)
  • Based on web standards you're already familiar with

Work-in-progress / Coming Soon

  • Schemas and validation for JSON request body
  • Additional body parsers such as multipart/form-data
  • Tooling to statically generate an OpenAPI schema from a set of route handlers
  • High performance trie-based (e.g. radix3) request router
  • Better documentation
  • Performance benchmarks and comparisons with other libraries
  • Deno support

Motivation

I've often wanted cleaner, more declarative, type-safe tooling for building web APIs. Something that's light-weight enough to be used with Cloudflare workers and powerful enough to replace Express. Now with new performance-focused runtimes like Bun this is ever more relevant.

Aren't there already enough choices for writing web APIs? How is this different from what's out there? Read more about the motivation behind this package (aka what's wrong with Express).

Installation

bun add @nbit/bun

# -- or --

npm install @nbit/node

# -- or --

npm install @nbit/cfw # for Cloudflare workers

More Examples

Route params

const routes = defineRoutes((app) => [
  app.post('/users/:id', (request) => {
    const userId = request.params.id; // <-- fully typed
    return { yourUserId: userId };
  }),
]);

Sending a file

const routes = defineRoutes((app) => [
  app.post('/', (request) => {
    return Response.file('assets/index.html');
  }),
]);

Request Headers

const routes = defineRoutes((app) => [
  app.post('/foo', async (request) => {
    const authToken = request.headers.get('Authorization') ?? '';
    // ... check auth ...
    return { success: true };
  }),
]);

Request body

const routes = defineRoutes((app) => [
  app.post('/auth', async (request) => {
    const { username, password } = await request.json();
    const isValid = await checkLogin(username, password);
    if (!isValid) {
      // Send a JSON response _with_ a custom status code
      return Response.json({ success: false }, { status: 403 });
    }
    // ...
  }),
]);

Throwing

const routes = defineRoutes((app) => [
  app.post('/auth', async (request) => {
    const { username, password } = await request.json();
    // The following check with _throw_ if not valid; see below
    await checkLogin(username, password);
    return { success: true };
  }),
]);

async function checkLogin(username, password) {
  if (username !== 'foo' || password !== '123') {
    throw new HttpError({ status: 403, message: 'Unauthorized' });
  }
}

Some of those examples might seem a bit boilerplatey for a hello world, but there's some important ergonomic design decisions with the defineRoutes() and attachRoutes() paradigm, as well as the fact that each route handler takes exactly one input (request) and returns exactly one result.

// TODO: Add more examples

Everything from middleware (which we call context) to body parsers to request params is fully typed, out of the box, using TypeScript's powerful type inference so you don't need to write type annotations everywhere.

const routes = defineRoutes((app) => [
  app.get('/users/:username', async (request) => {
    const username = request.params.username.toLowerCase(); // <-- ✅ TypeScript knows this is a string
    const foo = request.params.foo; // <-- 🚫 Type Error: foo does not exist on params
    const body = await request.json(); // <-- 🚫 Type Error: GET request doesn't have a body
    if (!isValidUsername(username)) {
      throw new HttpError({ status: 403 }); // <-- Throw from any level deep
    }
    const user = await db.getUserByUsername(username);
    if (!user) {
      return; // <-- Will proceed to the next handler, or send 404 if there are no more handlers
    }
    return user; // <<-- Automatically converted to JSON
  }),
]);

Note that in the above code we're defining an array of route handlers.

const routes = defineRoutes((app) => [ ... ]);

This reflects an important principle of this framework; we don't mutate a shared app object. We declaratively define a set of route handlers using defineRoutes(). The result is simply an array (which can be passed into attachRoutes() or used for tests).

From within a route handler you can return new Response(string) or return new Response(stream) or you can use a helper like return Response.json({...}) or return just a plain object and it will be sent as JSON.

Response follows the web standard for the most part, but there's an extra Response.file(path) to serve a static file. We might add additional non-standard helpers in future as well.

You can import { Response } from '@nbit/node' or from @nbit/bun, etc.

In Bun and Cloudflare workers (which have a built-in Response), the Response object is a sub-class of the built-in Response.

Similarly the request object that is passed in to each route handler follows the web standard for the most part, but it has an additional .params for route params as well as whatever custom context methods you define (see below).

Splitting routes into multiple files

This approach to declarative route handlers scales nicely if we want to split our routes into different files as our application grows:

// routes/foo.ts
export default defineRoutes((app) => [
  app.get('/', async (request) => { ... }),
  app.post('/foo', async (request) => { ... }),
]);

// routes/bar.ts (note the optional destructuring below)
export default defineRoutes(({ get, post }) => [
  get('/', async (request) => { ... }),
  post('/bar', async (request) => { ... }),
]);

// routes/index.ts
export { default as foo } from './foo';
export { default as bar } from './bar';

// server.ts
import * as handlers from './routes';

Bun.serve({
  port: 3000,
  fetch: attachRoutes(...Object.values(handlers)),
});

See full examples for Bun, Node or Express.

Context (aka middleware)

The design choice for extensibility is influenced by the way Apollo Server does things; this allows us to maximize type safety while still providing an ergonomic experience for developers.

Essentially you create a context object which will be passed to each route handler. This context object can have helpers for authentication, body parsing, etc.

Example:

import { createApplication, HttpError } from '@nbit/bun';

const { defineRoutes, attachRoutes } = createApplication({
  getContext: (request) => ({
    // We can provide async functions here that can be easily called within our route handlers
    authenticate: async () => { ... },
    someOtherHelper: () => {
      // We can throw a special HttpError from here
      if (!request.headers.get('foo')) {
        throw new HttpError({ status: 403 });
      }
    },
  }),
});

const routes = defineRoutes((app) => [
  app.get('/users/me', (request) => {
    const user = await request.authenticate(); // <-- This is fully typed; TS knows this method is available on `request` because we defined it above
    const foo = request.foo(); // <-- 🚫 Type Error: foo() does not exist on request or context
    return user.someDetails; // <-- We can be sure
  }),
]);

export { defineRoutes, attachRoutes };

Note in the above that whatever we return as part of context gets merged onto the request object. This has been convenient, but I'm not sure if it's too magical, so there's a possibility this might change to request.context in a future version.

Importantly, the context methods, e.g. .authenticate() can throw a special HttpError (or any error really, but HttpError will ensure the right response status, vs a generic error will result in a 500). This ensures we can do something like const { userId } = await request.authenticate() from within a route handler since it will always result in a valid user.

Testing route handlers

Testing a route handler is as easy as constructing a mock request, receiving a response, and asserting the response is as expected. See a live example here.

import { createApplication, Request } from '@nbit/node';

const { defineRoutes, createRequestHandler } = createApplication();

const routes = defineRoutes((app) => [
  app.get('/', (request) => {
    return { hello: 'world' };
  }),
]);

const requestHandler = createRequestHandler(routes);

it('should handle a request', async () => {
  const request = new Request('/');
  const response = await requestHandler(request);
  expect(response.status).toBe(200);
  const data = await response.json();
  expect(data).toEqual({ hello: 'world' });
});

Benchmarks

// TODO

Project Status

It is still early days, and some parts of the API will likely change (I will follow semver and a breaking change will be a major version bump). This is adapted from an internal set of tooling that has been used in production, but that doesn't mean this is stable. Please do try it out and leave feedback, criticisms and thoughts on the design choices and implementation. I know there's still a number of missing pieces, missing examples and missing documentation (file uploads, cors helpers, etc) but I wanted to get this out to gather early feedback. I hope you find this useful, even if merely as something fun to poke around with!

Download Details: 

Author: sstur
Source Code: https://github.com/sstur/nbit 

#typescript #node #cloudflare 

Nbit: A Zero-dependency, Strongly-typed Web Framework for Bun, Node

Hono: Ultrafast web framework for Cloudflare Workers, Deno, and Bun

Hono - [炎] means flame🔥 in Japanese - is a small, simple, and ultrafast web framework for Cloudflare Workers, Deno, Bun, and others.

import { Hono } from 'hono'
const app = new Hono()

app.get('/', (c) => c.text('Hono!!'))

export default app

Features

  • Ultrafast - the router does not use linear loops.
  • Zero-dependencies - using only Service Worker and Web Standard API.
  • Middleware - built-in middleware, custom middleware, and third-party middleware.
  • TypeScript - first-class TypeScript support.
  • Multi-platform - works on Cloudflare Workers, Fastly Compute@Edge, Deno, or Bun.

Benchmarks

Hono is fastest, compared to other routers for Cloudflare Workers.

hono - trie-router(default) x 389,510 ops/sec ±3.16% (85 runs sampled)
hono - regexp-router x 452,290 ops/sec ±2.64% (84 runs sampled)
itty-router x 206,013 ops/sec ±3.39% (90 runs sampled)
sunder x 323,131 ops/sec ±0.75% (97 runs sampled)
worktop x 191,218 ops/sec ±2.70% (91 runs sampled)
Fastest is hono - regexp-router
✨  Done in 43.56s.

Documentation

The documentation is available on honojs.dev.

Migration

Migration guide is available on docs/MIGRATION.md.

Contributing

Contributions Welcome! You can contribute in the following ways.

  • Create an Issue - Propose a new feature. Report a bug.
  • Pull Request - Fix a bug and typo. Refactor the code.
  • Create third-party middleware - Instruct below.
  • Share - Share your thoughts on the Blog, Twitter, and others.
  • Make your application - Please try to use Hono.

For more details, see docs/CONTRIBUTING.md.

Contributors

Thanks to all contributors! Especially, @metrue and @usualoma!


Documentation 👉 honojs.dev
v2.x has been released! Migration guide


Author: Honojs
Source Code: https://github.com/honojs/hono 
License: MIT license

#javascript #typescript #npm #router #cloudflare 

Hono: Ultrafast web framework for Cloudflare Workers, Deno, and Bun

Cloudflare Deploy Plugin for CakePHP

Cloudflare Deploy Plugin for CakePHP 

This plugin provides userful commands when deploying with Cloudflare.

This branch is for use with CakePHP 3.8+. For details see version map

Installation and Usage

CakePHP Cloudflare Deploy Plugin Documentation

Version Map

See Version Map

Installation

You can install this plugin into your CakePHP application using composer.

$ composer require challgren/cakephp-cloudflare-deploy

Load the plugin in your src/Application.php's boostrap() using:

$ bin/cake plugin load CloudflareDeploy

Configuration

Set your Cloudflare API User, API key and zoneId in Cloudflare settings in app.php.

You can get your zone ID by viewing the Overview of the domain controlled by Cloudflare.

return [
	'Cloudflare' => [
		'apiUser' => 'API Username',
		'apiKey' => 'API Key',
		'zoneId' => 'Zone ID'
	]
];

Usage

Run bin/cake clear_cloudflare this will enable Development on Cloudflare and purge the entire cache.

Contributing

You can fork the project, add features, and send pull requests or open issues.

Reporting Issues

If you are facing a problem with this plugin or found any bug, please open an issue on GitHub.

Author: challgren 
Source Code: https://github.com/challgren/cakephp-cloudflare-deploy 
License: MIT license

#php #cakephp #cloudflare #deploy 

Cloudflare Deploy Plugin for CakePHP
Callum Slater

Callum Slater

1654312268

cf-workers-telegram-bot: Serverless Telegram Bot on CloudFlare Workers

cf-workers-telegram-bot

serverless telegram bot on cf workers

Navigate to your new GitHub repository > Settings > Secrets and add the following secrets:

Push to master to trigger a deploy

To fork this repo and use wrangler:

  • Click fork
  • wrangler secret put SECRET_TELEGRAM_API_TOKEN and set it to your telegram bot token
  • wrangler publish
  • Done!

Getting started with cf-workers-telegram-bot

Once you've deployed the bot you can get your Webhook command URL by doing any of the following.

  • sha256sum(YourTelegramSecretKey) is the path to your webhook commands and should be put at the end of your worker URL to access commands such as setting your webhook
  • Use sha256sum <<< "your secret key" to get the path
  • Open the Cloudflare Worker Logs under Workers > cf-workers-telegram-bot > Logs > Begin log stream and make a GET request (open it in your browser) to your Worker URL and look at the logs to see your Access URL
  • Run wrangler tail --format pretty from inside your git repository and make a GET request to your Worker URL

Example URL for setting the Webhook and dropping pending updates:

https://cf-workers-telegram-bot.codebam.workers.dev/a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447?command=setWebhook

- Name: CF_API_TOKEN (should be added automatically)
- Name: CF_ACCOUNT_ID (should be added automatically)

- Name: SECRET_TELEGRAM_API_TOKEN
- Value: your-telegram-bot-token

The original worker.js is the content of Nikhil John's https://github.com/nikhiljohn10/telegram-bot-worker which is licensed with MIT. My modifications are licensed under the Apache license.

Download Details: 
Author: codebam
Source Code: https://github.com/codebam/cf-workers-telegram-bot 

#telegram #cloudflare #bot #serverless 

cf-workers-telegram-bot: Serverless Telegram Bot on CloudFlare Workers

Cómo Configurar La Canalización De CI/CD Para Cloudflare Worker

Hoy, la mayoría de mis proyectos en GitHub se mantienen actualizados con Renovate . Con la fusión automática habilitada, quiero tener la confianza suficiente de que la actualización de dependencias automatizadas no causará ninguna regresión.

Probar Cloudflare Worker está un poco fuera de control. No me malinterpreten, me encanta Cloudflare Worker. Sin embargo, la solución existente parece un poco poco intuitiva. Además de eso, dollarhaveclub/cloudworker ya no se mantiene activamente, lo cual es un fastidio.

TL;DR: Cómo configurar una canalización de CI/CD para un proyecto de Cloudflare Worker usando GitHub Action y Grafana k6 .

Visión general

Anteriormente, construí un clon de acortador de URL con Cloudflare Worker. Usando este proyecto existente ( enlace de GitHub ), buscaremos configurar una canalización de CI/CD para él junto con pruebas de integración simples.

Nuestra canalización de GitHub Action CI/CD es bastante sencilla. Las etapas (trabajos) son las siguientes:

Ejemplo de flujo de trabajo de CI en GitHub

Ejemplo de flujo de trabajo de CI en GitHub ( enlace )

  1. Comprobación de pelusa o prueba unitaria
  2. Implementar en el entorno de ensayo
  3. Ejecute las pruebas de integración en nuestro entorno Staging
  4. Ejecute la liberación semántica e implemente en el entorno de producción

Configuración de Wrangler

Para empezar, tendremos que modificar nuestro archivo existentewrangler.toml . Recuerde, necesitamos implementar un entorno de prueba para ejecutar nuestra prueba de integración en él:

[env.staging]name = "atomic-url-staging"workers_dev = truekv_namespaces = [  { binding = "URL_DB", id = "ca7936b380a840908c035a88d1e76584" },]
  • name— Asegúrese de que el namedebe ser único y alfanumérico ( -están permitidos) para cada entorno. Vamos a nombrar nuestro entorno de Staging atomic-url-staging.
  • worker_dev— Nuestras pruebas de integración se ejecutan en el <NAME>.<SUBDOMAIN>.workers.devpunto final. Por lo tanto, debemos implementar nuestro Cloudflare Worker configurando workers_dev = true( referencia ).
  • kv_namespaces— Atomic URL utiliza KV como su base de datos para almacenar URL abreviadas. Aquí, elegí usar un espacio de nombres de vista previa KV como base de datos de prueba. ¿Por qué? Simplemente porque es el mismo espacio de nombres KV de desarrollo que uso durante el desarrollo local (cuando ejecuto wrangler dev). Por supuesto, podría usar un espacio de nombres KV normal. Solo asegúrese de no estar usando Production KV id. Lea cómo crear un espacio de nombres KV .

A continuación, también necesitaremos crear un entorno de producción para implementar con nuestro espacio de nombres KV de producción:

[env.production]name = "atomic-url"route = "s.jerrynsh.com/*"workers_dev = falsekv_namespaces = [  { binding = "URL_DB", id = "7da8f192d2c1443a8b2ca76b22a8069f" },]

La sección del entorno de producción sería similar a la anterior, excepto que estaremos configurando worker_dev = falsey routepara la producción.

Despliegue

Para implementar manualmente desde su máquina local a su entorno respectivo, ejecute:

  • wrangler publish -e staging
  • wrangler publish -e production

Sin embargo, veremos cómo hacer esto automáticamente a través de nuestra canalización de CI/CD usando GitHub Actions.

Antes de continuar, puede encontrar la wrangler.tomlconfiguración completa aquí .

Oh, aquí hay una hoja de trucos para configurar wrangler.toml. ¡Te recomiendo que hagas uso de esto!

grafana k6

Para las pruebas de integración, usaremos una herramienta conocida como k6. Generalmente, k6 se usa como una herramienta para pruebas de rendimiento y carga. Ahora, tengan paciencia conmigo, no vamos a integrar ninguna prueba de carga en nuestra canalización de CI/CD; hoy no.

Aquí, ejecutaremos pruebas de humo para este proyecto cada vez que se envíen nuevas confirmaciones a nuestra mainrama. Una prueba de humo es esencialmente un tipo de prueba de integración que realiza una verificación de cordura en un sistema.

En este caso, realizar una prueba de humo es suficiente para determinar que nuestro sistema se implementa sin ninguna regresión y puede ejecutarse con una carga mínima.

que probar

Básicamente, aquí hay un par de cosas que queremos verificar como parte de nuestra prueba de humo para nuestra aplicación de acortador de URL en grupos :

  • La página principal debería cargarse como se esperaba con un estado de respuesta 200
group('visit main page', function () {
    const res = http.get(BASE_URL)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify homepage text': (r) =>
            r.body.includes(
                'A URL shortener POC built using Cloudflare Worker'
            ),
    })
})
  • Nuestro principal punto final de la API POST /api/urldebe crear una URL corta con la URL original
group('visit rest endpoint', function () {
    const res = http.post(
        `${BASE_URL}/api/url`,
        JSON.stringify({ originalUrl: DUMMY_ORIGINAL_URL }),
        { headers: { 'Content-Type': 'application/json' } }
    )check(res, {
        'is status 200': (r) => r.status === 200,
        'verify createShortUrl': (r) => {
            const { urlKey, shortUrl, originalUrl } = JSON.parse(r.body)
            shortenLink = shortUrl
            return urlKey.length === 8 && originalUrl === DUMMY_ORIGINAL_URL
        },
    })
})
  • Por último, queremos asegurarnos de que cuando visitemos la URL corta generada, nos redirija a la URL original.
group('visit shortUrl', function () {
    const res = http.get(shortenLink)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify original url': (r) => r.url === DUMMY_ORIGINAL_URL,
    })
})

Para probar localmente, simplemente ejecute k6 path/to/test.js. ¡Eso es todo! Puede encontrar el script de prueba completo aquí .

En caso de que esté pensando en ejecutar pruebas de carga, lea cómo determinar usuarios simultáneos en su prueba de carga.

Acciones de GitHub

Pasaré por alto esta sección ya que es bastante sencilla. Puede consultar el archivo de flujo de trabajo final de GitHub Actions aquí .

Juntemos todo lo que tenemos. A continuación se muestran las acciones de GitHub que necesitaremos usar:

Una cosa a tener en cuenta sobre el archivo de flujo de trabajo: para hacer que un trabajo dependa (necesite) de otro trabajo, utilizaremos la needsintaxis .

Secretos de acciones

Este proyecto requiere 2 acciones secretas:

  1. CF_API_TOKEN— Para ser utilizado por Wrangler GitHub Action para publicar automáticamente nuestro Cloudflare Worker en su entorno respectivo. Puede crear su token API utilizando la Edit Cloudflare Workersplantilla.
  2. NPM_TOKEN— Este proyecto también utiliza la liberación semántica para publicar automáticamente en NPM . Para habilitar esto, deberá crear un token de creación a NPM_TOKENtravés de npm .

Para agregarlo a los secretos de su repositorio de GitHub, consulte esta guía .

Si ha echado un vistazo al archivo de flujo de trabajo final, es posible que haya notado la sintaxis ${{ secrets.GITHUB_TOKEN }}y se haya preguntado por qué no mencioné nada sobre agregar GITHUB_TOKENsecretos de acciones a nuestro proyecto. Resulta que se crea y se agrega automáticamente a todos sus flujos de trabajo .

Comentario final

Es comprensible que las plataformas sin servidor sean generalmente conocidas por ser difíciles de probar y depurar. Sin embargo, eso no significa que debamos ignorarlo.

¿Qué es lo siguiente? Justo encima de mi cabeza, podríamos hacerlo mejor. Aquí hay un par de mejoras que podemos hacer:

  1. Agregue un trabajo/etapa que retroceda automáticamente y revierta la confirmación cuando fallan las pruebas de humo
  2. Cree un entorno de prueba individual después de la creación de relaciones públicas para que podamos realizar pruebas de humo en ellos.
  3. Probablemente sea excesivo para este proyecto: implementar la implementación canary suena como un desafío divertido

Referencias

Si está buscando pruebas unitarias de Cloudflare Workers, estas son mis recomendaciones:

Aquí hay un video decente sobre cómo configurar una canalización de CI/CD ideal pero práctica:

Fuente del artículo original en  https://betterprogramming.pub/  

#cicd #git #cloudflare 

Cómo Configurar La Canalización De CI/CD Para Cloudflare Worker
伊藤  直子

伊藤 直子

1653640984

Cloudflareワーカー用のCI/CDパイプラインを設定する方法

今日、GitHubでの私のプロジェクトのほとんどは、 Renovateで最新の状態に保たれています。自動マージを有効にして、自動依存関係の更新によってリグレッションが発生しないことを十分に確信したいと思います。

Cloudflareワーカーのテストはちょっと手間がかかります。誤解しないでください、私はCloudflareWorkerが大好きです。ただし、既存のソリューションは少し直感的ではないと感じています。その上、dollarshaveclub / cloudworkerはもはや積極的に維持されておらず、これは残念なことです。

TL; DR:GitHubActionとGrafanak6を使用してCloudflareWorkerプロジェクトのCI/CDパイプラインを設定する方法。

概要

以前、CloudflareWorkerを使用してURL短縮クローンを作成しました。この既存のプロジェクト(GitHubリンク)を使用して、簡単な統合テストとともに、そのプロジェクトのCI/CDパイプラインのセットアップを検討します。

GitHub Action CI/CDパイプラインはかなり単純です。ステージ(ジョブ)は次のとおりです。

GitHubでのCIワークフローの例

GitHubでのCIワークフローの例(リンク

  1. リントチェックまたはユニットテスト
  2. ステージング環境にデプロイします
  3. ステージング環境で統合テストを実行します
  4. セマンティックリリースを実行し、本番環境にデプロイします

WranglerConfig

まず、既存のwrangler.tomlファイルを変更する必要があります。統合テストを実行するには、ステージング環境をデプロイする必要があることを忘れないでください。

[env.staging]
name = "atomic-url-staging"
workers_dev = true
kv_namespaces = [
  { binding = "URL_DB", id = "ca7936b380a840908c035a88d1e76584" },
]
  • name—環境ごとnameに一意で英数字(許可)である必要があることを確認してください。-ステージング環境に名前を付けましょうatomic-url-staging
  • worker_dev—統合テストは<NAME>.<SUBDOMAIN>.workers.devエンドポイントで実行されます。workers_dev = trueしたがって、 (参照)を設定してCloudflareワーカーをデプロイする必要があります。
  • kv_namespaces— Atomic URLは、短縮URLを格納するデータベースとしてKVを使用します。ここでは、プレビュー名前空間KVをテストデータベースとして使用することを選択しました。なんで?ローカル開発中(実行中)に使用するのと同じ開発KV名前空間であるという理由だけでwrangler dev。もちろん、通常のKV名前空間を使用することもできます。ProductionKVを使用していないことを確認してくださいidKV名前空間を作成する方法をお読みください

次に、本番KV名前空間を使用してデプロイする本番環境も作成する必要があります。

[env.production]
name = "atomic-url"
route = "s.jerrynsh.com/*"
workers_dev = false
kv_namespaces = [
  { binding = "URL_DB", id = "7da8f192d2c1443a8b2ca76b22a8069f" },
]

本番環境のセクションは、前と同じですが、本番用に設定worker_dev = falseしますroute

展開

ローカルマシンからそれぞれの環境に手動でデプロイするには、次のコマンドを実行します。

  • wrangler publish -e staging
  • wrangler publish -e production

ただし、GitHubアクションを使用してCI/CDパイプラインを介してこれを自動的に行う方法を検討します。

先に進む前に、ここwrangler.tomlで完全な構成を見つけることができます。

ああ、これが設定するチートシートwrangler.tomlです。これを利用することを強くお勧めします!

Grafanak6

統合テストには、k6と呼ばれるツールを使用します。一般に、k6はパフォーマンスと負荷テストのツールとして使用されます。さて、我慢してください。負荷テストをCI/CDパイプラインに統合するつもりはありません。今日ではありません。

ここでは、新しいコミットがブランチにプッシュされるたびに、このプロジェクトのスモークテストを実行します。mainスモークテストは、基本的に、システムの健全性チェックを実行する統合テストの一種です。

この場合、スモークテストを実行するだけで、システムがリグレッションなしで展開され、最小限の負荷で実行できることを確認できます。

何をテストするか

基本的に、グループでのURL短縮アプリのスモークテストの一部として確認したいことがいくつかあります。

  • メインページは、200の応答ステータスで期待どおりに読み込まれるはずです
group('visit main page', function () {
    const res = http.get(BASE_URL)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify homepage text': (r) =>
            r.body.includes(
                'A URL shortener POC built using Cloudflare Worker'
            ),
    })
})
  • メインのPOSTAPIエンドポイント/api/urlは、元のURLで短縮URLを作成する必要があります
group('visit rest endpoint', function () {
    const res = http.post(
        `${BASE_URL}/api/url`,
        JSON.stringify({ originalUrl: DUMMY_ORIGINAL_URL }),
        { headers: { 'Content-Type': 'application/json' } }
    )check(res, {
        'is status 200': (r) => r.status === 200,
        'verify createShortUrl': (r) => {
            const { urlKey, shortUrl, originalUrl } = JSON.parse(r.body)
            shortenLink = shortUrl
            return urlKey.length === 8 && originalUrl === DUMMY_ORIGINAL_URL
        },
    })
})
  • 最後に、生成された短縮URLにアクセスすると、元のURLにリダイレクトされることを確認する必要があります
group('visit shortUrl', function () {
    const res = http.get(shortenLink)check(res, {
        'is status 200': (r) => r.status === 200,
        'verify original url': (r) => r.url === DUMMY_ORIGINAL_URL,
    })
})

ローカルでテストするには、を実行するだけk6 path/to/test.jsです。それで全部です!完全なテストスクリプトはここにあります。

負荷テストの実行を検討している場合は、負荷テストで同時ユーザーを決定する方法をお読みください。

GitHubアクション

このセクションは非常に単純なので、ここで詳しく説明します。ここで、最終的なGitHubActionsワークフローファイルを参照できます

私たちが持っているすべてのものをつなぎ合わせましょう。以下は、使用する必要のあるGitHubアクションです。

ワークフローファイルについて注意すべき点が1つあります。ジョブを別のジョブに依存させる(必要とする)ために、need構文を使用します。

アクションの秘密

このプロジェクトには、2つのアクションシークレットが必要です。

  1. CF_API_TOKEN— Wrangler GitHub Actionが、Cloudflareワーカーをそれぞれの環境に自動的に公開するために使用します。テンプレートを使用してAPIトークンを作成できますEdit Cloudflare Workers
  2. NPM_TOKEN—このプロジェクトは、semantic-releaseを使用してNPMに自動的に公開します。これを有効にするには、vianpmcreatetokenを作成する必要がNPM_TOKENあります

GitHubリポジトリシークレットに追加するには、このガイドを確認してください。

最終的なワークフローファイルをご覧になった方は、構文に気づき、プロジェクトのアクションシークレットに${{ secrets.GITHUB_TOKEN }}追加することについて何も言及しなかったのはなぜか疑問に思われたかもしれません。GITHUB_TOKEN結局のところ、それは自動的に作成され、すべてのワークフローに追加されます

閉会の辞

当然のことながら、サーバーレスプラットフォームは一般に、テストとデバッグが難しいことが知られています。しかし、それは私たちがそれを無視すべきだという意味ではありません。

それで、次は何ですか?私の頭の真上で、私たちはもっとうまくやることができました。これが私たちが行うことができるいくつかの改善です:

  1. スモークテストが失敗したときに自動的にロールバックしてコミットを元に戻すジョブ/ステージを追加します
  2. PRの作成時に個別のテスト環境を作成して、それらに対してスモークテストを実行できるようにします
  3. このプロジェクトではおそらくやり過ぎです—カナリアの展開を実装することは楽しい挑戦のように聞こえます

参考文献

Cloudflareワーカーの単体テストを検討している場合は、次のことをお勧めします。

これは、理想的でありながら実用的なCI/CDパイプラインのセットアップに関する適切なビデオです。

https://betterprogramming.pub/の元の記事のソース   

#cicd #git #cloudflare 

Cloudflareワーカー用のCI/CDパイプラインを設定する方法