Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Heure ProDev : AdonisJS

Heure ProDev : AdonisJS

Avatar for Jaime Arias Almeida

Jaime Arias Almeida

November 06, 2025
Tweet

More Decks by Jaime Arias Almeida

Other Decks in Programming

Transcript

  1. Jaime Arias CNRS Research Engineer @ LIPN Responsible of the

    dev-team @ LIPN Chargé de mission Logiciels @ INS2I Member Collège Codes Sources et Logiciels (CoSo) Ambassador Sofware Heritage [email protected] https://www.jaime-arias.fr Heure ProDev - Jaime Arias | 2 of 50
  2. Disclaimer This presentation will present the essentials of AdonisJS and

    will not cover technical aspects. Heure ProDev - Jaime Arias | 3 of 50
  3. What is AdonisJS ? npm npm v6.19.1 v6.19.1 downloads downloads

    212k/month 212k/month license license MIT MIT issues issues 4 open 4 open Stars Stars 18k 18k TypeScript-first web framework for building web apps and API servers. Provides a cohesive ecosystem for: Fullstack MVC framework for Node.js Heure ProDev - Jaime Arias | 5 of 50
  4. Installation AdonisJS You can create a new project using npm

    init . ❯ npm init adonisjs@latest Heure ProDev - Jaime Arias | 9 of 50
  5. Installation AdonisJS _ _ _ _ ____ / \ __|

    | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project › api Heure ProDev - Jaime Arias | 10 of 50
  6. Installation AdonisJS ❯ Which starter kit would you like to

    use … Press <ENTER> to select Slim Starter Kit: A lean AdonisJS application with just the framework core _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api Web Starter Kit: Everything you need to build a server render app API Starter Kit: AdonisJS app tailored for creating JSON APIs Inertia Starter: Kit Inertia app with a frontend framework of your choice Heure ProDev - Jaime Arias | 10 of 50
  7. Installation AdonisJS ❯ Which starter kit would you like to

    use … Press <ENTER> to select Web Starter Kit: Everything you need to build a server render app _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api Slim Starter Kit: A lean AdonisJS application with just the framework core API Starter Kit: AdonisJS app tailored for creating JSON APIs Inertia Starter: Kit Inertia app with a frontend framework of your choice Heure ProDev - Jaime Arias | 10 of 50
  8. Installation AdonisJS ❯ Which starter kit would you like to

    use … Press <ENTER> to select API Starter Kit: AdonisJS app tailored for creating JSON APIs _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api Slim Starter Kit: A lean AdonisJS application with just the framework core Web Starter Kit: Everything you need to build a server render app Inertia Starter: Kit Inertia app with a frontend framework of your choice Heure ProDev - Jaime Arias | 10 of 50
  9. Installation AdonisJS ❯ Which starter kit would you like to

    use … Press <ENTER> to select Inertia Starter: Kit Inertia app with a frontend framework of your choice _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api Slim Starter Kit: A lean AdonisJS application with just the framework core Web Starter Kit: Everything you need to build a server render app API Starter Kit: AdonisJS app tailored for creating JSON APIs Heure ProDev - Jaime Arias | 10 of 50
  10. Installation AdonisJS ❯ Which authentication guard you want to use

    … Press <ENTER> to select Session: Authenticate users using cookies and session _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit Access Token: Authenticate clients using API tokens Basic Auth: Authenticate users using HTTP Basic Auth Skip: I want to configure the Auth package manually Heure ProDev - Jaime Arias | 10 of 50
  11. Installation AdonisJS ❯ Which authentication guard you want to use

    … Press <ENTER> to select Access Token: Authenticate clients using API tokens _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit Session: Authenticate users using cookies and session Basic Auth: Authenticate users using HTTP Basic Auth Skip: I want to configure the Auth package manually Heure ProDev - Jaime Arias | 10 of 50
  12. Installation AdonisJS ❯ Which authentication guard you want to use

    … Press <ENTER> to select Basic Auth: Authenticate users using HTTP Basic Auth _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit Session: Authenticate users using cookies and session Access Token: Authenticate clients using API tokens Skip: I want to configure the Auth package manually Heure ProDev - Jaime Arias | 10 of 50
  13. Installation AdonisJS ❯ Which authentication guard you want to use

    … Press <ENTER> to select Skip: I want to configure the Auth package manually _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit Session: Authenticate users using cookies and session Access Token: Authenticate clients using API tokens Basic Auth: Authenticate users using HTTP Basic Auth Heure ProDev - Jaime Arias | 10 of 50
  14. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select SQLite _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens LibSQL MySQL PostgreSQL MS SQL Skip I want to configure Lucid manually Heure ProDev - Jaime Arias | 10 of 50
  15. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select LibSQL _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens SQLite MySQL PostgreSQL MS SQL Skip I want to configure Lucid manually Heure ProDev - Jaime Arias | 10 of 50
  16. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select MySQL _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens SQLite LibSQL PostgreSQL MS SQL Skip I want to configure Lucid manually Heure ProDev - Jaime Arias | 10 of 50
  17. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select PostgreSQL _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens SQLite LibSQL MySQL MS SQL Skip I want to configure Lucid manually Heure ProDev - Jaime Arias | 10 of 50
  18. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select MS SQL _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens SQLite LibSQL MySQL PostgreSQL Skip I want to configure Lucid manually Heure ProDev - Jaime Arias | 10 of 50
  19. Installation AdonisJS ❯ Which database driver you want to use

    … Press <ENTER> to select Skip I want to configure Lucid manually _ _ _ _ ____ / \ __| | ___ _ __ (_)___ | / ___| / _ \ / _` |/ _ \| '_ \| / __|_ | \___ \ / ___ \ (_| | (_) | | | | \__ \ |_| |___) | /_/ \_\__,_|\___/|_| |_|_|___/\___/|____/ ❯ Where should we create your new project · api ❯ Which starter kit would you like to use · API Starter Kit ❯ Which authentication guard you want to use · access_tokens SQLite LibSQL MySQL PostgreSQL MS SQL Heure ProDev - Jaime Arias | 10 of 50
  20. Installation AdonisJS ❯ Download starter kit (511 ms) ❯ Install

    packages (17 s) ❯ Prepare application (376 ms) ❯ Configure Lucid (4 s) Lucid configured to use "postgres" database ❯ Configure Auth (1.15 s) Auth configured to use "access_tokens" guard ╭──────────────────────────────────────────────────────────────────╮ │ Your AdonisJS project has been created successfully! │ │──────────────────────────────────────────────────────────────────│ │ │ │ ❯ cd api │ │ ❯ npm run dev │ │ ❯ Open http://localhost:3333 │ │ ❯ │ │ ❯ Have any questions? │ │ ❯ Join our Discord server - https://discord.gg/vDcEjq6 │ │ │ ╰──────────────────────────────────────────────────────────────────╯ Heure ProDev - Jaime Arias | 10 of 50
  21. Installation AdonisJS ❯ npm run dev [ info ] starting

    HTTP server... ╭─────────────────────────────────────────────────╮ │ │ │ Server address: http://localhost:3333 │ │ Watch Mode: HMR │ │ Ready in: 257 ms │ │ │ ╰─────────────────────────────────────────────────╯ [13:46:54.747] INFO (98807): started HTTP server on localhost:3333 ❯ curl http://localhost:3333/ {"hello":"world"} Heure ProDev - Jaime Arias | 11 of 50
  22. Installation IDE Support The recommended IDE setup is VS Code

    + the AdonisJS Extension extension AdonisJS Extension jripouteau | 46,095 installs | (14) | Free | Sponsor The official VSCode extension of AdonisJS Install Trouble Installing? Heure ProDev - Jaime Arias | 12 of 50
  23. Installation IDE Support Japa Extension jripouteau | 14,930 installs |

    (6) | Free | Sponsor The VSCode extension for Japa Install Trouble Installing? Edge templates syntax highlighter AdonisJS adonisjs.com/ | 18,344 installs | (3) | Free Official Edge template engine extension for VSCode Install Trouble Installing? Heure ProDev - Jaime Arias | 13 of 50
  24. Installation Plugins https://packages.adonisjs.com/ Curated list of projects, featuring packages recommended

    by the official team and enriched by contributions from a vibrant community Heure ProDev - Jaime Arias | 14 of 50
  25. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command Available commands: add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  26. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: add Install and configure a package Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  27. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: build Build application for production by compiling frontend assets and TypeScript source to JavaScript Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  28. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: configure Configure a package after it has been installed Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  29. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: eject Eject scaffolding stubs to your application root Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  30. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: list View list of available commands Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  31. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: repl Start a new REPL session Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands serve Start the development HTTP server along with the file watcher to perform restarts on file change test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  32. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: serve Start the development HTTP server along with the file watcher to perform restarts on file change Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session test Run tests along with the file watcher to re-run tests on file change Heure ProDev - Jaime Arias | 16 of 50
  33. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace Available commands: test Run tests along with the file watcher to re-run tests on file change Options: --ansi|--no-ansi Force enable or disable colorful output --help View help for a given command add Install and configure a package build Build application for production by compiling frontend assets and TypeScript source to JavaScript configure Configure a package after it has been installed eject Eject scaffolding stubs to your application root list View list of available commands repl Start a new REPL session serve Start the development HTTP server along with the file watcher to perform restarts on file change Heure ProDev - Jaime Arias | 16 of 50
  34. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace db db:seed Execute database seeders db:truncate Truncate all tables in database db:wipe Drop all tables, views and types in database Heure ProDev - Jaime Arias | 16 of 50
  35. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace env env:add Add a new environment variable Heure ProDev - Jaime Arias | 16 of 50
  36. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace generate generate:key Generate a cryptographically secure random application key Heure ProDev - Jaime Arias | 16 of 50
  37. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace inspect inspect:rcfile Inspect the RC file with its default values Heure ProDev - Jaime Arias | 16 of 50
  38. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace list list:routes List application routes. Heure ProDev - Jaime Arias | 16 of 50
  39. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace make make:command Create a new ace command class make:controller Create a new HTTP controller class make:event Create a new event class make:exception Create a new custom exception class make:factory Make a new factory make:listener Create a new event listener class make:middleware Create a new middleware class for HTTP requests make:migration Make a new migration file make:model Make a new Lucid model make:preload Create a new preload file inside the start directory make:provider Create a new service provider class make:seeder Make a new Seeder file make:service Create a new service class make:test Create a new Japa test file Heure ProDev - Jaime Arias | 16 of 50
  40. Ace CLI What is Ace? Ace is a command line

    framework used by AdonisJS to create and run console commands. ❯ node ace migration migration:fresh Drop all tables and re-migrate the database migration:refresh Rollback and migrate database migration:reset Rollback all migrations migration:rollback Rollback migrations to a specific batch number migration:run Migrate database by running pending migrations migration:status View migrations status Heure ProDev - Jaime Arias | 16 of 50
  41. Routing Routing In AdonisJS, routes are defined inside the start/routes.ts

    file. 1 import router from '@adonisjs/core/services/router' 2 3 router.get('/', async () => { 4 return { message: 'Hello world from the home page.' } 5 }) 6 7 router.get('/about', async () => { 8 return { message: 'This is the about page.' } 9 }) 10 11 router.get('/posts/:id', async ({ params }) => { 12 return { message: `This is post with id ${params.id}` } 13 }) Heure ProDev - Jaime Arias | 17 of 50
  42. Routing Routing In AdonisJS, routes are defined inside the start/routes.ts

    file. 3 router.get('/', async () => { 4 return { message: 'Hello world from the home page.' } 5 }) 1 import router from '@adonisjs/core/services/router' 2 6 7 router.get('/about', async () => { 8 return { message: 'This is the about page.' } 9 }) 10 11 router.get('/posts/:id', async ({ params }) => { 12 return { message: `This is post with id ${params.id}` } 13 }) Heure ProDev - Jaime Arias | 17 of 50
  43. Routing Routing In AdonisJS, routes are defined inside the start/routes.ts

    file. 7 router.get('/about', async () => { 8 return { message: 'This is the about page.' } 9 }) 1 import router from '@adonisjs/core/services/router' 2 3 router.get('/', async () => { 4 return { message: 'Hello world from the home page.' } 5 }) 6 10 11 router.get('/posts/:id', async ({ params }) => { 12 return { message: `This is post with id ${params.id}` } 13 }) Heure ProDev - Jaime Arias | 17 of 50
  44. Routing Routing In AdonisJS, routes are defined inside the start/routes.ts

    file. 11 router.get('/posts/:id', async ({ params }) => { 12 return { message: `This is post with id ${params.id}` } 13 }) 1 import router from '@adonisjs/core/services/router' 2 3 router.get('/', async () => { 4 return { message: 'Hello world from the home page.' } 5 }) 6 7 router.get('/about', async () => { 8 return { message: 'This is the about page.' } 9 }) 10 Heure ProDev - Jaime Arias | 17 of 50
  45. Routing Routing You can run the list:routes command to view

    the list of routes registered by your application. ❯ node ace list:routes METHOD ROUTE ............................................ HANDLER MIDDLEWARE GET / ................................................ closure GET /about ........................................... closure GET /posts/:id ....................................... closure Heure ProDev - Jaime Arias | 18 of 50
  46. Routing Routing You can run the list:routes command to view

    the list of routes registered by your application. You can register routes for different HTTP methods. ❯ node ace list:routes METHOD ROUTE ............................................ HANDLER MIDDLEWARE GET / ................................................ closure GET /about ........................................... closure GET /posts/:id ....................................... closure 1 router.get('users', () => {}) // GET method 2 router.post('users', () => {}) // POST method 3 router.put('users/:id', () => {}) // PUT method 4 router.patch('users/:id', () => {}) // PATCH method 5 router.delete('users/:id', () => {}) // DELETE method Heure ProDev - Jaime Arias | 18 of 50
  47. Routing Routing You can assign a unique, memorable name to

    a route. 1 router.get('users', () => {}).as('users.index') 2 3 router.post('users', () => {}).as('users.store') 4 5 router.delete('users/:id', () => {}).as('users.delete') Heure ProDev - Jaime Arias | 19 of 50
  48. Routing Routing You can assign a unique, memorable name to

    a route. You can create a group of routes. The URI pattern of routes inside a group can be prefixed. 1 router.get('users', () => {}).as('users.index') 2 3 router.post('users', () => {}).as('users.store') 4 5 router.delete('users/:id', () => {}).as('users.delete') 1 router 2 .group(() => { 3 router.get('users', () => {}) 4 router.get('payments', () => {}) 5 }) 6 .prefix('/api') Heure ProDev - Jaime Arias | 19 of 50
  49. Controllers Controllers HTTP controllers offer an abstraction layer to organize

    the route handlers inside dedicated files. Heure ProDev - Jaime Arias | 20 of 50
  50. Controllers Controllers HTTP controllers offer an abstraction layer to organize

    the route handlers inside dedicated files. You can create a new controller by running the following command. ❯ node ace make:controller users DONE: create app/controllers/users_controller.ts Heure ProDev - Jaime Arias | 20 of 50
  51. Controllers Controllers HTTP controllers offer an abstraction layer to organize

    the route handlers inside dedicated files. You can create a new controller by running the following command. The controllers are stored within the ./app/controllers directory. ❯ node ace make:controller users DONE: create app/controllers/users_controller.ts 1 export default class UsersController { 2 index() { 3 return [ 4 { id: 1, username: 'arias' }, 5 { id: 2, username: 'daian' }, 6 ] 7 } 8 } Heure ProDev - Jaime Arias | 20 of 50
  52. Controllers Controllers We can import the controller using the #controllers

    alias. // start/routes.ts import router from '@adonisjs/core/services/router' router.get('users', () => {}).as('users.index') 1 2 3 4 Heure ProDev - Jaime Arias | 21 of 50
  53. Controllers Controllers We can import the controller using the #controllers

    alias. // start/routes.ts import router from '@adonisjs/core/services/router' const UsersController = () => import('#controllers/users_controller') router.get('users', () => {}).as('users.index') 1 2 3 4 5 Heure ProDev - Jaime Arias | 21 of 50
  54. Controllers Controllers We can import the controller using the #controllers

    alias. // start/routes.ts import router from '@adonisjs/core/services/router' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']).as('users.index') 1 2 3 4 5 Heure ProDev - Jaime Arias | 21 of 50
  55. Controllers Controllers We can import the controller using the #controllers

    alias. // start/routes.ts import router from '@adonisjs/core/services/router' router.get('users', '#controllers/users_controller.index').as('users.index') 1 2 3 4 Heure ProDev - Jaime Arias | 21 of 50
  56. Controllers Controllers We can import the controller using the #controllers

    alias. // start/routes.ts import router from '@adonisjs/core/services/router' router.get('users', '#controllers/users_controller.index').as('users.index') 1 2 3 4 ❯ curl http://localhost:3333/users [{"id":1,"username":"arias"},{"id":2,"username":"daian"}] Heure ProDev - Jaime Arias | 21 of 50
  57. Middleware Middleware A middleware is a function that is executed

    before the route handler during an HTTP request. Heure ProDev - Jaime Arias | 22 of 50
  58. Middleware Middleware A middleware is a function that is executed

    before the route handler during an HTTP request. Middlewares can be chained — each one may handle or forward the request. Heure ProDev - Jaime Arias | 22 of 50
  59. Middleware Middleware A middleware is a function that is executed

    before the route handler during an HTTP request. Middlewares can be chained — each one may handle or forward the request. https://docs.adonisjs.com/guides/basics/middleware Heure ProDev - Jaime Arias | 22 of 50
  60. Middleware Middleware AdonisJS split the middleware stack into following three

    groups: Server middleware stack: it runs on every HTTP request, even if you have not defined any route for the current request’s URL. Heure ProDev - Jaime Arias | 23 of 50
  61. Middleware Middleware AdonisJS split the middleware stack into following three

    groups: Server middleware stack: it runs on every HTTP request, even if you have not defined any route for the current request’s URL. Router middleware stack: they are executed on every HTTP request that has a matching route. Heure ProDev - Jaime Arias | 23 of 50
  62. Middleware Middleware AdonisJS split the middleware stack into following three

    groups: Server middleware stack: it runs on every HTTP request, even if you have not defined any route for the current request’s URL. Router middleware stack: they are executed on every HTTP request that has a matching route. Named middleware collection: it’s a collection of middleware that are not executed unless explicitly assigned to a route or a group Heure ProDev - Jaime Arias | 23 of 50
  63. Middleware Middleware A middleware can be created with the make:middleware

    command ❯ node ace make:middleware user_location Heure ProDev - Jaime Arias | 24 of 50
  64. Middleware Middleware A middleware can be created with the make:middleware

    command ❯ Under which stack you want to register the middleware? … Press <ENTER> to select server router named ❯ node ace make:middleware user_location Heure ProDev - Jaime Arias | 24 of 50
  65. Middleware Middleware A middleware can be created with the make:middleware

    command ❯ Under which stack you want to register the middleware? · named DONE: create app/middleware/user_location_middleware.ts DONE: update start/kernel.ts file ❯ node ace make:middleware user_location Heure ProDev - Jaime Arias | 24 of 50
  66. Middleware Middleware A middleware can be created with the make:middleware

    command Middlewares are stored within the ./app/middleware directory ❯ node ace make:middleware user_location ❯ Under which stack you want to register the middleware? · named DONE: create app/middleware/user_location_middleware.ts DONE: update start/kernel.ts file 1 // app/middleware/user_location_middleware.ts 2 import type { HttpContext } from '@adonisjs/core/http' 3 import type { NextFn } from '@adonisjs/core/types/http' 4 5 export default class UserLocationMiddleware { 6 async handle(ctx: HttpContext, next: NextFn) { 7 /* Middleware logic goes here (before the next call) */ 8 console.log(ctx) 9 10 /* Call next method in the pipeline */ 11 await next() Heure ProDev - Jaime Arias | 24 of 50
  67. Middleware Middleware Middleware can be applied either as an array

    or by calling the use method multiple times. import router from '@adonisjs/core/services/router' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) .as('users.index') 1 2 3 4 5 6 Heure ProDev - Jaime Arias | 25 of 50
  68. Middleware Middleware Middleware can be applied either as an array

    or by calling the use method multiple times. import router from '@adonisjs/core/services/router' import { middleware } from '#start/kernel' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) .use(middleware.userLocation()) .as('users.index') 1 2 3 4 5 6 7 8 Heure ProDev - Jaime Arias | 25 of 50
  69. Validation Validation vinejs/vine One of the fastest validation library for

    Node.js 15 Contributors 8 Issues 1.2k Stars 29 Forks Heure ProDev - Jaime Arias | 26 of 50
  70. Validation Validation AdonisJS does not technically force you to use

    VineJS . vinejs/vine One of the fastest validation library for Node.js 15 Contributors 8 Issues 1.2k Stars 29 Forks Heure ProDev - Jaime Arias | 26 of 50
  71. Validation Validation The data validation is usually performed at the

    controller level. VineJS uses the concept of validators : you create one validator for each action your application can perform. Heure ProDev - Jaime Arias | 28 of 50
  72. Validation Validation The data validation is usually performed at the

    controller level. VineJS uses the concept of validators : you create one validator for each action your application can perform. You can create a new validator by running the following command: ❯ node ace make:validator user DONE: create app/validators/user.ts Heure ProDev - Jaime Arias | 28 of 50
  73. Validation Validation The data validation is usually performed at the

    controller level. VineJS uses the concept of validators : you create one validator for each action your application can perform. You can create a new validator by running the following command: The validators are created inside the app/validators directory. ❯ node ace make:validator user DONE: create app/validators/user.ts Heure ProDev - Jaime Arias | 28 of 50
  74. Validation Validation Each validator is a const variable holding the

    result of vine.compile method. 1 import vine from '@vinejs/vine' 2 3 /** 4 * Validates user's creation action 5 */ 6 export const createUserValidator = vine.compile( 7 vine.object({ 8 username: vine.string().trim().minLength(3).maxLength(10), 9 email: vine.string().trim().email(), 10 password: vine.string().trim().minLength(8), 11 }) 12 ) Heure ProDev - Jaime Arias | 29 of 50
  75. Validation Validation You can access the request body using the

    request.all() method. // app/controllers/users_controller.ts import type { HttpContext } from '@adonisjs/core/http' export default class UsersController { index() { /* ... */ } async store({ request }: HttpContext) { const data = request.all() return data } } 1 2 3 4 5 6 7 8 9 10 11 Heure ProDev - Jaime Arias | 30 of 50
  76. Validation Validation You can access the request body using the

    request.all() method. // app/controllers/users_controller.ts import type { HttpContext } from '@adonisjs/core/http' import { createUserValidator } from '#validators/user' export default class UsersController { index() { /* ... */ } async store({ request }: HttpContext) { const data = request.all() const payload = await createUserValidator.validate(data) return payload } } 1 2 3 4 5 6 7 8 9 10 11 12 13 Heure ProDev - Jaime Arias | 30 of 50
  77. Validation Validation You can access the request body using the

    request.all() method. // app/controllers/users_controller.ts import type { HttpContext } from '@adonisjs/core/http' import { createUserValidator } from '#validators/user' export default class UsersController { index() { /* ... */ } async store({ request }: HttpContext) { const payload = await request.validateUsing(createUserValidator) return payload } } 1 2 3 4 5 6 7 8 9 10 11 12 Heure ProDev - Jaime Arias | 30 of 50
  78. Validation Validation You can access the request body using the

    request.all() method. // app/controllers/users_controller.ts import type { HttpContext } from '@adonisjs/core/http' import { createUserValidator } from '#validators/user' export default class UsersController { index() { /* ... */ } async store({ request }: HttpContext) { const payload = await request.validateUsing(createUserValidator) return payload } } 1 2 3 4 5 6 7 8 9 10 11 12 1 // start/routes.ts 2 import router from '@adonisjs/core/services/router' 3 const UsersController = () => import('#controllers/users_controller') 4 5 router.get('users', [UsersController, 'index']) 6 router.post('users', [UsersController, 'store']) Heure ProDev - Jaime Arias | 30 of 50
  79. Validation Validation Let’s try it ! ❯ curl -s -X

    POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev" }' | jq Heure ProDev - Jaime Arias | 31 of 50
  80. Validation Validation Let’s try it ! ❯ curl -s -X

    POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev" }' | jq { "errors": [ { "message": "The password field must have at least 8 characters", "rule": "minLength", "field": "password", "meta": { "min": 8 } } Heure ProDev - Jaime Arias | 31 of 50
  81. Validation Validation Let’s try it ! ❯ curl -s -X

    POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev rlz" }' | jq Heure ProDev - Jaime Arias | 31 of 50
  82. Validation Validation Let’s try it ! ❯ curl -s -X

    POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev rlz" }' | jq { "username": "arias", "email": "[email protected]", "password": "prodev rulz!" } Heure ProDev - Jaime Arias | 31 of 50
  83. SQL and ORMs SQL and ORMs The AdonisJS core team

    built the Lucid ORM but does not force you to use it. adonisjs/lucid AdonisJS SQL ORM. Supports PostgreSQL, MySQL, MSSQL, Redshift, SQLite and many more 76 Contributors 21 Issues 1.2k Stars 207 Forks Heure ProDev - Jaime Arias | 33 of 50
  84. SQL and ORMs Lucid You can create a new model

    using the following command: ❯ node ace make:model User SKIPPED: create app/models/user.ts (File already exists) Heure ProDev - Jaime Arias | 34 of 50
  85. SQL and ORMs Lucid You can create a new model

    using the following command: Models are stored within the ./app/models directory ❯ node ace make:model User SKIPPED: create app/models/user.ts (File already exists) 1 import { DateTime } from 'luxon' 2 import { BaseModel, column } from '@adonisjs/lucid/orm' 3 4 export default class User extends BaseModel { 5 @column({ isPrimary: true }) 6 declare id: number 7 8 @column.dateTime({ autoCreate: true }) 9 declare createdAt: DateTime 10 11 @column.dateTime({ autoCreate: true, autoUpdate: true }) Heure ProDev - Jaime Arias | 34 of 50
  86. SQL and ORMs Migrations Migrations are a way to modify

    the database schema and data using incremental changesets. Heure ProDev - Jaime Arias | 35 of 50
  87. SQL and ORMs Migrations Migrations are a way to modify

    the database schema and data using incremental changesets. You can create a new migration using the following command. ❯ node ace make:migration users DONE: create database/migrations/1762377170235_create_users_table.ts Heure ProDev - Jaime Arias | 35 of 50
  88. SQL and ORMs Migrations Migrations are created inside the database/migrations

    directory. 1 import { BaseSchema } from '@adonisjs/lucid/schema' 2 3 export default class extends BaseSchema { 4 protected tableName = 'users' 5 6 async up() { 7 this.schema.createTable(this.tableName, (table) => { 8 table.increments('id') 9 10 table.timestamp('created_at') 11 table.timestamp('updated_at') 12 }) 13 } 14 15 async down() { 16 this.schema.dropTable(this.tableName) 17 } 18 } Heure ProDev - Jaime Arias | 36 of 50
  89. SQL and ORMs Migrations You can run all the pending

    migrations using the following command. ❯ node ace migration:run [ info ] Upgrading migrations version from "1" to "2" ❯ migrated database/migrations/1762349794119_create_users_table Migrated in 151 ms Heure ProDev - Jaime Arias | 37 of 50
  90. SQL and ORMs Migrations You can run all the pending

    migrations using the following command. ❯ node ace migration:run [ info ] Upgrading migrations version from "1" to "2" ❯ migrated database/migrations/1762349794119_create_users_table Migrated in 151 ms Heure ProDev - Jaime Arias | 37 of 50
  91. SQL and ORMs Migrations You can run all the pending

    migrations using the following command. The database must exist before running migrations. AdonisJS only creates tables, not the database itself. ❯ node ace migration:run [ info ] Upgrading migrations version from "1" to "2" ❯ migrated database/migrations/1762349794119_create_users_table Migrated in 151 ms Heure ProDev - Jaime Arias | 37 of 50
  92. SQL and ORMs CRUD Operations Lucid models have built-in methods

    to perform CRUD operations on the database. import User from '#models/user' /** * Create a new user */ const user = await User.create({ username: 'arias', email: '[email protected]', password: 'prodev rulz' }) 1 2 3 4 5 6 7 8 9 10 Heure ProDev - Jaime Arias | 38 of 50
  93. SQL and ORMs CRUD Operations Lucid models have built-in methods

    to perform CRUD operations on the database. import User from '#models/user' /** * Find all users */ const users = await User.all() 1 2 3 4 5 6 Heure ProDev - Jaime Arias | 38 of 50
  94. SQL and ORMs CRUD Operations Lucid models have built-in methods

    to perform CRUD operations on the database. import User from '#models/user' /** * Find a user by primary key */ const user = await User.find(1) 1 2 3 4 5 6 Heure ProDev - Jaime Arias | 38 of 50
  95. SQL and ORMs CRUD Operations Lucid models have built-in methods

    to perform CRUD operations on the database. import User from '#models/user' /** * Update a user */ const user = await User.find(1) user.username = 'jaime.arias' await user.save() 1 2 3 4 5 6 7 8 Heure ProDev - Jaime Arias | 38 of 50
  96. SQL and ORMs CRUD Operations Lucid models have built-in methods

    to perform CRUD operations on the database. import User from '#models/user' /** * Delete a user */ const user = await User.find(1) await user.delete() 1 2 3 4 5 6 7 Heure ProDev - Jaime Arias | 38 of 50
  97. SQL and ORMs CRUD Operations Let’s try it // app/controllers/users_controller.ts

    import type { HttpContext } from '@adonisjs/core/http' import { createUserValidator } from '#validators/user' export default class UsersController { index() { return [ { id: 1, username: 'arias' }, { id: 2, username: 'daian' }, ] } async store({ request }: HttpContext) { const payload = await request.validateUsing(createUserValidator) return payload } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Heure ProDev - Jaime Arias | 39 of 50
  98. SQL and ORMs CRUD Operations Let’s try it index() {

    return [ { id: 1, username: 'arias' }, { id: 2, username: 'daian' }, ] } 1 // app/controllers/users_controller.ts 2 import type { HttpContext } from '@adonisjs/core/http' 3 import { createUserValidator } from '#validators/user' 4 5 export default class UsersController { 6 7 8 9 10 11 12 13 async store({ request }: HttpContext) { 14 const payload = await request.validateUsing(createUserValidator) 15 return payload 16 } 17 } Heure ProDev - Jaime Arias | 39 of 50
  99. SQL and ORMs CRUD Operations Let’s try it import User

    from '#models/user' async index() { const users = await User.all() return users } 1 // app/controllers/users_controller.ts 2 import type { HttpContext } from '@adonisjs/core/http' 3 import { createUserValidator } from '#validators/user' 4 5 6 export default class UsersController { 7 8 9 10 11 12 async store({ request }: HttpContext) { 13 const payload = await request.validateUsing(createUserValidator) 14 return payload 15 } 16 } Heure ProDev - Jaime Arias | 39 of 50
  100. SQL and ORMs CRUD Operations Let’s try it async store({

    request }: HttpContext) { const payload = await request.validateUsing(createUserValidator) return payload } 1 // app/controllers/users_controller.ts 2 import type { HttpContext } from '@adonisjs/core/http' 3 import { createUserValidator } from '#validators/user' 4 import User from '#models/user' 5 6 export default class UsersController { 7 async index() { 8 const users = await User.all() 9 return users 10 } 11 12 13 14 15 16 } Heure ProDev - Jaime Arias | 39 of 50
  101. SQL and ORMs CRUD Operations Let’s try it async store({

    request }: HttpContext) { const payload = await request.validateUsing(createUserValidator) const user = await User.create(payload) return user } 1 // app/controllers/users_controller.ts 2 import type { HttpContext } from '@adonisjs/core/http' 3 import { createUserValidator } from '#validators/user' 4 import User from '#models/user' 5 6 export default class UsersController { 7 async index() { 8 const users = await User.all() 9 return users 10 } 11 12 13 14 15 16 17 } Heure ProDev - Jaime Arias | 39 of 50
  102. SQL and ORMs CRUD Operations Let’s try it ❯ curl

    -s -X POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev rulz!" }' | jq Heure ProDev - Jaime Arias | 40 of 50
  103. SQL and ORMs CRUD Operations Let’s try it ❯ curl

    -s -X POST http://localhost:3333/users \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "email": "[email protected]", "password": "prodev rulz!" }' | jq { "username": "arias", "email": "[email protected]", "createdAt": "2025-11-05T21:42:32.745+00:00", "updatedAt": "2025-11-05T21:42:32.745+00:00", "id": 1 } Heure ProDev - Jaime Arias | 40 of 50
  104. SQL and ORMs CRUD Operations Let’s try it ❯ curl

    -s http://localhost:3333/users | jq Heure ProDev - Jaime Arias | 40 of 50
  105. SQL and ORMs CRUD Operations Let’s try it ❯ curl

    -s http://localhost:3333/users | jq [ { "id": 1, "username": "arias", "email": "[email protected]", "createdAt": "2025-11-05T21:42:32.745+00:00", "updatedAt": "2025-11-05T21:42:32.745+00:00" } ] Heure ProDev - Jaime Arias | 40 of 50
  106. Authentication Authentication AdonisJS ships with a robust and secure authentication

    system. The authentication package is built around guards and providers. Guards are end-to-end implementations of a specific login type (e.g., sessions, cookies, tokens, etc.). Providers are used to look up users and tokens from a database. You can build your authentication guards for custom requirements. Heure ProDev - Jaime Arias | 42 of 50
  107. Authentication Authentication The following are inbuilt authentication guards. Guard How

    it Works Session Tracks logged-in user via cookies and session store Access Token Issues secure random tokens after login; client stores and sends them for authentication Basic Auth Sends Base64-encoded credentials in the Authorization header on each request You can implement social authentication ( @adonisjs/ally package). Heure ProDev - Jaime Arias | 43 of 50
  108. Authentication Verifying user credentials Secure APIs are provided to find

    users and verify their passwords It’s possible to implement additional ways to verify a user (e.g., 2FA) The authentication guards are defined inside the config/auth.ts file import type { HttpContext } from '@adonisjs/core/http' export default class AuthController { async store({ request }: HttpContext) { } } 1 2 3 4 5 6 7 Heure ProDev - Jaime Arias | 44 of 50
  109. Authentication Verifying user credentials Secure APIs are provided to find

    users and verify their passwords It’s possible to implement additional ways to verify a user (e.g., 2FA) The authentication guards are defined inside the config/auth.ts file import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' export default class AuthController { async store({ request }: HttpContext) { /** * Step 1: Get credentials from the request body */ const { username, password } = await request.validateUsing(loginValidator) } } 1 2 3 4 5 6 7 8 9 10 11 Heure ProDev - Jaime Arias | 44 of 50
  110. Authentication Verifying user credentials Secure APIs are provided to find

    users and verify their passwords It’s possible to implement additional ways to verify a user (e.g., 2FA) The authentication guards are defined inside the config/auth.ts file import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' import User from '#models/user' export default class AuthController { async store({ request }: HttpContext) { const { username, password } = await request.validateUsing(loginValidator) /** * Step 2: Verify credentials */ const user = await User.verifyCredentials(username, password) } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Heure ProDev - Jaime Arias | 44 of 50
  111. Authentication Verifying user credentials Secure APIs are provided to find

    users and verify their passwords It’s possible to implement additional ways to verify a user (e.g., 2FA) The authentication guards are defined inside the config/auth.ts file import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' import User from '#models/user' export default class AuthController { async store({ request, auth }: HttpContext) { const { username, password } = await request.validateUsing(loginValidator) const user = await User.verifyCredentials(username, password) /** * Step 3: Return access token */ return await auth.use('api').createToken(user) 1 2 3 4 5 6 7 8 9 10 11 12 13 Heure ProDev - Jaime Arias | 44 of 50
  112. Authentication Protecting routes Apply the auth middleware to the routes

    you want to protect from unauthenticated users. import router from '@adonisjs/core/services/router' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) 1 2 3 4 5 Heure ProDev - Jaime Arias | 45 of 50
  113. Authentication Protecting routes Apply the auth middleware to the routes

    you want to protect from unauthenticated users. import router from '@adonisjs/core/services/router' import { middleware } from '#start/kernel' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) .use(middleware.auth()) 1 2 3 4 5 6 7 Heure ProDev - Jaime Arias | 45 of 50
  114. Authentication Protecting routes Apply the auth middleware to the routes

    you want to protect from unauthenticated users. import router from '@adonisjs/core/services/router' import { middleware } from '#start/kernel' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) .use(middleware.auth()) router.post('users', [UsersController, 'store']).as('users.store') 1 2 3 4 5 6 7 8 9 Heure ProDev - Jaime Arias | 45 of 50
  115. Authentication Protecting routes Apply the auth middleware to the routes

    you want to protect from unauthenticated users. import router from '@adonisjs/core/services/router' import { middleware } from '#start/kernel' const UsersController = () => import('#controllers/users_controller') router.get('users', [UsersController, 'index']) .use(middleware.auth()) router.post('users', [UsersController, 'store']).as('users.store') router.post('login', [AuthController, 'store']).as('auth.login') 1 2 3 4 5 6 7 8 9 10 11 Heure ProDev - Jaime Arias | 45 of 50
  116. Authentication Protecting routes Let’s try ❯ curl -s http://localhost:3333/users |

    jq { "errors": [ { "message": "Unauthorized access" } ] } Heure ProDev - Jaime Arias | 46 of 50
  117. Authentication Protecting routes Let’s try ❯ curl -s -X POST

    http://localhost:3333/login \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "password": "prodev rulz!" }' Heure ProDev - Jaime Arias | 46 of 50
  118. Authentication Protecting routes Let’s try ❯ curl -s -X POST

    http://localhost:3333/login \ -H "Content-Type: application/json" \ -d '{ "username": "arias", "password": "prodev rulz!" }' { "type": "bearer", "name": null, "token": "oat_Mw.Wm0wMUdpUm9YcUNFWTk4V01NZGhLRjFfTC1HYnc0R1I3ZDFXS0ROcDM4MTIzNzc2NDU", "abilities": [ "*" ], "lastUsedAt": null, "expiresAt": null } Heure ProDev - Jaime Arias | 46 of 50
  119. Authentication Protecting routes Let’s try ❯ curl -s http://localhost:3333/users \

    -H "Authorization: Bearer <TOKEN>" | jq [ { "id": 1, "username": "arias", "email": "[email protected]", "createdAt": "2025-11-06T09:40:39.096+00:00", "updatedAt": "2025-11-06T09:40:39.096+00:00" } ] Heure ProDev - Jaime Arias | 46 of 50
  120. Authentication Logout Logging out (the currently authenticated token): // app/controllers/auth_controller.ts

    import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' import User from '#models/user' export default class AuthController { async store({ request, auth }: HttpContext) { /* .. */ } } 1 2 3 4 5 6 7 8 9 Heure ProDev - Jaime Arias | 47 of 50
  121. Authentication Logout Logging out (the currently authenticated token): // app/controllers/auth_controller.ts

    import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' import User from '#models/user' export default class AuthController { async store({ request, auth }: HttpContext) { /* .. */ } async destroy({ auth }: HttpContext) { await auth.use('api').invalidateToken() } } 1 2 3 4 5 6 7 8 9 10 11 12 13 Heure ProDev - Jaime Arias | 47 of 50
  122. Authentication Logout Logging out (the currently authenticated token): // app/controllers/auth_controller.ts

    import type { HttpContext } from '@adonisjs/core/http' import { loginValidator } from '#validators/auth' import User from '#models/user' export default class AuthController { async store({ request, auth }: HttpContext) { /* .. */ } async destroy({ auth }: HttpContext) { await auth.use('api').invalidateToken() } } 1 2 3 4 5 6 7 8 9 10 11 12 13 1 // start/routes.ts 2 3 router.delete('logout', [AuthController, 'destroy']) 4 .use(middleware.auth()) 5 .as('auth.logout') Heure ProDev - Jaime Arias | 47 of 50
  123. Authentication Logout Let’s try it ❯ curl -s -X DELETE

    http://localhost:3333/logout | jq { "errors": [ { "message": "Unauthorized access" } ] } Heure ProDev - Jaime Arias | 48 of 50
  124. Authentication Logout Let’s try it curl -s -X DELETE http://localhost:3333/logout

    \ -H "Authorization: Bearer <TOKEN>" Heure ProDev - Jaime Arias | 48 of 50
  125. Authentication Logout Let’s try it ❯ curl -s http://localhost:3333/users \

    -H "Authorization: Bearer <TOKEN>" | jq { "errors": [ { "message": "Unauthorized access" } ] } Heure ProDev - Jaime Arias | 48 of 50