Athenna RC File
Understand what is the purpose of the .athennarc.json file.
Introduction
Inside the root directory of your project, there is a file
called .athennarc.json
which is responsible for configuring
the workspace and certain runtime settings of your Athenna
application.
RC file vs Configurations
The responsible of the .athennarc.json
is configuring the workspace
and certain runtime settings to bootstrap your Athenna
application properly. Also, when working with .json
files is
very easy to manipulate the values of it, making it possible
to make changes on the file in runtime. Let's see an example
where Athenna manipulates your .athennarc.json
:
node artisan make:service UserService
Athenna will create the service file in your project but
also register it inside your .athennarc.json
file:
{
"services": [
"#src/services/UserService"
]
}
Custom RC file path
You can change the name and the path of your RC file or even
create customized ones for each environment (.athennarc.dev.json
,
.athennarc.prod.json
). To do that you need to set the new
path to Ignite::load()
static method:
import { Ignite } from '@athenna/core'
const ignite = await new Ignite().load(import.meta.url, {
athennaRcPath: './bin/athennadevrc.json' 👈
})
await ignite.httpServer()
Always remember that when using relative paths to set something in Athenna, you need to use your project root path as reference, just like in the example above.
Using RC file in package.json
You can also use the RC file inside package.json
. By default,
If you don't specify the path of your RC file, and the default
.athennarc.json
cannot be found in the root path of your application,
Athenna will check if the athenna
property exists in your package.json
:
{
"athenna": {
"providers": [
"@athenna/core/providers/CoreProvider",
"@athenna/http/providers/HttpRouteProvider",
"@athenna/http/providers/HttpServerProvider"
],
"directories": {
"bin": "bootstrap"
}
}
}
RC File properties
Let's cover all of the .athennarc.json
file properties and
understand how to use each one of them:
The preloads
property
An array of files that will be loaded when your application is bootstrapping. The files are loaded after booting the service providers. You can do anything you want in preload files. Check the example bellow:
import { Log } from '@athenna/logger'
import { Config } from '@athenna/core'
Log.info(`Hello from ${Config.get('app.name')} application!`)
{
"preloads": [
"./bin/preloads/say-hello.js"
]
}
The providers
property
An array of service providers to load when the application is bootstrapping:
{
"providers": [
"@athenna/core/providers/CoreProvider",
"@athenna/http/providers/HttpRouteProvider",
"@athenna/http/providers/HttpServerProvider"
]
}
More information about service providers could be found at service providers documentation section.
The services
property
This property is responsible to register your application services or from some library inside the service container. In most cases, it is better to simply instantiate your services, but in others you might have different implementations for some interface, using inversion of control in these cases could be an exceptional idea to register your services in the container:
{
"services": [
"#src/services/AppService",
"./src/services/OtherService.js"
]
}
The commands
property
An object that is responsible to register your application commands and their respective settings. The key of the commands object needs to be exactly your command signature without any arguments, flags or spaces. Also, the value of it could be the command path or an object with the "path" key inside:
{
"commands": {
"make:exception": "@athenna/core/commands/MakeExceptionCommand",
"make:facade": {
"path": "@athenna/core/commands/MakeFacadeCommand",
"env": "local",
"destination": "./src/providers/facades",
"loadApp": false,
"stayAlive": false,
"loadAllCommands": false,
"environments": ["console"]
}
}
}
Depending on the command you are running, it got their
own configurations. Commands like make:...
for example,
reads the destination
property to the file generated
for a different path from it default.
There are properties that you can define whatever your command. Let's see who they are and what they do:
path
- Defines the path to your command, this field is mandatory if you are using an object to define your command.loadApp
- Iftrue
, theIgnite.fire()
method will be called until running your command. TheIgnite.fire()
method is responsible to load your env file and configuration files and also boot your service providers.env
- Defines which env file will be used to run your command. This field is not required and it will only be relevant when theloadApp
property istrue
.stayAlive
- Iftrue
, your command will stay running until the event loop is not in use anymore. Very useful for keep running background tasks from commands.loadAllCommands
- Iftrue
, all the commands inside thecommands
property will be loaded. Useful when you command needs to call other command programmatically.environments
- Only relevant whenloadApp
istrue
. The environments set will be used as parameter forIgnite.fire()
method and will help Athenna to select the service providers that should or shouldn't be booted.
More information about commands could be found at cli commands documentation section.
The templates
property
Map your application commands templates with their respective
path. The templates mapped in this object will be used by your
make
commands to generate the resource with some specific
code template:
{
"templates": {
"exception": "node_modules/@athenna/core/templates/exception.edge",
"facade": "node_modules/@athenna/core/templates/facade.edge"
}
}
The directories
property
Map your application directories with their respective
base path. The Path
class will use the directories mapped in this object to
resolve the paths of your application:
{
"directories": {
"bin": "bin",
"src": "src",
"app": "app",
"bootstrap": "bootstrap",
"public": "public",
"static": "public/static",
"assets": "public/assets",
"nodeModules": "node_modules",
"nodeModulesBin": "node_modules/.bin",
"tests": "tests",
"stubs": "tests/stubs",
"fixtures": "tests/fixtures",
"models": "src/models",
"services": "src/services",
"jobs": "src/jobs",
"workers": "src/workers",
"exceptions": "src/exceptions",
"repositories": "src/repositories",
"console": "src/console",
"commands": "src/console/commands",
"http": "src/http",
"guards": "src/http/guards",
"controllers": "src/http/controllers",
"middlewares": "src/http/middlewares",
"interceptors": "src/http/interceptors",
"terminators": "src/http/terminators",
"validators": "src/validators",
"cron": "src/cron",
"schedulers": "src/cron/schedulers",
"config": "src/config",
"database": "src/database",
"seeders": "src/database/seeders",
"migrations": "src/database/migrations",
"lang": "src/lang",
"resources": "src/resources",
"views": "src/resources/views",
"locales": "src/resources/locales",
"providers": "src/providers",
"facades": "src/facades",
"routes": "src/routes",
"storage": "src/storage",
"logs": "src/storage/logs"
}
}
The paths above are the default ones used by Athenna to resolve
your application paths. You can change one of them or many
if you want, your directories defined in directories
property
will always be merged with the defaults.
Athenna always rely on Path
class methods to find files and directories that are used
internally by the framework, like configuration file, route
files, entry points and many others. Changing the directories
property
could be very useful when you are building your own project structure.
The controllers
property
An array with the controllers of your application. The controllers registered in this array will be registered in the service container to be accessed easily by your Route facade:
{
"controllers": [
"#src/http/controllers/AppController",
"./src/http/controllers/OtherController.js"
]
}
The middlewares
property
An array with the middlewares of your application. The
middlewares registered in this array will be registered
in the service container to be accessed easily by your
Route
facade:
{
"middlewares": [
"#src/http/middlewares/AppMiddleware",
"./src/http/interceptors/AppInterceptor.js"
]
}
Athenna expects that the middlewares set in this property
to be annotated with @Middleware()
, @Interceptor()
or @Terminator()
annotations, this is not mandatory, but you will only
be able to set the name of the middleware or if it is global or not using
the annotations.
If you are not using TypeScript in your application, you can use the
namedMiddlewares
property to register named middlewares and the
globalMiddlewares
property to register global middlewares.
More information about middlewares could be found at http middlewares documentation section.
The namedMiddlewares
property
Map the named middlewares of your application. Named
middlewares could be configured using the @Middleware()
annotation, but if you are not using TypeScript in your
application, you can use this object to map your named
middlewares. Named middlewares are very useful to be used
in your route declaration:
{
"namedMiddlewares": {
"app": "#src/http/middlewares/AppMiddleware",
"intercept": "./src/http/interceptors/AppInterceptor.js"
}
}
The globalMiddlewares
property
An array with the global middlewares of your application.
Global middlewares could be configured using the @Middleware()
annotation, but if you are not using TypeScript in your
application, you can use this object to map your named
middlewares. Global middlewares are executed every time
in any request of your application:
{
"globalMiddlewares": [
"#src/http/middlewares/AppMiddleware",
"./src/http/interceptors/AppInterceptor.js"
]
}
The artisan
property
An object with a variety of Artisan configurations.
At this point the only configurations accepted are artisan.child.executor
and artisan.child.path
. Both configurations are used to define
how the Artisan.callInChild()
method will behave when no options
are set to it as second argument:
{
"artisan": {
"child": {
"executor": "node --inspect",
"path": "./bin/artisan.ts"
}
}
}
Athenna will automatically parse the artisan.child.path
using
the Path.ext()
method, so you don't need to worry about if the
extension is .js
or .ts
.