Application Server
The FullJS application server provides a robust, modular, and secure foundation for running server-side services. It combines modern architectural principles with deep Linux integration to deliver enterprise-grade capabilitie
Microservice Architecture
The FullJS applications server follows a microservice-based server architecture with deep systemd integration. The application server is represented as a Systemd target ([application].target), with each individual microservice corresponding to a systemd unit instance ([application]@[microservice]).
Adding and Removing Microservices from the Application Server
To add a microservice (a.k.a systemd unit instance) to the application server (a.k.a systemd target):
sudo systemctl enable [application]@[microservice]
To remove a microservice from the application server group:
sudo systemctl disable [application]@[microservice]
Note: Enabling a microservice only registers it with the application server for automatic start at boot. It does **not** start the microservice immediately in the current session.
Starting and Stopping a Microservice
Each microservice runs as a separate systemd unit instance ([application]@[microservice]). To start a microservice:
sudo systemctl start [application]@[microservice]
To stop a microservice:
sudo systemctl stop [application]@[microservice]
Note: starting a microservice only affects the current session and does not configure it to start automatically at boot.
Checking the Status of a Microservice
Each microservice runs as a separate systemd unit instance ([application]@[microservice]).
- To check the current status of a microservice instance:
sudo systemctl status [application]@[microservice]
This command shows whether the service is running, stopped, or failed, along with recent log entries.
Starting and Stopping the application server
To start the application server use systemd’s start command.
sudo systemctl start [application].target
To stop a running application server, you can use:
sudo systemctl stop [application].target
Keep in mind that starting an application server only affects the current session and does not configure it to start automatically at boot.
Enabling and Disabling the application server
To start the application server automatically at boot, you must enable it.
To start the application server at boot:
sudo systemctl enable [application].target
To disable the application service from starting automatically:
sudo systemctl disable [application].target
Keep in mind that enabling an application server does not start it in the current session.
Filesystem Layout
The application conforms to the Linux Filesystem Hierarchy Standard (FHS). Executables, data, runtime state, and configuration are separated cleanly:
/srv/[application]/[microservice]/– contains the deployed application/run/[application]/[microservice]/**– runtime files (e.g., sockets, PID files)/var/lib/[application]/[microservice]/**– persistent state data (e.g., storage files)/etc/[application]/[microservice]/**– configuration files (if any)
Plugin-based architecture
Note: This documentation is not final and may be updated as the architecture evolves.
The plugin-based architecture allows the application server and other modules to be extended and customized by dynamically enabling plugins. Each plugin is a self-contained module and encapsulates a specific functionality, such as HTTP handling, authentication, permission management, systemd integration. This design decouples core module logic from optional features, making it easier to maintain, test, and evolve the system.
How it works:
- Core Server Class: The main Server class provides the infrastructure for running the application and managing plugins.
- Plugin Registration: Plugins are registered via a static method, e.g.,
enablePlugin(pluginClass, options). This allows the server to load specific functionality only when needed. - Static Initialization: A static block in the server class runs once when the class is defined. It is used to register all required plugins. This ensures that the server is fully configured before any instances are created.
import {Server} from "appserver";
import {AppServerPlugin} from "appserver";
import {SystemdPlugin} from "appserver";
import {HttpPlugin} from "appserver";
import {AuthPlugin} from "appserver";
import {PermPlugin} from "appserver";
import {DebugConsolePlugin} from "appserver";
new (class MyServer extends Server {
static {
MyServer.enablePlugin(SystemdPlugin);
MyServer.enablePlugin(HttpPlugin, {port: 8080, endpoint: /^(?!.*\.jss$).*/, slot: "http_slot00"});
MyServer.enablePlugin(AppServerPlugin);
MyServer.enablePlugin(AuthPlugin);
MyServer.enablePlugin(PermPlugin);
MyServer.enablePlugin(DebugConsolePlugin);
}
constructor(...args) {
super(...args);
}
})();
HttpPlugin
Overview
The HttpPlugin extends the core Server class with HTTP capabilities. When this plugin is enabled, the server can listen on a given port and expose REST-like endpoints.
This makes it possible to build fully functional web APIs directly on top of the server, using standard Request and Response handling from the Web API specification.
Enabling the Plugin
To enable the HTTP server functionality, the plugin must be registered in the static block of the server class:
MyServer.enablePlugin(HttpPlugin, {
port: 8080,
endpoint: /^(?!.*\.jss$).*/,
slot: "http_slot00"
});
Parameters
- port – the TCP port where the HTTP server will listen (e.g., 8080).
- endpoint – optional regular expression filter for matching request paths.
- slot – identifier for the HTTP handler slot. This allows multiple independent HTTP bindings if needed.
Decorator-Based Routing
Once the HttpPlugin is enabled, endpoints can be defined directly in the server class using decorators:
@http.get(path)
Declares a GET endpoint for the given path.
- Other HTTP methods (POST, PUT, DELETE, etc.) are also supported in the same decorator style.
Example
@http.get("/myendpoint")
async handleRequest(request) {
return new Response("Hello world", {
status: 200,
headers: {"Content-Type": "text/plain"}
});
}
Request and Response Handling
The plugin uses standard Web API classes:
- Request – represents the incoming HTTP request (method, URL, headers, body).
- Response – represents the outgoing HTTP response (status, headers, body).
This ensures full compatibility with modern JavaScript patterns for handling HTTP.
Summary
By enabling the HttpPlugin:
- The core server becomes an HTTP server.
- Endpoints can be declared with clean decorator syntax.
- Request and response handling follows the Web API standard, making integration straightforward and predictable.