⚡ Zig Guide LiveUnofficialbut fully verified
✓ Zig 0.17.0-dev.1778+767d25269What's newOn an older Zig?

What We Are Building

A URL shortener: you hand it a long address, it hands you a short one, and anyone who follows the short one lands on the long one. It is the classic first service for a reason. It is small enough to finish and real enough to need everything a bigger service needs: a database, a schema, validation, and an HTTP surface with all four verbs.

The finished service speaks five routes:

RouteDoesWhich is
POST /linksshorten a URL, answer with the slugCreate
GET /{slug}redirect, and count the hitRead
GET /links/{slug}report target and hit countRead
PUT /links/{slug}point the slug somewhere elseUpdate
DELETE /links/{slug}retire the slugDelete

Storage is PostgreSQL, one table:

CREATE TABLE links (
  id     bigserial PRIMARY KEY,
  slug   text UNIQUE NOT NULL,
  target text NOT NULL,
  hits   bigint NOT NULL DEFAULT 0
);

Decision one: no driver

The service talks to Postgres directly, over its wire protocol. The cookbook recipe showed that protocol byte by byte: every message is a tag, a length, and a payload. This project turns that recipe into something a program can lean on: a client that connects, authenticates, sends SQL, iterates rows, and survives errors. That is what a driver is, and writing one small enough to read removes the last box marked magic between your code and the database.

Decision two: the seams

Almost nothing in this project needs a network to run. That is not an accident; it is the same rule the rest of the guide follows: protocol code parses from a Reader, never from a socket. The Postgres client is tested against scripted bytes. The slug logic is arithmetic. The HTTP handlers take request bytes and return response bytes, against a store interface with an in-memory implementation, the same seam the ORM’s Repo chapter used. So those three chapters run in your browser, checked by CI like every other snippet on this site.

Only the last chapter opens sockets. It assembles the client, the slugs and the routes into one file, swaps the in-memory store for one that writes SQL, and serves the whole thing against a real database. CI compiles that file on every run; you run it on your machine, where a real Postgres can answer.

What is deliberately missing

Naming what a small project skips is more honest than hoping nobody asks, and each gap here is one seam away from this design.

  • Connection pooling. One connection serves every request, which is fine at tutorial scale.
  • The extended query protocol. Real drivers send parameters separately from SQL. This project quotes values into SQL text, does it carefully, and the client chapter says exactly what the tradeoff is.
  • SCRAM authentication. The client speaks cleartext password auth, which is what a default local Postgres accepts from loopback. The client chapter names what production adds.
  • Users and rate limits. Nothing here knows who you are.

The web server track covers the HTTP side in full depth; this project reuses its ideas in miniature and keeps the focus on the storage path.