Application Server: Difference between revisions

From FullJS
Jump to navigation Jump to search
Line 95: Line 95:
# '''Static Initialization''': A '''static block''' in the server class runs once when the class is defined. It is used to register all required plugins at startup. This ensures that the server is fully configured before any instances are created.
# '''Static Initialization''': A '''static block''' in the server class runs once when the class is defined. It is used to register all required plugins at startup. This ensures that the server is fully configured before any instances are created.


<code>
<pre>
import {Server} from "appserver";
import {Server} from "appserver";
import {AppServerPlugin} from "appserver";
import {AppServerPlugin} from "appserver";
Line 120: Line 120:


})();
})();
</code>
</pre>


# '''Plugin Isolation and Modularity''': Each plugin is a self-contained module, responsible for a particular aspect of server functionality. The server core interacts with plugins through a defined interface, enabling safe modularity and easy swapping or upgrading of features.
# '''Plugin Isolation and Modularity''': Each plugin is a self-contained module, responsible for a particular aspect of server functionality. The server core interacts with plugins through a defined interface, enabling safe modularity and easy swapping or upgrading of features.

Revision as of 21:13, 1 September 2025

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/fulljs/[instance]/ – contains the deployed application
  • /run/fulljs/[instance]/** – runtime files (e.g., sockets, PID files)
  • /var/lib/fulljs/[instance]/** – persistent state data (e.g., storage files)
  • /etc/fulljs/** – configuration files (if any)

Plugin-based architecture – Extend and customize backend functionality through a modular plugin system

Description: The plugin-based architecture allows the backend server to be extended and customized by dynamically enabling modular plugins. Each plugin encapsulates a specific functionality, such as HTTP handling, authentication, permission management, system integration, or debugging tools. This design decouples core server logic from optional features, making it easier to maintain, test, and evolve the system.

How it works:

  1. Core Server Class: The main server class provides the infrastructure for running the application and managing plugins. For example, Server in the code acts as the base class.
  2. 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.
  3. Static Initialization: A static block in the server class runs once when the class is defined. It is used to register all required plugins at startup. 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 {
        this.enablePlugin(SystemdPlugin);
        this.enablePlugin(HttpPlugin, {port: 8080, endpoint: /^(?!.*\.jss$).*/, slot: "http_slot00"});
        this.enablePlugin(AppServerPlugin);
        this.enablePlugin(AuthPlugin);
        this.enablePlugin(PermPlugin);
        this.enablePlugin(DebugConsolePlugin);
    }

    constructor(...args) {
        super(...args);
    }

})();
  1. Plugin Isolation and Modularity: Each plugin is a self-contained module, responsible for a particular aspect of server functionality. The server core interacts with plugins through a defined interface, enabling safe modularity and easy swapping or upgrading of features.
  2. Extensibility: Developers can create new plugins without modifying the core server code. By simply calling enablePlugin(NewPlugin) in the static block, the new functionality is integrated seamlessly.

Benefits:

  • Modular Design: Features can be added or removed without touching the core logic.
  • Reusability: Plugins can be shared between different projects or server instances.
  • Scalability: Additional functionality can be loaded dynamically as the application grows.
  • Maintainability: Bugs or updates in one plugin do not affect other parts of the system.