Ajouter la recherche de tickets à un Worker

CloudflareBeginner
Pratiquer maintenant

Introduction

Une API de support doit pouvoir trouver les tickets ouverts et créer, mettre à jour ou supprimer des enregistrements individuels en toute sécurité. Vous allez connecter un Worker à D1, mettre en place un accès SQL paramétré et tester le comportement de l’API face aux enregistrements manquants et aux entrées incorrectes.

Le routeur HTTP est fourni afin que vous puissiez vous concentrer sur l’intégration de la base de données. Cet atelier indépendant utilise un Worker et une base de données D1 temporaires, ainsi que des données locales distinctes.

Utilisez votre propre compte d’apprentissage et une VM fraîche. La configuration prépare d’abord Node.js 22.22.0, puis exécute npm install pour installer Wrangler 4.131.1, utilisé localement pour le projet, ainsi que les dépendances nécessaires à l’évaluation dans /home/labex/project/ticket-database. Les versions des dépendances directes sont verrouillées ; l’installation crée son propre fichier lock. La configuration n’effectue aucune connexion au cloud ni aucune opération évaluée sur la base de données. Sur une machine personnelle, installez la même version de Wrangler avec npm install --save-dev wrangler@4.131.1 dans votre projet.

Cet exercice utilise de petits enregistrements synthétiques dans les limites de l’offre D1 Free allowances. L’utilisation déjà effectuée sur votre compte est prise en compte dans ces limites. Aucun domaine acheté n’est nécessaire. Conservez cette VM jusqu’à ce que la suppression des ressources et la déconnexion aient toutes deux été vérifiées.

Autoriser cette VM et sélectionner le compte

Dans cette étape, vous connectez ce terminal fraîchement préparé à votre propre compte d’apprentissage. Une simple connexion au Dashboard n’autorise pas la VM. L’autorisation D1 permet de créer, modifier et supprimer des bases de données ; l’autorisation Workers permet le déploiement ; l’autorisation KV permet à Wrangler de gérer l’inventaire lors du nettoyage. Consultez la page de consentement réelle, notamment la section Background Access, avant d’autoriser l’accès.

Ouvrez le projet préparé et vérifiez la version verrouillée de l’interface en ligne de commande :

cd /home/labex/project/ticket-database
npx wrangler --version

La sortie attendue est 4.131.1. Lancez l’autorisation par appareil ; --device affiche un code à saisir dans un navigateur et --browser=false vous laisse choisir vous-même le navigateur :

npx wrangler login --device --browser=false --scopes account:read user:read d1:write workers_scripts:write workers_kv:write

Ouvrez l’URL affichée dans votre navigateur, saisissez le code actuel, vérifiez votre compte d’apprentissage et les autorisations demandées, puis autorisez l’accès. Attendez que le terminal confirme la réussite. Ne collez jamais de mots de passe ou de jetons dans les fichiers du projet.

npx wrangler whoami --json

Vérifiez que loggedIn: true apparaît, puis lisez le name et l’id du compte, même si un seul compte est listé. Copiez l’ID voulu dans la configuration ci-dessous. La variable shell suivante utilise 6 octets aléatoires, soit 12 caractères hexadécimaux, afin d’éviter les collisions avec les autres participants. Un here-document écrit le JSON situé entre les lignes JSON ; $RUN y est développé.

La barre oblique inverse devant $schema conserve cette clé JSON littérale ; $RUN est toujours remplacé par le nom unique de cette exécution.

RUN=labex-c04-d02-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
  "\$schema": "./node_modules/wrangler/config-schema.json",
  "name": "$RUN",
  "account_id": "YOUR_ACCOUNT_ID",
  "main": "src/index.js",
  "compatibility_date": "2026-09-15",
  "workers_dev": true,
  "preview_urls": false
}
JSON

Remplacez YOUR_ACCOUNT_ID avant d’exécuter ce bloc. Gardez ce terminal ouvert afin que RUN reste disponible. name identifie cette exécution ; account_id sélectionne le compte utilisé pour les opérations cloud. Le fichier est un fichier JSON ordinaire, également valide en JSONC. Sa création ne déploie aucun Worker.

Préparer des données locales et distantes indépendantes

Dans cette étape, vous créez la connexion D1 et alimentez la table de tickets familière. La configuration fournit le routage HTTP et la validation des entrées dans src/index.js ; les fonctions de stockage manquantes se trouvent dans src/store.js. Vous pouvez ainsi vous concentrer sur l’accès SQL.

Créez une base de données cloud temporaire. --binding DB fournit au code de l’application un nom court, --update-config enregistre son nom réel et son UUID dans wrangler.jsonc, et --use-remote=false conserve le développement en local :

npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false

Lisez le nom et l’ID créés, puis inspectez la liaison enregistrée :

cat wrangler.jsonc

L’entrée DB doit désigner la base de données de cette exécution. Une liaison est une connexion configurée entre le code et une ressource. Son UUID identifie la base de données cloud, tandis que --local utilise une base de données SQLite distincte sur cette VM. Incluez toujours --local ou --remote dans les commandes SQL.

cat schema.sql
npx wrangler d1 execute DB --local --file schema.sql
npx wrangler d1 execute DB --remote --file schema.sql

Les deux cibles contiennent maintenant les deux mêmes tickets de départ. DB est le nom reçu par le gestionnaire fourni sous la forme env.DB ; il doit correspondre à la liaison de la configuration.

Implémenter les opérations CRUD paramétrées

Dans cette étape, vous implémentez les opérations CRUD : créer, lire, mettre à jour et supprimer. Une instruction préparée sépare la structure SQL des données saisies. Chaque ? est un paramètre de substitution ; .bind(...) fournit les valeurs dans l’ordre. Ne concaténez jamais une entrée utilisateur dans du SQL, même si elle semble inoffensive.

WHERE limite les enregistrements concernés. .all() renvoie un objet de résultat dont le champ results contient le tableau de lignes. .first() renvoie une ligne ou null. La clause RETURNING de SQLite renvoie la ligne modifiée sans nécessiter de nouvelle recherche. Pour une suppression, .run() expose meta.changes, qui indique si l’enregistrement existait réellement.

Écrivez le module de stockage :

cat > src/store.js <<'JS'
export async function list(db, status) {
  const query = status === null
    ? db.prepare('SELECT id, subject, status, source FROM tickets ORDER BY id')
    : db.prepare('SELECT id, subject, status, source FROM tickets WHERE status = ? ORDER BY id').bind(status);
  const { results } = await query.all();
  return results;
}
export async function get(db, id) {
  return db.prepare('SELECT id, subject, status, source FROM tickets WHERE id = ?').bind(id).first();
}
export async function create(db, subject) {
  return db.prepare("INSERT INTO tickets (subject, source) VALUES (?, 'api') RETURNING id, subject, status, source").bind(subject).first();
}
export async function update(db, id, status) {
  return db.prepare('UPDATE tickets SET status = ? WHERE id = ? RETURNING id, subject, status, source').bind(status, id).first();
}
export async function remove(db, id) {
  const result = await db.prepare('DELETE FROM tickets WHERE id = ?').bind(id).run();
  return result.meta.changes === 1;
}
JS

Lisez src/index.js pour voir comment le routage fourni utilise ces fonctions. Les enregistrements manquants produisent une réponse 404 contrôlée ; une entrée mal formée produit une réponse 400 ; une erreur de base de données interceptée produit une réponse 503 sans révéler les détails internes de SQL.

Démarrez le serveur local en tâche de fond afin de conserver le terminal disponible :

npx wrangler dev --ip 0.0.0.0 > dev.log 2>&1 &

Lisez le journal de démarrage et attendez le message indiquant que le serveur est à l’écoute :

cat dev.log
curl -i http://localhost:8787/tickets?status=open

Vous devez obtenir HTTP 200 et uniquement le ticket 1. Le serveur utilise la base de données locale. Notez le numéro de tâche affiché par le terminal pour pouvoir effectuer le nettoyage.

Tester les écritures et les entrées rejetées en local

Dans cette étape, vous testez autre chose que des lectures réussies. curl -i affiche le statut HTTP et les en-têtes ; -H fournit le type de contenu JSON et -d envoie un corps, avec la méthode POST par défaut.

Créez un sujet contenant une ponctuation ressemblant à du SQL :

curl -i http://localhost:8787/tickets -H 'Content-Type: application/json' -d "{\"subject\":\"Printer ' OR 1=1 --\"}"

Vous devez obtenir 201, avec le sujet conservé comme donnée. Copiez l’id numérique renvoyé dans TICKET_ID ci-dessous ; ne supposez pas que les ID restent identiques après plusieurs tests :

TICKET_ID=YOUR_RETURNED_ID
curl -i http://localhost:8787/tickets/$TICKET_ID
curl -i -X PATCH http://localhost:8787/tickets/$TICKET_ID -H 'Content-Type: application/json' -d '{"status":"closed"}'
curl -i -X DELETE http://localhost:8787/tickets/$TICKET_ID
curl -i http://localhost:8787/tickets/$TICKET_ID

Vous devez obtenir une lecture 200, une mise à jour 200 avec closed, une suppression 204 sans corps, puis 404 avec {"error":"not_found"}. Les deux tickets d’origine doivent rester intacts.

Envoyez un JSON mal formé et un statut incorrect :

curl -i http://localhost:8787/tickets -H 'Content-Type: application/json' -d '{'
curl -i -X PATCH http://localhost:8787/tickets/1 -H 'Content-Type: application/json' -d '{"status":"lost"}'

Vous devez obtenir HTTP 400 avec invalid_json, puis invalid_status. Le paramétrage SQL empêche l’entrée de devenir du SQL, tandis que la validation applicative rejette les valeurs qui ne respectent pas les règles métier. Ces deux mécanismes répondent à des problèmes différents.

Déployer et tester la base de données liée

Dans cette étape, vous publiez le gestionnaire et sa liaison D1. La base de données distante est déjà alimentée ; le déploiement ne copie pas les lignes locales.

npx wrangler deploy

Copiez l’URL réelle https://...workers.dev affichée après le déploiement dans une variable shell. Il s’agit d’une API synthétique temporaire : supprimez-la après les tests.

URL='YOUR_DEPLOYED_HTTPS_URL'
curl -i "$URL/tickets?status=open"

Vous devez obtenir 200 et le ticket 1. Si un déploiement récent renvoie temporairement une erreur de la plateforme, attendez quelques secondes et répétez cette lecture pendant une minute au maximum. Ne poursuivez que lorsque le statut et le JSON correspondent ; une erreur persistante doit être examinée.

Répétez les opérations CRUD sur l’API distante en copiant l’ID renvoyé par cette API :

curl -i "$URL/tickets" -H 'Content-Type: application/json' -d '{"subject":"Remote test"}'
TICKET_ID=YOUR_RETURNED_ID
curl -i -X PATCH "$URL/tickets/$TICKET_ID" -H 'Content-Type: application/json' -d '{"status":"closed"}'
curl -i -X DELETE "$URL/tickets/$TICKET_ID"
curl -i "$URL/tickets/$TICKET_ID"
curl -i "$URL/tickets"

Vous devez obtenir 201, 200, 204, 404, puis les deux tickets de départ inchangés. Dans le Dashboard, ouvrez précisément ce Worker et sa vue Bindings. Vérifiez que DB pointe vers votre base de données ; suivez le lien vers la base de données pour effectuer une inspection en lecture seule. Une liaison enregistrée localement ne prouve pas que la connexion déployée est correcte.

Le Worker déployé et sa liaison DB

Cet exemple montre le Worker déployé connecté à sa base D1 via DB. Le suffixe aléatoire identifie cette exécution d’exemple ; vos noms seront différents. Le lien Value du tableau ouvre la base de données sélectionnée par la liaison déployée.

Supprimer les ressources temporaires

Dans cette étape, vous supprimez uniquement les ressources de cet atelier alors que la VM est encore autorisée. Terminez d’abord toutes les vérifications fonctionnelles. Conservez la configuration jusqu’à la fin de la vérification de suppression.

npx wrangler delete

Vérifiez que seul le nom du Worker de cette exécution apparaît dans la configuration.

npx wrangler d1 delete DB

Examinez l’invite et confirmez qu’il s’agit uniquement de la base de données de cette exécution. Listez ensuite les bases de données :

npx wrangler d1 list --json

Le nom et l’UUID de la base de données que vous avez notés doivent être absents d’une réponse réussie. D’autres ressources peuvent rester présentes. Une erreur d’authentification ou de réseau ne permet pas de conclure : rétablissez l’accès et répétez la lecture avant de continuer. Effectuez la vérification de cette étape tant que vous êtes encore connecté.

Arrêtez également la tâche de développement locale. Listez les tâches et terminez uniquement la tâche wrangler dev que vous avez démarrée, en remplaçant %1 si son numéro de tâche est différent :

jobs
kill %1

Mettre fin à l’autorisation de cette VM

Dans cette étape, vous mettez fin à l’autorisation uniquement après la réussite de la vérification indépendante de la suppression. La déconnexion supprime l’autorisation Wrangler enregistrée sur cette VM ; fermer une VM ne suffit pas à nettoyer les ressources cloud.

npx wrangler logout
npx wrangler whoami --json

Vous devez obtenir loggedIn: false. Cette requête non authentifiée peut se terminer avec un code différent de zéro ; cela est attendu uniquement si la réponse structurée indique explicitement que vous êtes déconnecté. Terminez la vérification, puis fermez l’environnement de l’atelier.

Résumé

Vous avez appris à ajouter une recherche de tickets à un Worker. Vous avez vérifié les résultats observables dans la base de données, conservé explicitement l’état local et le compte sélectionné, puis supprimé les ressources temporaires avant de vous déconnecter.