Looking to migrate your application to AdonisJS 6? Checkout our migration guide!

Updates from March 2024

Harminder Virk

We are entering a new month, so it is time to reflect back and share updates with you from the last month.

Github adds syntax highlighting for Edge templates

Github now recognizes the syntax of Edge templates and provides syntax highlighting for them. This contribution is made by Liam Potter (a long-time AdonisJS user) via this PR.

To enable syntax highlighting, you must set the code block language to edge, as shown in the following example.

Atomic Locks

Julien (from the core team) has created Verrou - A framework agnostic library for managing distributed locks to prevent race conditions.

We provide first-class integration with Verrou via the @adonisjs/lock package. You can store the locks inside an AdonisJS app within a Redis or SQL database, along with the memory store that can be used during testing.

import locks from '@adonisjs/lock/services/main'
/**
* Create a lock instance with a unique key
*/
const lock = locks.createLock(`order.${orderId}.fulfill`)
/**
* Executed the code by wrapping it inside the
* "lock.run" method.
*
* The callback will be executed only when we are
* able to acquire a lock
*/
const [executed, result] = lock.run(async () => {
//Fulfill the order
})
if (executed) {
return result
}
return 'Unable to fulfill order. Try again after some time'

InertiaJS adapter (with SSR)

We have finally taken over the development of the InertiaJS adapter (for AdonisJS). The project is led by Julien Ripouteau, and the first version has been released under the experimental flag.

InertiaJS can become an excellent alternative for projects that use a frontend framework like Vue or React for the application's UI and create a separate JSON API using AdonisJS.

With InertiaJS, you can remove routing and a lot of state management boilerplate from your frontend apps and keep everything within a single codebase.

So, try Inertia with our new integration and share your feedback. After smoothing out certain rough edges, we are looking forward to releasing a stable version soon.

Changes to the Vite integration

To support SSR mode for the InertiaJS application, we need access to Vite APIs within the AdonisJS process to pre-render your React or Vue components on the server and send HTML to the browser.

This requires us to run Vite alongside AdonisJS rather than in a separate process (as we do with the current integration).

We have released this new integration under the experimental flag and are looking for feedback from early adopters. Please give this integration a try and report your issues in the adonisjs/vite repo.

Env identifier

Env identifiers are keywords you can prefix to the value of an environment variable and define value resolution for that keyword. For example, you may create a file identifier that resolves the value from the filesystem.

import { readFile } from 'node:fs/promises'
import { EnvParser } from '@adonisjs/env'
/**
* Define the identifier
*/
EnvParser.identifier('file', (value) => {
return readFile(value, 'utf-8')
})

Once you have defined the identifier, you can prefix the value of an environment variable with the file keyword, and its value will be resolved from the filesystem.

DB_PASSWORD=file:/run/secret/db_password

Quality of life improvements for VineJS

We recently added support for conditional validation in VineJS via the requiredIf rules. These rules serve as an alternative to the existing Vine.union schema type. The requiredIf rules offer a terse API at the cost of a less type-safe API.

In the following example, the firstName and the lastName fields are optional. However, if one is provided, the other should also be required.

vine.object({
firstName: vine
.string()
.optional()
.requiredIfExists('lastName'),
lastName: vine
.string()
.optional()
.requiredIfExists('firstName'),
})

Improved error reporting for fields inside arrays

In the previous versions of VineJS, the errors for fields inside an array used wildcard identifier (*) for the nested field path. For example:

// Old output
[
{
field: 'categories.*',
index: 1,
message: 'The 1 field must be a number',
rule: 'number',
},
{
field: 'categories.*',
index: 2,
message: 'The 2 field must be a number',
rule: 'number',
}
]

However, starting from @vinejs/vine@2, the value of the field property contains the index of the array element for which the validation has failed.

// New output
[
{
field: 'categories.1',
index: 1,
message: 'The 1 field must be a number',
rule: 'number',
},
{
field: 'categories.2',
index: 2,
message: 'The 2 field must be a number',
rule: 'number',
}
]

Notable Releases