INTEGRITY Dokumentace

Vytvoření adresáře zaměstnanců

V tomto tutoriálu se naučíte, jak pomocí D1 vytvořit adresář zaměstnanců. Tato aplikace umožní uživatelům zobrazit informace o zaměstnancích organizace a administrátorům umožní přímo v aplikaci přidávat nové zaměstnance. K tomu budete nejprve potřebovat nastavit databáze D1 ke správě dat bez problémů a poté vyvinete a nasadíte svoji aplikaci pomocí HonoX framework a Cloudflare Pages.

Předpoklady

Než budete pokračovat v tomto tutoriálu, ujistěte se, že máte následující:

Pokud nechcete nastavení dokončit nyní, zobrazit dokončený kód na GitHubu.

1. Nainstalujte HonoX

V tomto tutoriálu použijete HonoX, metaframework pro vytváření full-stack webů a webových API k sestavení vaší aplikace. Chcete-li HonoX použít ve svém projektu, spusťte hono-create příkazu.

Pro začátek spusťte následující příkaz:

npm create hono@latest

Během procesu nastavení budete požádáni o zadání názvu adresáře projektu a výběr šablony. Při výběru zvolte x-basic šablona.

2. Inicializujte svou aplikaci HonoX

Jakmile je projekt nastavený, uvidíte seznam vygenerovaných souborů níže. Toto je typická struktura projektu pro aplikaci HonoX:

.
├── app
│   ├── global.d.ts // global type definitions
│   ├── routes
│   │   ├── _404.tsx // not found page
│   │   ├── _error.tsx // error page
│   │   ├── _renderer.tsx // renderer definition
│   │   ├── about
│   │   │   └── [name].tsx // matches `/about/:name`
│   │   └── index.tsx // matches `/`
│   └── server.ts // server entry file
├── package.json
├── tsconfig.json
└── vite.config.ts

Projekt obsahuje adresáře pro kód aplikace, trasy a nastavení serveru, spolu s konfiguračními soubory pro správu balíčků, TypeScript a Vite.

3. Vytvořte databázi

Chcete-li vytvořit databázi pro svůj projekt, použijte nástroj Cloudflare CLI Wrangler, který podporuje wrangler d1 příkaz pro operace s databází D1. Vytvořte novou databázi s názvem staff-directory s následujícím příkazem:

npx wrangler d1 create staff-directory

Po vytvoření databáze bude nutné nastavit binding v Konfigurační soubor Wrangler k propojení databáze s vaší aplikací.

Tento binding umožňuje vaší aplikaci pracovat s prostředky Cloudflare, jako jsou databáze D1, KV namespaces a R2 buckety. Chcete-li to nastavit, vytvořte v kořenovém adresáři projektu soubor Wrangler a zadejte základní informace o konfiguraci:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "staff-directory",
	// Set this to today's date
	"compatibility_date": "2026-08-28"
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "staff-directory"
# Set this to today's date
compatibility_date = "2026-08-28"

Dále přidejte údaje o databázovém bindingu do souboru Wrangler. To zahrnuje zadání názvu bindingu (v tomto případě DB), která se použije k odkazování na databázi ve vaší aplikaci, spolu s database_name a database_id zadaný při vytváření databáze:

{
	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "staff-directory",
			"database_id": "f495af5f-dd71-4554-9974-97bdda7137b3"
		}
	]
}
[[d1_databases]]
binding = "DB"
database_name = "staff-directory"
database_id = "f495af5f-dd71-4554-9974-97bdda7137b3"

Nyní máte aplikaci nakonfigurovanou pro přístup k databázi D1 a práci s ní, ať už přes příkazovou řádku, nebo přímo v kódu.

Budete také muset upravit konfigurační soubor Vite v vite.config.js. Přidejte následující konfigurační nastavení, aby byl Vite v lokálním prostředí správně nastaven pro práci s vazbami Cloudflare:

import adapter from "@hono/vite-dev-server/cloudflare";

export default defineConfig(({ mode }) => {
	if (mode === "client") {
		return {
			plugins: [client()],
		};
	} else {
		return {
			plugins: [
				honox({
					devServer: {
						adapter,
					},
				}),
				pages(),
			],
		};
	}
});

4. Pracujte s D1

S databází D1 můžete přímo pracovat vydáváním SQL příkazů pomocí wrangler d1 execute příkaz:

wrangler d1 execute staff-directory --command "SELECT name FROM sqlite_schema WHERE type ='table'"

Výše uvedený příkaz umožňuje spouštět dotazy nebo operace přímo z příkazové řádky.

Pro operace, jako je počáteční naplnění dat nebo dávkové zpracování, můžete předat soubor SQL s příkazy. Za tímto účelem vytvořte schema.sql soubor v kořenovém adresáři vašeho projektu a vložte do něj své SQL dotazy:

CREATE TABLE locations (
    location_id INTEGER PRIMARY KEY AUTOINCREMENT,
    location_name VARCHAR(255) NOT NULL
);

CREATE TABLE departments (
    department_id INTEGER PRIMARY KEY AUTOINCREMENT,
    department_name VARCHAR(255) NOT NULL
);

CREATE TABLE employees (
    employee_id INTEGER PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(255) NOT NULL,
    position VARCHAR(255) NOT NULL,
    image_url VARCHAR(255) NOT NULL,
    join_date DATE NOT NULL,
    location_id INTEGER REFERENCES locations(location_id),
    department_id INTEGER REFERENCES departments(department_id)
);

INSERT INTO locations (location_name) VALUES ('London, UK'), ('Paris, France'), ('Berlin, Germany'), ('Lagos, Nigeria'), ('Nairobi, Kenya'), ('Cairo, Egypt'), ('New York, NY'), ('San Francisco, CA'), ('Chicago, IL');

INSERT INTO departments (department_name) VALUES ('Software Engineering'), ('Product Management'), ('Information Technology (IT)'), ('Quality Assurance (QA)'), ('User Experience (UX)/User Interface (UI) Design'), ('Sales and Marketing'), ('Human Resources (HR)'), ('Customer Support'), ('Research and Development (R&D)'), ('Finance and Accounting');

Výše uvedené dotazy vytvoří tři tabulky: Locations, Departments, a Employees. Chcete-li tyto tabulky naplnit počátečními daty, použijte INSERT INTO příkaz. Po přípravě souboru se schématem pomocí těchto příkazů jej můžete použít v databázi D1. Provedete to pomocí --file příznak pro určení souboru schématu ke spuštění:

wrangler d1 execute staff-directory --file=./schema.sql

Chcete-li lokálně spustit schéma a naplnit data do lokálního adresáře, předejte --local příznak k výše uvedenému příkazu.

5. Vytvořte příkazy SQL

Jakmile máte databázi D1 nastavenou a soubor Wrangler nakonfigurovaný podle předchozích kroků, je databáze ve vašem kódu dostupná prostřednictvím DB binding. To vám umožní přímo pracovat s databází přípravou a spouštěním příkazů SQL. V následujícím kroku se naučíte, jak pomocí tohoto bindingu provádět běžné databázové operace, jako je načítání dat a vkládání nových záznamů.

Získávání dat z databáze

export const findAllEmployees = async (db: D1Database) => {
	const query = `
      SELECT employees.*, locations.location_name, departments.department_name
      FROM employees
      JOIN locations ON employees.location_id = locations.location_id
      JOIN departments ON employees.department_id = departments.department_id
      `;
	const { results } = await db.prepare(query).run();
	const employees = results;
	return employees;
};

Vložení dat do databáze

export const createEmployee = async (db: D1Database, employee: Employee) => {
	const query = `
      INSERT INTO employees (name, position, join_date, image_url, department_id, location_id)
      VALUES (?, ?, ?, ?, ?, ?)`;

	const results = await db
		.prepare(query)
		.bind(
			employee.name,
			employee.position,
			employee.join_date,
			employee.image_url,
			employee.department_id,
			employee.location_id,
		)
		.run();
	const employees = results;
	return employees;
};

Úplný seznam všech dotazů použitých v aplikaci najdete v db.ts soubor v kódové základně.

6. Vytvořte uživatelské rozhraní

Aplikace používá hono/jsx pro vykreslování. Renderer můžete nastavit v app/routes/_renderer.tsx pomocí middlewaru vykreslovaného přes JSX, který slouží jako vstupní bod vaší aplikace:

import { jsxRenderer } from 'hono/jsx-renderer'
import { Script } from 'honox/server'

export default jsxRenderer(({ children, title }) => {
  return (
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{title}</title>
        <Script src="/app/client.ts" async />
      </head>
      <body>{children}</body>
    </html>
  )
})

Přidejte vazby definované dříve v global.d.ts soubor, kde jsou definovány globální definice typů pro TypeScript, což zajišťuje konzistenci typů v celé aplikaci:

declare module "hono" {
	interface Env {
		Variables: {};
		Bindings: {
			DB: D1Database;
		};
	}
}

Tato aplikace používá Tailwind CSS pro stylování. Chcete-li použít Tailwind CSS, viz Dokumentace TailwindCSS, nebo postupujte podle kroků poskytnuto na GitHubu.

Chcete-li zobrazit seznam zaměstnanců, vyvolejte findAllEmployees funkci z vašeho db.ts soubor a zavolejte ji uvnitř routes/index.tsx soubor. createRoute() přítomná v souboru slouží jako pomocná funkce pro definování rout, které zpracovávají různé HTTP metody, jako GET, POST, PUT, nebo DELETE.

import { css } from 'hono/css'
import { createRoute } from 'honox/factory'
import Counter from '../islands/counter'

const className = css`
  font-family: sans-serif;
`

export default createRoute((c) => {
  const name = c.req.query('name') ?? 'Hono'
  return c.render(
    <div class={className}>
      <h1>Hello, {name}!</h1>
      <Counter />
    </div>,
    { title: name }
  )
})

Stávající kód v souboru obsahuje zástupný symbol využívající komponentu Counter. Tuto část byste měli nahradit následujícím blokem kódu:

import { createRoute } from 'honox/factory'
import type { FC } from 'hono/jsx'
import type { Employee } from '../db'
import { findAllEmployees, findAllDepartments, findAllLocations } from '../db'

const EmployeeCard: FC<{ employee: Employee }> = ({ employee }) => {
  const { employee_id, name, image_url, department_name, location_name } = employee;
  return (
    <div className="max-w-sm bg-white border border-gray-200 rounded-lg shadow-md">
      <a href={`/employee/${employee_id}`}>
        <img className="bg-indigo-600 p-4 rounded-t-lg" src={image_url} alt={name} />
        //...
      </a>
    </div>
  );
};

export const GET = createRoute(async (c) => {
  const employees = await findAllEmployees(c.env.DB)
  const locations = await findAllLocations(c.env.DB)
  const departments = await findAllDepartments(c.env.DB)
  return c.render(
    <section className="flex-grow">
      <h1 className="mb-4 text-3xl font-extrabold text-gray-900 dark:text-white md:text-5xl lg:text-6xl mt-12">
        <span className="text-transparent bg-clip-text bg-gradient-to-r to-blue-600 from-sky-400">{`Directory `}</span>
      </h1>
      //...
      </section>
      <section className="flex flex-wrap -mx-4">
        {employees.map((employee) => (
          <div className="w-full sm:w-1/2 md:w-1/3 lg:w-1/4 px-2 mb-4">
            <EmployeeCard employee={employee} />
          </div>
        ))}
      </section>
    </section>
  )
})

Tento úryvek kódu ukazuje, jak importovat findAllEmployees, findAllLocations, a findAllDepartments funkce z db.ts soubor a jak používat vazbu c.env.DB k volání těchto funkcí. Díky nim můžete načtená data získat a zobrazit na stránce.

Přidání zaměstnance

Použijte export POST trasu pro vytvoření nového zaměstnance přes /admin stránka:

import { createRoute } from "honox/factory";
import type { Employee } from "../../db";
import { getFormDataValue, getFormDataNumber } from "../../utils/formData";
import { createEmployee } from "../../db";

export const POST = createRoute(async (c) => {
	try {
		const formData = await c.req.formData();
		const imageFile = formData.get("image_file");
		let imageUrl = "";

		// TODO: process image url with R2

		const employeeData: Employee = {
			employee_id: getFormDataValue(formData, "employee_id"),
			name: getFormDataValue(formData, "name"),
			position: getFormDataValue(formData, "position"),
			image_url: imageUrl,
			join_date: getFormDataValue(formData, "join_date"),
			department_id: getFormDataNumber(formData, "department_id"),
			location_id: getFormDataNumber(formData, "location_id"),
			location_name: "",
			department_name: "",
		};

		await createEmployee(c.env.DB, employeeData);
		return c.redirect("/", 303);
	} catch (error) {
		return new Response("Error processing your request", { status: 500 });
	}
});

Ukládejte obrázky do R2

Během vytváření nového zaměstnance lze nahraný obrázek uložit do bucketu R2 ještě před přidáním do databáze.

Pro uložení obrázku do bucketu R2:

  1. Vytvořte R2 bucket.
  2. Nahrajte obrázek do tohoto bucketu.
  3. Získejte veřejnou URL adresu obrázku z bucketu. Tato URL adresa se poté uloží do databáze a odkazuje na obrázek uložený v bucketu R2.

Použijte wrangler r2 bucket create příkaz k vytvoření bucketu:

wrangler r2 bucket create employee-avatars

Jakmile je bucket vytvořen, přidejte binding bucketu R2 do souboru Wrangler:

{
	"r2_buckets": [
		{
			"binding": "MY_BUCKET",
			"bucket_name": "employee-avatars"
		}
	]
}
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "employee-avatars"

Předejte binding R2 do global.d.ts soubor:

declare module "hono" {
	interface Env {
		Variables: {};
		Bindings: {
			DB: D1Database;
			MY_BUCKET: R2Bucket;
		};
	}
}

Pro uložení nahraného obrázku do bucketu R2 můžete použít put() metoda poskytovaná službou R2. Tato metoda umožňuje nahrát soubor obrázku do vašeho bucketu:

if (imageFile instanceof File) {
	const key = `${new Date().getTime()}-${imageFile.name}`;
	const fileBuffer = await imageFile.arrayBuffer();

	await c.env.MY_BUCKET.put(key, fileBuffer, {
		httpMetadata: {
			contentType: imageFile.type || "application/octet-stream",
		},
	});
	console.log(`File uploaded successfully: ${key}`);
	imageUrl = `https://pub-8d936184779047cc96686a631f318fce.r2.dev/${key}`;
}

Viz GitHub pro celou kódovou základnu.

7. Nasaďte svou aplikaci HonoX

Jakmile je vaše aplikace připravena k nasazení, můžete pomocí Wrangleru sestavit a nasadit projekt do sítě Cloudflare Network. Ujistěte se, že jste přihlášeni ke svému účtu Cloudflare spuštěním wrangler whoami příkaz. Pokud nejste přihlášeni, Wrangler vás vyzve k přihlášení vytvořením API klíče, který můžete použít k automatickému odesílání ověřených požadavků z vašeho počítače.

Po úspěšném přihlášení zkontrolujte, že je váš soubor Wrangler nakonfigurován podobně jako v níže uvedeném bloku kódu:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "staff-directory",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
	"r2_buckets": [
		{
			"binding": "MY_BUCKET",
			"bucket_name": "employee-avatars"
		}
	],
	"d1_databases": [
		{
			"binding": "DB",
			"database_name": "staff-directory",
			"database_id": "f495af5f-dd71-4554-9974-97bdda7137b3"
		}
	]
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "staff-directory"
# Set this to today's date
compatibility_date = "2026-08-28"

[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "employee-avatars"

[[d1_databases]]
binding = "DB"
database_name = "staff-directory"
database_id = "f495af5f-dd71-4554-9974-97bdda7137b3"

Spustit wrangler deploy k nasazení projektu na Cloudflare. Po nasazení můžete ověřit, že aplikace funguje, otevřením přidělené adresy URL nasazení. V prohlížeči by se měla zobrazit vaše aplikace se základním frontendem, který jste vytvořili. Pokud vaše databáze neobsahuje žádná data, přejděte na /admin stránku pro přidání nového zaměstnance, po čemž by se měl nový zaměstnanec zobrazit na vaší domovské stránce.

Závěr

V tomto tutoriálu jste vytvořili aplikaci adresáře zaměstnanců, ve které uživatelé mohou zobrazit všechny zaměstnance organizace. Podrobnosti najdete v Repozitář Staff Directory pro celý zdrojový kód.

ukázka Staff Directory