à votre première application web avec AdonisJS AdonisJS Jaime Arias CNRS, Laboratoire d'Informatique de Paris Nord (LIPN) 23 juin 2026 Journées nationales du DEVeloppement logiciel (JDEV 2026) Code source du tutoriel github.com/himito/tutorial-adonisjs 1 / 59
LIPN Leads the dev team at LIPN Chargé de Mission at INS2I « Software » Member · Collège Codes Sources et Logiciels Ambassador · Software Heritage [email protected] www.jaime-arias.fr A AdonisJS 7 2 / 59
API, built test-first. DEMAIN Le front-end sera construit dans le tutoriel « Vue.js : Développer des interfaces utilisateur réactives et modulaires » A AdonisJS 7 3 / 59
around 2016 to end the "assemble your stack from scratch" era in Node. Inspired by Laravel and Rails. v7 highlights: end-to-end type safety, a new migrations-first Lucid that generates your model schema, zero-config OpenTelemetry, and a reworked auth starter kit. A AdonisJS 7 6 / 59
turn the editor into a guide — autocomplete for AdonisJS, plus the lint/format/error trio every Node.js project wants. AdonisJS Node.js essentials A AdonisJS 7 10 / 59
kits are pre-configured templates. We pick --kit=api — a headless JSON backend with the database and token auth already wired up. Open http://localhost:3333 — the backend returns: Official starter kits api NOTRE CHOIX Backend + empty frontend monorepo, end-to-end type-safe. hypermedia Server-rendered HTML with Edge templates & Alpine.js. react · vue Fullstack via Inertia.js — server-rendered or SPA. Community: slim (minimal) · mcp (MCP server). A AdonisJS 7 12 / 59
POST /todos + token Response 200 · JSON SQL The request enters the app, flows through the pipeline to the database, and the controller's return value flows back out as the JSON response. A AdonisJS 7 14 / 59
tidy Instead of testing afterwards, we lead with a test that states what an endpoint should do — then write just enough code to satisfy it. We keep it lighter than dogmatic TDD — not a failing test for every line, but each real feature leads with a test that states the goal. A AdonisJS 7 16 / 59
feature, confirm the harness runs: generate a test with ace, then send a real HTTP request to the health route at / — no database needed. That green line is the rhythm we repeat for every feature. A AdonisJS 7 18 / 59
SQLite needs zero setup — just npm i better-sqlite3 . The whole database is a single file; swap DB_CONNECTION later for Postgres in production. A AdonisJS 7 21 / 59
relationship: a user has many todos, and each todo belongs to a user. 1 ──< ∞ hasMany belongsTo todos.user_id references users.id — delete a user and their todos cascade away. A AdonisJS 7 22 / 59
a database change in code — an up() to apply it and a down() to undo it. The -m flag scaffolds the model and its migration together. A AdonisJS 7 23 / 59
writes one typed class per table into database/schema.ts . Your models extend these — never the other way around. serializeAs: null hides the password from JSON, and userId is the foreign key to users . A AdonisJS 7 25 / 59
Delete Active Record: the class queries the table, each instance is a row. Return one from a controller and it serializes to JSON automatically. A AdonisJS 7 27 / 59
behaviour as a test, then run it and watch it fail. Generate the test file Then run the suite It fails with a 404 — there's no route yet. A AdonisJS 7 29 / 59
just enough to satisfy the test — one action, one route. Scaffold it, implement one action Add one route Green! Now build out the rest the same way. A AdonisJS 7 30 / 59
tests Same rhythm: write the tests for create, show, update & delete — and watch them fail before writing a line of logic. Run the suite Four reds — now build the controller actions that turn them green. A AdonisJS 7 31 / 59
the full resource The --resource flag scaffolds all five REST actions. Each gets an HttpContext — request, response, params, auth, bouncer — in one object. Destructure what you need. A AdonisJS 7 32 / 59
response object has a named helper for each status — readable, and it sets the code for you. Success · 2xx response.ok() 200 OK response.created() 201 Created response.noContent() 204 No Content Client & server errors · 4xx / 5xx response.badRequest() 400 Bad Request response.unauthorized() 401 Unauthorized response.forbidden() 403 Forbidden response.notFound() 404 Not Found response.unprocessableEntity() 422 Invalid A thrown findOrFail() or a failed validator becomes 404 / 422 automatically. A AdonisJS 7 33 / 59
helper for every HTTP verb; whatever the handler returns becomes JSON. Routes can be named for easy URL building and grouped to share a prefix or middleware. A helper for every HTTP verb Named routes (aliases) Groups — shared prefix & middleware A AdonisJS 7 34 / 59
factories generate realistic records on demand — so your tests read intent, not boilerplate. Define it once Use it everywhere Backed by Faker for fake titles, emails, dates — one line replaces a wall of create({ … }) . A AdonisJS 7 36 / 59
several items Seed a few rows with the factory, then assert the endpoint returns them all. Run it createMany(3) fills the table; res.body() is the parsed JSON — assert on its length and contents. A AdonisJS 7 37 / 59
for authenticating requests. AdonisJS ships three — pick per app; we use access tokens for our API. All three share one API — auth.use('api').authenticate() — so swapping strategies barely touches your code. A AdonisJS 7 43 / 59
string that carries no data of its own — unlike a JWT. The server stores only its hash and looks it up on every request. If the hash matches, the request runs as that user. If it's missing or wrong, it's a 401 — and because only the hash is stored, a token can be revoked instantly. A AdonisJS 7 44 / 59
file — a named guard that uses tokens and points at your User model. What each piece does default: 'api' The guard used whenever you don't name one explicitly. tokensGuard Reads the Authorization: Bearer header and verifies the token. tokensUserProvider Resolves the user from the User model and its accessTokens . A AdonisJS 7 45 / 59
composes the generated UserSchema with the withAuthFinder mixin — which hashes passwords and adds verifyCredentials . We add the todos relationship. A AdonisJS 7 46 / 59
public routes No auth middleware — reachable before you have a token. token.value!.release() reveals the plain string — the only moment you can read it. A AdonisJS 7 47 / 59
with a factory UserFactory.merge({ password }) creates a real user so we can log in as them. Focus one test .pin() runs only this test — handy while iterating on a single endpoint. A AdonisJS 7 49 / 59
You write abilities (inline checks) and policies (a class per model), then ask bouncer "can this user do X?" — it answers true / false or throws a 403 . Install & configure One command wires the provider, the initialize_bouncer middleware, and the abilities / policies folders. Two ways to authorize A AdonisJS 7 53 / 59
for the resource, then encode the rule. Each method returns a boolean: true allows, false denies. Generate it Bouncer auto-discovers policies, so the class is ready to use immediately. Encode the rule A AdonisJS 7 54 / 59
filtering — add .paginate(page, limit) (write the test first!) Token abilities — issue read-only tokens with scopes Rate limiting & CORS — both first- party, a few lines each Deploy — node ace build , ship to any Node 24 host A AdonisJS 7 58 / 59
You built it test-first. test-first. Routes, controllers, models, validators, guards and policies — each led by a test, all backed by a green suite. docs.adonisjs.com lucid.adonisjs.com 59 / 59