orator 5.0.1 → 5.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,107 +1,84 @@
1
1
  # Orator
2
2
 
3
- Orator API Server, meant to interact well with Fable, Meadow and FoxHound.
3
+ > An unopinionated API server abstraction for REST and IPC services
4
4
 
5
- [![Coverage Status](https://coveralls.io/repos/stevenvelozo/orator/badge.svg?branch=master)](https://coveralls.io/r/stevenvelozo/orator?branch=master) [![Build Status](https://travis-ci.org/stevenvelozo/orator.svg?branch=master)](https://travis-ci.org/stevenvelozo/orator) [![Dependency Status](https://david-dm.org/stevenvelozo/orator.svg)](https://david-dm.org/stevenvelozo/orator) [![devDependency Status](https://david-dm.org/stevenvelozo/orator/dev-status.svg)](https://david-dm.org/stevenvelozo/orator#info=devDependencies)
5
+ Orator is not an attempt to reinvent the wheel. Nor do we want to make a car with five of them. Orator is a thin abstraction layer over service server implementations (like Restify), providing a consistent interface for building API servers. You can spin up a web server in a single simple line, and configuration is managed through a consistent JSON format -- so as you begin to have 10 or 15 or 5,000 microservices, you don't have a bunch of boilerplate API server code laying around.
6
6
 
7
- This is not an attempt to reinvent the wheel. Nor do we want to make a car with five of them.
7
+ ## Features
8
8
 
9
- Orator is a wrapper for [restify](https://github.com/restify/node-restify), which is an amazing API server. With Orator, you can spin up a web server in a single simple line. And config settings are managed via a consistent json format, so as you begin to have 10 or 15 or 5,000 microservices, you don't have a bunch of boilerplate API server code laying around.
9
+ - **Unopinionated Design** - Wraps any service server implementation through a consistent interface
10
+ - **REST and IPC** - Full HTTP server support via Restify, or in-process IPC for testing and microservice composition
11
+ - **Lifecycle Management** - Before/After hooks for initialization and service start phases
12
+ - **Static File Serving** - Built-in static file serving with subdomain-based folder routing
13
+ - **Fable Integration** - First-class service provider in the Fable ecosystem with logging and configuration
14
+ - **Browser & Node.js** - Works in both environments with automatic service server selection
10
15
 
11
- ## Creating a Simple Server
16
+ ## Quick Start
12
17
 
13
- Okay, so you want to make a simple api server. You would need to create a node.js project, then install the Orator dependency with npm:
18
+ ```javascript
19
+ const libFable = require('fable');
20
+ const libOrator = require('orator');
21
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
14
22
 
15
- ```sh
16
- npm install orator --save
17
- ```
23
+ const _Fable = new libFable({
24
+ Product: 'MyAPIServer',
25
+ ProductVersion: '1.0.0',
26
+ ServicePort: 8080
27
+ });
18
28
 
19
- Then within your javascript code, you could write the following:
29
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
30
+ _Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
31
+ _Fable.serviceManager.instantiateServiceProvider('Orator');
32
+ _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
20
33
 
21
- ```js
22
- // Load the orator module with a few settings
23
- var libOrator = require('orator').new(
34
+ _Fable.Orator.serviceServer.get('/hello/:name',
35
+ (pRequest, pResponse, fNext) =>
24
36
  {
25
- Product: 'MyMicroserviceHash',
26
- ProductVersion: '9.8.7',
27
-
28
- "APIServerPort": 8000
37
+ pResponse.send({ greeting: `Hello ${pRequest.params.name}!` });
38
+ return fNext();
29
39
  });
30
40
 
31
- // Add an API endpoint
32
- libOrator.webServer.post
33
- (
34
- '/echo/:name',
35
- function(pRequest, pResponse, fNext)
41
+ _Fable.Orator.startService(
42
+ () =>
36
43
  {
37
- // Send back whatever was sent as "name" in the URI
38
- pResponse.send(pRequest.params);
39
- return fNext();
40
- }
41
- );
42
-
43
- // Start the web service
44
- libOrator.startWebServer();
44
+ console.log('Server is running on port 8080');
45
+ });
45
46
  ```
46
47
 
47
- After writing this code, you could run your service and a browser going to `http://localhost:8000/echo/Gargamel` would return a JSON object with Gargamel as the name.
48
-
49
- Of course, this is not much different from the Restify code. Where it gets interesting is dealing with things like logging and configuration management. For instance, if you do
48
+ ## Installation
50
49
 
51
- ```js
52
- // Load the orator module with a few settings
53
- var libOrator = require('orator').new(
54
- {
55
- Product: 'MyMicroserviceHash',
56
- ProductVersion: '9.8.7',
50
+ ```bash
51
+ npm install orator
52
+ ```
57
53
 
58
- "APIServerPort": 8000,
54
+ ## Configuration
59
55
 
60
- ConfigFile:__dirname+'/MyMicroservice-Config.json'
61
- });
56
+ | Setting | Type | Default | Description |
57
+ |---------|------|---------|-------------|
58
+ | `Product` | string | `"Unnamed_Service"` | Application name identifier |
59
+ | `ProductVersion` | string | `"0.0.1"` | Application version string |
60
+ | `ServicePort` | number | `8080` | Port for the service server to listen on |
61
+ | `APIServerPort` | number | - | Legacy alias for ServicePort (automatically migrated) |
62
+ | `RestifyConfiguration` | object | `{}` | Configuration passed to Restify when using the Restify service server |
62
63
 
63
- // Add an API endpoint
64
- libOrator.webServer.post
65
- (
66
- '/echo/:name',
67
- function(pRequest, pResponse, fNext)
68
- {
69
- // Send back whatever was sent as "name" in the URI
70
- pResponse.send(pRequest.params);
71
- return fNext();
72
- }
73
- );
64
+ ## Documentation
74
65
 
75
- // Start the web service
76
- libOrator.startWebServer();
77
- ```
66
+ Full documentation is available in the [`docs`](./docs) folder, or served locally:
78
67
 
79
- Then you could create a file in the same folder as this script called `MyMicroservice-Config.json` and as long as it is valid json, settings can be loaded from there. Something like this:
80
-
81
- ```json
82
- {
83
- "APIServerPort": 8080,
84
-
85
- "UUID":
86
- {
87
- "DataCenter": 0,
88
- "Worker": 0
89
- },
90
-
91
- "LogStreams":
92
- [
93
- {
94
- "level": "info",
95
- "path": "./MyMicroService-Server.log"
96
- },
97
- {
98
- "level": "trace",
99
- "streamtype": "process.stdout"
100
- }
101
- ]
102
- }
68
+ ```bash
69
+ npx docsify-cli serve docs
103
70
  ```
104
71
 
105
- And suddenly the bunyan logging will write to a file and stdout, and you can configure 20 Docker instances to each have a different Worker ID.
72
+ - [Architecture](docs/architecture.md) - Service server abstraction design
73
+ - [Getting Started](docs/getting-started.md) - Step-by-step setup guide
74
+ - [Static File Serving](docs/static-files.md) - Serving files from disk
75
+ - [IPC Server](docs/ipc-server.md) - In-process service invocation
106
76
 
77
+ ## Related Packages
107
78
 
79
+ - [orator-serviceserver-base](https://github.com/stevenvelozo/orator-serviceserver-base) - Abstract base class for service servers
80
+ - [orator-serviceserver-restify](https://github.com/stevenvelozo/orator-serviceserver-restify) - Restify service server implementation
81
+ - [orator-http-proxy](https://github.com/stevenvelozo/orator-http-proxy) - HTTP proxy pass-through for Orator
82
+ - [orator-static-server](https://github.com/stevenvelozo/orator-static-server) - Static file serving module
83
+ - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
84
+ - [meadow](https://github.com/stevenvelozo/meadow) - Data access layer with automatic REST endpoints
package/docs/.nojekyll ADDED
File without changes
package/docs/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # Orator
2
+
3
+ > An unopinionated API server abstraction for REST and IPC services
4
+
5
+ Orator is a thin abstraction layer over service server implementations, providing a consistent interface for building API servers. It doesn't care whether you're running Restify, building an in-process service mesh, or doing something entirely novel with your own service server implementation. Orator provides the lifecycle, the configuration, and the conventions -- you provide the service logic.
6
+
7
+ ## Features
8
+
9
+ - **Unopinionated Design** - Wraps any service server implementation through a consistent interface
10
+ - **REST and IPC** - Full HTTP server support via Restify, or in-process IPC for testing and microservice composition
11
+ - **Lifecycle Management** - Before/After hooks for initialization and service start phases
12
+ - **Static File Serving** - Built-in static file serving with subdomain-based folder routing
13
+ - **Fable Integration** - First-class service provider in the Fable ecosystem with logging and configuration
14
+ - **Browser & Node.js** - Works in both environments with automatic service server selection
15
+
16
+ ## Quick Start
17
+
18
+ ```javascript
19
+ const libFable = require('fable');
20
+ const libOrator = require('orator');
21
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
22
+
23
+ const _Fable = new libFable({
24
+ Product: 'MyAPIServer',
25
+ ProductVersion: '1.0.0',
26
+ ServicePort: 8080
27
+ });
28
+
29
+ // Register Orator and a service server with Fable
30
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
31
+ _Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
32
+ _Fable.serviceManager.instantiateServiceProvider('Orator');
33
+ _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
34
+
35
+ // Add an API endpoint
36
+ _Fable.Orator.serviceServer.get('/hello/:name',
37
+ (pRequest, pResponse, fNext) =>
38
+ {
39
+ pResponse.send({ greeting: `Hello ${pRequest.params.name}!` });
40
+ return fNext();
41
+ });
42
+
43
+ // Start the service
44
+ _Fable.Orator.startService(
45
+ () =>
46
+ {
47
+ console.log('Server is running on port 8080');
48
+ });
49
+ ```
50
+
51
+ ## Installation
52
+
53
+ ```bash
54
+ npm install orator
55
+ ```
56
+
57
+ ## How It Works
58
+
59
+ Orator follows the Fable service provider pattern. You register it with a Fable instance, and it orchestrates one or more service server implementations to handle incoming requests. If you don't provide a service server, Orator will automatically set up its built-in IPC server -- which is useful for testing and in-process communication where no network traffic is needed.
60
+
61
+ ```
62
+ Fable (Core)
63
+ └── Orator (Service Orchestration)
64
+ └── Service Server (Restify, IPC, or custom)
65
+ ├── Route Registration (GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD)
66
+ ├── Middleware Pipeline
67
+ └── Static File Serving
68
+ ```
69
+
70
+ ## Configuration
71
+
72
+ Orator accepts configuration through the Fable settings object:
73
+
74
+ ```json
75
+ {
76
+ "Product": "MyAPIServer",
77
+ "ProductVersion": "1.0.0",
78
+ "ServicePort": 8080,
79
+ "RestifyConfiguration": {}
80
+ }
81
+ ```
82
+
83
+ | Setting | Type | Default | Description |
84
+ |---------|------|---------|-------------|
85
+ | `Product` | string | `"Unnamed_Service"` | Application name identifier |
86
+ | `ProductVersion` | string | `"0.0.1"` | Application version string |
87
+ | `ServicePort` | number | `8080` | Port for the service server to listen on |
88
+ | `APIServerPort` | number | - | Legacy alias for ServicePort (automatically migrated) |
89
+ | `RestifyConfiguration` | object | `{}` | Configuration passed to Restify server creation |
90
+ | `ServiceServerOptions` | object | `{}` | Options passed to the auto-initialized service server |
91
+
92
+ ## API Reference
93
+
94
+ ### Lifecycle Methods
95
+
96
+ | Method | Description |
97
+ |--------|-------------|
98
+ | `initialize(fCallback)` | Initializes Orator and its service server |
99
+ | `startService(fCallback)` | Starts the service server listening on the configured port |
100
+ | `stopService(fCallback)` | Stops the running service server |
101
+
102
+ ### Route Invocation
103
+
104
+ | Method | Description |
105
+ |--------|-------------|
106
+ | `invoke(pMethod, pRoute, pData, fCallback)` | Programmatically invoke a registered route without HTTP |
107
+
108
+ ### Static Files
109
+
110
+ | Method | Description |
111
+ |--------|-------------|
112
+ | `addStaticRoute(pFilePath, pDefaultFile, pRoute, pRouteStrip, pParams)` | Serve static files from a directory |
113
+
114
+ ### Legacy Methods
115
+
116
+ | Method | Maps To |
117
+ |--------|---------|
118
+ | `startWebServer(fCallback)` | `startService(fCallback)` |
119
+ | `stopWebServer(fCallback)` | `stopService(fCallback)` |
120
+ | `getWebServer()` | Returns `serviceServer` (lazy-initializes if needed) |
121
+
122
+ ### Properties
123
+
124
+ | Property | Type | Description |
125
+ |----------|------|-------------|
126
+ | `serviceServer` | object | The active service server instance |
127
+ | `webServer` | object | Legacy alias for `serviceServer` |
128
+
129
+ ## Testing
130
+
131
+ ```bash
132
+ npm test
133
+ ```
134
+
135
+ ## Related Packages
136
+
137
+ - [orator-serviceserver-base](https://github.com/stevenvelozo/orator-serviceserver-base) - Abstract base class for service servers
138
+ - [orator-serviceserver-restify](https://github.com/stevenvelozo/orator-serviceserver-restify) - Restify service server implementation
139
+ - [orator-http-proxy](https://github.com/stevenvelozo/orator-http-proxy) - HTTP proxy pass-through for Orator
140
+ - [orator-static-server](https://github.com/stevenvelozo/orator-static-server) - Static file serving module
141
+ - [fable](https://github.com/stevenvelozo/fable) - Service provider framework
142
+ - [meadow](https://github.com/stevenvelozo/meadow) - Data access layer with automatic REST endpoints
@@ -0,0 +1,21 @@
1
+ - Getting Started
2
+
3
+ - [Introduction](/)
4
+ - [Getting Started](getting-started.md)
5
+ - [Architecture](architecture.md)
6
+
7
+ - Core Concepts
8
+
9
+ - [Service Servers](service-servers.md)
10
+ - [Lifecycle Hooks](lifecycle-hooks.md)
11
+ - [Static File Serving](static-files.md)
12
+
13
+ - Service Server Implementations
14
+
15
+ - [IPC Server](ipc-server.md)
16
+ - [Restify Server](restify-server.md)
17
+
18
+ - Advanced
19
+
20
+ - [HTTP Proxy](http-proxy.md)
21
+ - [Configuration Reference](configuration.md)
@@ -0,0 +1,92 @@
1
+ # Architecture
2
+
3
+ Orator's design separates the concerns of service lifecycle management from the specifics of any HTTP server implementation. This abstraction allows you to swap service servers, test without network overhead, and maintain consistent patterns across many microservices.
4
+
5
+ ## Layered Design
6
+
7
+ ```
8
+ ┌─────────────────────────────────────────────┐
9
+ │ Fable │
10
+ │ (Configuration, Logging, DI) │
11
+ └─────────────────────┬───────────────────────┘
12
+
13
+ ┌─────────────────────▼───────────────────────┐
14
+ │ Orator │
15
+ │ (Lifecycle, Static Files, Invocation) │
16
+ └─────────────────────┬───────────────────────┘
17
+
18
+ ┌─────────────────────▼───────────────────────┐
19
+ │ OratorServiceServerBase │
20
+ │ (Abstract Route & Middleware API) │
21
+ └───────┬─────────────┬───────────────────────┘
22
+ │ │
23
+ ┌───────▼──────┐ ┌────▼──────────────┐
24
+ │ IPC Server │ │ Restify Server │
25
+ │ (built-in) │ │ (network HTTP) │
26
+ └──────────────┘ └───────────────────┘
27
+ ```
28
+
29
+ ### Fable Layer
30
+
31
+ Fable provides the foundation: dependency injection, configuration management, logging, and service wiring. Orator registers itself as a Fable service and gains access to all of these capabilities automatically.
32
+
33
+ ### Orator Layer
34
+
35
+ Orator manages the service lifecycle (initialization, starting, stopping) and provides higher-level features like static file serving and programmatic route invocation. It delegates actual HTTP handling to whichever service server implementation is registered.
36
+
37
+ ### Service Server Layer
38
+
39
+ Service servers implement the actual HTTP verb handling. The base class (`orator-serviceserver-base`) defines the interface, and concrete implementations like `orator-serviceserver-restify` and the built-in IPC server provide the behavior.
40
+
41
+ ## Service Provider Pattern
42
+
43
+ All Orator modules follow the Fable service provider pattern. Services are registered with a Fable instance by type, then instantiated on demand:
44
+
45
+ ```javascript
46
+ // Register the service types
47
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
48
+ _Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
49
+
50
+ // Instantiate them -- Fable handles wiring
51
+ _Fable.serviceManager.instantiateServiceProvider('Orator');
52
+ _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
53
+
54
+ // Access via Fable
55
+ _Fable.Orator.startService();
56
+ ```
57
+
58
+ ## Auto-Initialization
59
+
60
+ If no service server is registered when Orator initializes, it will automatically create and register the built-in IPC service server. This makes it possible to use Orator for in-process route invocation without configuring a network server:
61
+
62
+ ```javascript
63
+ // No OratorServiceServer registered -- IPC is used automatically
64
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
65
+ _Fable.serviceManager.instantiateServiceProvider('Orator');
66
+
67
+ _Fable.Orator.serviceServer.get('/api/data',
68
+ (pRequest, pResponse, fNext) =>
69
+ {
70
+ pResponse.send({ value: 42 });
71
+ return fNext();
72
+ });
73
+
74
+ // Invoke the route programmatically (no network call)
75
+ _Fable.Orator.invoke('GET', '/api/data', {},
76
+ (pError, pResponseData) =>
77
+ {
78
+ console.log(pResponseData); // { value: 42 }
79
+ });
80
+ ```
81
+
82
+ ## Template Method Pattern
83
+
84
+ The service server base class uses a template method pattern for route registration. The base class validates inputs, and derived classes implement the `do*` methods with actual behavior:
85
+
86
+ ```
87
+ Base: get(pRoute, ...) → validates pRoute → calls doGet(pRoute, ...)
88
+ └── Restify: doGet(pRoute, ...) → this.server.get(pRoute, ...)
89
+ └── IPC: doGet(pRoute, ...) → this.addRouteProcessor('GET', pRoute, ...)
90
+ ```
91
+
92
+ This pattern allows derived classes to focus on implementation without duplicating validation logic.
@@ -0,0 +1,94 @@
1
+ # Configuration Reference
2
+
3
+ Orator is configured through the Fable settings object. Settings can be provided directly, loaded from a configuration file, or a combination of both.
4
+
5
+ ## Orator Settings
6
+
7
+ | Setting | Type | Default | Description |
8
+ |---------|------|---------|-------------|
9
+ | `Product` | string | `"Unnamed_Service"` | Application name identifier |
10
+ | `ProductVersion` | string | `"0.0.1"` | Application version string |
11
+ | `ServicePort` | number | `8080` | Port for the service server to listen on |
12
+ | `APIServerPort` | number | - | Legacy alias for `ServicePort` (automatically migrated) |
13
+ | `ServiceServerOptions` | object | `{}` | Options passed to the auto-initialized service server |
14
+
15
+ ## Restify Settings
16
+
17
+ When using the Restify service server:
18
+
19
+ | Setting | Type | Default | Description |
20
+ |---------|------|---------|-------------|
21
+ | `RestifyConfiguration` | object | `{}` | Configuration passed to `restify.createServer()` |
22
+ | `RestifyConfiguration.maxParamLength` | number | `Number.MAX_SAFE_INTEGER` | Maximum URL parameter length |
23
+
24
+ ## HTTP Proxy Settings
25
+
26
+ When using the HTTP proxy module:
27
+
28
+ | Setting | Type | Default | Description |
29
+ |---------|------|---------|-------------|
30
+ | `OratorHTTPProxyDestinationURL` | string | `"http://127.0.0.1/"` | URL to proxy requests to |
31
+ | `OratorHTTPProxyRequestPrefixList` | array | `["/1.0/*"]` | Route prefixes to proxy |
32
+ | `OratorHTTPProxyLogLevel` | number | `0` | Proxy logging verbosity |
33
+
34
+ ## Fable Settings
35
+
36
+ These Fable settings are commonly used with Orator:
37
+
38
+ | Setting | Type | Default | Description |
39
+ |---------|------|---------|-------------|
40
+ | `LogStreams` | array | `[{ level: "info" }]` | Log output destinations |
41
+ | `LogNoisiness` | number | `0` | Controls Orator's internal trace logging |
42
+ | `UUID.DataCenter` | number | `0` | Data center ID for UUID generation |
43
+ | `UUID.Worker` | number | `0` | Worker ID for UUID generation |
44
+
45
+ ## Example Configuration File
46
+
47
+ ```json
48
+ {
49
+ "Product": "MyAPIServer",
50
+ "ProductVersion": "2.1.0",
51
+ "ServicePort": 8080,
52
+
53
+ "RestifyConfiguration": {
54
+ "strictNext": true
55
+ },
56
+
57
+ "UUID": {
58
+ "DataCenter": 0,
59
+ "Worker": 1
60
+ },
61
+
62
+ "LogStreams": [
63
+ {
64
+ "level": "info",
65
+ "path": "./server.log"
66
+ },
67
+ {
68
+ "level": "trace",
69
+ "streamtype": "process.stdout"
70
+ }
71
+ ]
72
+ }
73
+ ```
74
+
75
+ ## Loading Configuration
76
+
77
+ ```javascript
78
+ // Direct configuration
79
+ const _Fable = new libFable({
80
+ Product: 'MyAPIServer',
81
+ ServicePort: 8080
82
+ });
83
+
84
+ // From a JSON file
85
+ const _Fable = new libFable({
86
+ ConfigFile: __dirname + '/config.json'
87
+ });
88
+
89
+ // Combined (direct settings override file settings)
90
+ const _Fable = new libFable({
91
+ ConfigFile: __dirname + '/config.json',
92
+ ServicePort: 9090 // Overrides whatever is in config.json
93
+ });
94
+ ```
package/docs/cover.md ADDED
@@ -0,0 +1,11 @@
1
+ # Orator <small>5</small>
2
+
3
+ > An unopinionated API server abstraction for REST and IPC services
4
+
5
+ - Consistent interface over any service server implementation
6
+ - Full REST support via Restify with in-process IPC for testing
7
+ - Built-in static file serving with subdomain routing
8
+ - First-class Fable service provider with lifecycle management
9
+
10
+ [GitHub](https://github.com/stevenvelozo/orator)
11
+ [Get Started](#orator)
@@ -0,0 +1,133 @@
1
+ # Getting Started
2
+
3
+ This guide walks through setting up an Orator-based API server from scratch.
4
+
5
+ ## Installation
6
+
7
+ Create a new Node.js project and install the dependencies:
8
+
9
+ ```bash
10
+ mkdir my-api-server && cd my-api-server
11
+ npm init -y
12
+ npm install fable orator orator-serviceserver-restify
13
+ ```
14
+
15
+ ## Basic Server
16
+
17
+ The simplest possible Orator server:
18
+
19
+ ```javascript
20
+ const libFable = require('fable');
21
+ const libOrator = require('orator');
22
+ const libOratorServiceServerRestify = require('orator-serviceserver-restify');
23
+
24
+ // 1. Create a Fable instance with your service configuration
25
+ const _Fable = new libFable({
26
+ Product: 'MyAPIServer',
27
+ ProductVersion: '1.0.0',
28
+ ServicePort: 8080
29
+ });
30
+
31
+ // 2. Register Orator and a service server
32
+ _Fable.serviceManager.addServiceType('Orator', libOrator);
33
+ _Fable.serviceManager.addServiceType('OratorServiceServer', libOratorServiceServerRestify);
34
+ _Fable.serviceManager.instantiateServiceProvider('Orator');
35
+ _Fable.serviceManager.instantiateServiceProvider('OratorServiceServer');
36
+
37
+ // 3. Define your API endpoints
38
+ _Fable.Orator.serviceServer.get('/api/status',
39
+ (pRequest, pResponse, fNext) =>
40
+ {
41
+ pResponse.send({ status: 'ok', timestamp: new Date().toISOString() });
42
+ return fNext();
43
+ });
44
+
45
+ // 4. Start the server
46
+ _Fable.Orator.startService(
47
+ () =>
48
+ {
49
+ _Fable.log.info('API server is ready');
50
+ });
51
+ ```
52
+
53
+ Run it with `node server.js` and visit `http://localhost:8080/api/status` in your browser.
54
+
55
+ ## Adding Routes
56
+
57
+ Orator's service server exposes methods for all standard HTTP verbs. Each handler receives `pRequest`, `pResponse`, and `fNext` -- the standard Restify handler signature.
58
+
59
+ ```javascript
60
+ // GET with URL parameters
61
+ _Fable.Orator.serviceServer.get('/api/user/:id',
62
+ (pRequest, pResponse, fNext) =>
63
+ {
64
+ let tmpUserID = pRequest.params.id;
65
+ pResponse.send({ id: tmpUserID, name: 'Example User' });
66
+ return fNext();
67
+ });
68
+
69
+ // POST with body parsing
70
+ _Fable.Orator.serviceServer.postWithBodyParser('/api/user',
71
+ (pRequest, pResponse, fNext) =>
72
+ {
73
+ let tmpNewUser = pRequest.body;
74
+ _Fable.log.info(`Creating user: ${tmpNewUser.name}`);
75
+ pResponse.send({ created: true, user: tmpNewUser });
76
+ return fNext();
77
+ });
78
+
79
+ // PUT, DELETE, PATCH follow the same pattern
80
+ _Fable.Orator.serviceServer.del('/api/user/:id',
81
+ (pRequest, pResponse, fNext) =>
82
+ {
83
+ pResponse.send({ deleted: true, id: pRequest.params.id });
84
+ return fNext();
85
+ });
86
+ ```
87
+
88
+ ## Using Middleware
89
+
90
+ Register middleware that runs before all route handlers:
91
+
92
+ ```javascript
93
+ // Add a middleware function
94
+ _Fable.Orator.serviceServer.use(
95
+ (pRequest, pResponse, fNext) =>
96
+ {
97
+ _Fable.log.trace(`${pRequest.method} ${pRequest.url}`);
98
+ return fNext();
99
+ });
100
+ ```
101
+
102
+ ## Configuration from File
103
+
104
+ Fable supports loading configuration from a JSON file, which means your Orator server configuration can live outside your code:
105
+
106
+ ```json
107
+ {
108
+ "Product": "MyAPIServer",
109
+ "ProductVersion": "1.0.0",
110
+ "ServicePort": 8080,
111
+ "LogStreams": [
112
+ {
113
+ "level": "info",
114
+ "path": "./server.log"
115
+ },
116
+ {
117
+ "level": "trace",
118
+ "streamtype": "process.stdout"
119
+ }
120
+ ]
121
+ }
122
+ ```
123
+
124
+ ```javascript
125
+ const _Fable = new libFable({ ConfigFile: __dirname + '/config.json' });
126
+ ```
127
+
128
+ ## Next Steps
129
+
130
+ - [Architecture](architecture.md) - Understand the service server abstraction
131
+ - [Lifecycle Hooks](lifecycle-hooks.md) - Customize initialization and startup behavior
132
+ - [Static File Serving](static-files.md) - Serve files from disk
133
+ - [IPC Server](ipc-server.md) - Use Orator without a network server