palinxdocs

Share logic with a service

Services hold logic that pages and endpoints share. Palinx creates them and hands them out with inject().

Add a service

Create src/services/greeting.service.ts:

src/services/greeting.service.ts
import { Service, singleton } from "@palinx/core";

@singleton()
export class GreetingService extends Service {
  message() {
    return "Hello from the server";
  }
}

A service extends Service. @singleton() means one instance for the whole app, which is also the default.

Use it in the endpoint

src/api/greeting.ts (changes since step 6)
-import { Api, api, get } from "@palinx/core";
+import { Api, api, get, inject } from "@palinx/core";
+import { GreetingService } from "../services/greeting.service";
 
 @api("/greeting")
 export default class Greeting extends Api {
+  private greetings = inject(GreetingService);
+
   @get("/")
   show() {
-    return Response.json({ message: "Hello from the server" });
+    return Response.json({ message: this.greetings.message() });
   }
 }

inject(GreetingService) returns the instance palinx manages; you never call new on a service.

Run it

Nothing changes on screen: /api/greeting still returns {"message":"Hello from the server"}, and the home page still shows The server says: Hello from the server. The logic moved; the behaviour didn't.

How it works

Importing the service and calling inject() is all the wiring there is: palinx registers the class the first time it's injected and includes it in the production build. Any other endpoint, page or service that needs a greeting injects the same instance. Services & dependency injection covers per-request and transient scopes, and services that depend on each other.

Next: Build for production.