retold-data-service 2.0.8 → 2.0.10
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/.vscode/settings.json +33 -14
- package/CONTRIBUTING.md +50 -0
- package/README.md +200 -56
- package/docs/.nojekyll +0 -0
- package/docs/README.md +76 -0
- package/docs/_sidebar.md +13 -0
- package/docs/architecture.md +94 -0
- package/docs/behavior-injection.md +111 -0
- package/docs/configuration.md +93 -0
- package/docs/cover.md +11 -0
- package/docs/dal-access.md +87 -0
- package/docs/endpoints.md +121 -0
- package/docs/index.html +39 -0
- package/docs/initialization.md +77 -0
- package/docs/lifecycle-hooks.md +81 -0
- package/docs/schema-definition.md +128 -0
- package/docs/storage-providers.md +109 -0
- package/package.json +10 -6
- package/source/Retold-Data-Service.js +22 -13
- package/test/RetoldDataService_tests.js +1315 -18
package/.vscode/settings.json
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"sqltools.connections": [
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
{
|
|
4
|
+
"mysqlOptions": {
|
|
5
|
+
"authProtocol": "default",
|
|
6
|
+
"enableSsl": "Disabled"
|
|
7
|
+
},
|
|
8
|
+
"ssh": "Disabled",
|
|
9
|
+
"previewLimit": 50,
|
|
10
|
+
"server": "localhost",
|
|
11
|
+
"port": 3306,
|
|
12
|
+
"driver": "MariaDB",
|
|
13
|
+
"name": "Local MariaDB Harness",
|
|
14
|
+
"database": "bookstore",
|
|
15
|
+
"username": "root",
|
|
16
|
+
"password": "123456789",
|
|
17
|
+
"group": "Retold Development"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"mysqlOptions": {
|
|
21
|
+
"authProtocol": "default",
|
|
22
|
+
"enableSsl": "Disabled"
|
|
23
|
+
},
|
|
24
|
+
"ssh": "Disabled",
|
|
25
|
+
"previewLimit": 50,
|
|
26
|
+
"server": "localhost",
|
|
27
|
+
"port": 31306,
|
|
28
|
+
"driver": "MariaDB",
|
|
29
|
+
"name": "Containerized MariaDB Harness",
|
|
30
|
+
"group": "Retold Development",
|
|
31
|
+
"database": "bookstore",
|
|
32
|
+
"username": "root",
|
|
33
|
+
"password": "123456789"
|
|
34
|
+
}
|
|
35
|
+
]
|
|
17
36
|
}
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Contributing to Retold
|
|
2
|
+
|
|
3
|
+
We welcome contributions to Retold and its modules. This guide covers the expectations and process for contributing.
|
|
4
|
+
|
|
5
|
+
## Code of Conduct
|
|
6
|
+
|
|
7
|
+
The Retold community values **empathy**, **equity**, **kindness**, and **thoughtfulness**. We expect all participants to treat each other with respect, assume good intent, and engage constructively. These values apply to all interactions: pull requests, issues, discussions, and code review.
|
|
8
|
+
|
|
9
|
+
## How to Contribute
|
|
10
|
+
|
|
11
|
+
### Pull Requests
|
|
12
|
+
|
|
13
|
+
Pull requests are the preferred method for contributing changes. To submit one:
|
|
14
|
+
|
|
15
|
+
1. Fork the module repository you want to change
|
|
16
|
+
2. Create a branch for your work
|
|
17
|
+
3. Make your changes, following the code style of the module you are editing
|
|
18
|
+
4. Ensure your changes have test coverage (see below)
|
|
19
|
+
5. Open a pull request against the module's main branch
|
|
20
|
+
|
|
21
|
+
**Submitting a pull request does not guarantee it will be accepted.** Maintainers review contributions for fit, quality, and alignment with the project's direction. A PR may be declined, or you may be asked to revise it. This is normal and not a reflection on the quality of your effort.
|
|
22
|
+
|
|
23
|
+
### Reporting Issues
|
|
24
|
+
|
|
25
|
+
If you find a bug or have a feature suggestion, open an issue on the relevant module's repository. Include enough detail to reproduce the problem or understand the proposal.
|
|
26
|
+
|
|
27
|
+
## Test Coverage
|
|
28
|
+
|
|
29
|
+
Every commit must include test coverage for the changes it introduces. Retold modules use Mocha in TDD style. Before submitting:
|
|
30
|
+
|
|
31
|
+
- **Write tests** for any new functionality or bug fixes
|
|
32
|
+
- **Run the existing test suite** with `npm test` and confirm all tests pass
|
|
33
|
+
- **Check coverage** with `npm run coverage` if the module supports it
|
|
34
|
+
|
|
35
|
+
Pull requests that break existing tests or lack coverage for new code will not be merged.
|
|
36
|
+
|
|
37
|
+
## Code Style
|
|
38
|
+
|
|
39
|
+
Follow the conventions of the module you are working in. The general Retold style is:
|
|
40
|
+
|
|
41
|
+
- **Tabs** for indentation, never spaces
|
|
42
|
+
- **Plain JavaScript** only (no TypeScript)
|
|
43
|
+
- **Allman-style braces** (opening brace on its own line)
|
|
44
|
+
- **Variable naming:** `pVariable` for parameters, `tmpVariable` for temporaries, `libSomething` for imports
|
|
45
|
+
|
|
46
|
+
When in doubt, match what the surrounding code does.
|
|
47
|
+
|
|
48
|
+
## Repository Structure
|
|
49
|
+
|
|
50
|
+
Each module is its own git repository. The [retold](https://github.com/stevenvelozo/retold) repository tracks module organization but does not contain module source code. Direct your pull request to the specific module repository where your change belongs.
|
package/README.md
CHANGED
|
@@ -1,86 +1,230 @@
|
|
|
1
1
|
# Retold Data Service
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> An all-in-one Fable service that turns a Stricture schema into a complete REST API
|
|
4
|
+
|
|
5
|
+
Retold Data Service combines Meadow (data access), Orator (API server), and Meadow Endpoints (REST routes) into a single service provider. Point it at a compiled Stricture model and it auto-generates typed CRUD endpoints for every entity -- complete with filtering, pagination, soft deletes, and behavior injection hooks.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Zero-Boilerplate REST** - Define your schema once, get full CRUD endpoints for every entity automatically
|
|
10
|
+
- **Provider-Agnostic** - Swap between MySQL, MSSQL, SQLite, or ALASQL without changing application code
|
|
11
|
+
- **Schema-Driven** - Stricture DDL compiles into a model that drives endpoint generation, validation, and defaults
|
|
12
|
+
- **Lifecycle Hooks** - `onBeforeInitialize`, `onInitialize`, and `onAfterInitialize` for custom startup logic
|
|
13
|
+
- **Behavior Injection** - Pre- and post-operation hooks on every CRUD operation for custom business logic
|
|
14
|
+
- **DAL Access** - Direct programmatic data access alongside the REST endpoints for server-side logic
|
|
15
|
+
- **Fable Service Provider** - First-class service in the Fable ecosystem with logging, configuration, and DI
|
|
16
|
+
- **Double-Init Protection** - Guards against accidental re-initialization
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```javascript
|
|
21
|
+
const libFable = require('fable');
|
|
22
|
+
const libRetoldDataService = require('retold-data-service');
|
|
23
|
+
|
|
24
|
+
const _Fable = new libFable({
|
|
25
|
+
APIServerPort: 8086,
|
|
26
|
+
MySQL: {
|
|
27
|
+
Server: '127.0.0.1',
|
|
28
|
+
Port: 3306,
|
|
29
|
+
User: 'root',
|
|
30
|
+
Password: 'secret',
|
|
31
|
+
Database: 'bookstore',
|
|
32
|
+
ConnectionPoolLimit: 20
|
|
33
|
+
},
|
|
34
|
+
MeadowConnectionMySQLAutoConnect: true
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
_Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
|
|
38
|
+
|
|
39
|
+
_Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
|
|
40
|
+
StorageProvider: 'MySQL',
|
|
41
|
+
StorageProviderModule: 'meadow-connection-mysql',
|
|
42
|
+
FullMeadowSchemaPath: `${__dirname}/model/`,
|
|
43
|
+
FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
_Fable.RetoldDataService.initializeService(
|
|
47
|
+
(pError) =>
|
|
48
|
+
{
|
|
49
|
+
if (pError)
|
|
50
|
+
{
|
|
51
|
+
return console.log('Error initializing data service:', pError);
|
|
52
|
+
}
|
|
53
|
+
console.log('REST API is running on port 8086');
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install retold-data-service
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## How It Works
|
|
64
|
+
|
|
65
|
+
Retold Data Service orchestrates the full Meadow stack into a single initialization sequence:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Fable (Core)
|
|
69
|
+
└── Retold Data Service
|
|
70
|
+
├── Orator (API Server)
|
|
71
|
+
│ └── Restify (HTTP Engine)
|
|
72
|
+
├── Meadow (Data Access Layer)
|
|
73
|
+
│ ├── Schema (from compiled Stricture model)
|
|
74
|
+
│ ├── FoxHound (Query DSL)
|
|
75
|
+
│ └── Provider (MySQL / MSSQL / SQLite / ALASQL)
|
|
76
|
+
└── Meadow Endpoints (REST Routes)
|
|
77
|
+
├── Create POST /1.0/Entity
|
|
78
|
+
├── Read GET /1.0/Entity/:ID
|
|
79
|
+
├── Reads GET /1.0/Entities/:Begin/:Cap
|
|
80
|
+
├── Update PUT /1.0/Entity
|
|
81
|
+
├── Delete DELETE /1.0/Entity/:ID
|
|
82
|
+
├── Count GET /1.0/Entities/Count
|
|
83
|
+
├── Schema GET /1.0/Entity/Schema
|
|
84
|
+
└── New GET /1.0/Entity/Schema/New
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Options
|
|
88
|
+
|
|
89
|
+
| Option | Default | Description |
|
|
90
|
+
|--------|---------|-------------|
|
|
91
|
+
| `StorageProvider` | `'MySQL'` | Database provider name |
|
|
92
|
+
| `StorageProviderModule` | `'meadow-connection-mysql'` | Node module for the provider |
|
|
93
|
+
| `FullMeadowSchemaPath` | `process.cwd() + '/model/'` | Path to the compiled schema |
|
|
94
|
+
| `FullMeadowSchemaFilename` | `'MeadowModel-Extended.json'` | Compiled model filename |
|
|
95
|
+
| `AutoStartOrator` | `true` | Start the HTTP server automatically |
|
|
96
|
+
| `APIServerPort` | `8080` | Port for the HTTP server |
|
|
97
|
+
|
|
98
|
+
## SQLite Example
|
|
99
|
+
|
|
100
|
+
For embedded or test scenarios, use the in-memory SQLite provider:
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
const libMeadowConnectionSQLite = require('meadow-connection-sqlite');
|
|
104
|
+
|
|
105
|
+
const _Fable = new libFable({
|
|
106
|
+
APIServerPort: 8086,
|
|
107
|
+
SQLite: { SQLiteFilePath: ':memory:' }
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
_Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
|
|
111
|
+
_Fable.serviceManager.addServiceType('MeadowSQLiteProvider', libMeadowConnectionSQLite);
|
|
112
|
+
_Fable.serviceManager.instantiateServiceProvider('MeadowSQLiteProvider');
|
|
113
|
+
|
|
114
|
+
_Fable.MeadowSQLiteProvider.connectAsync(
|
|
115
|
+
(pError) =>
|
|
116
|
+
{
|
|
117
|
+
_Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
|
|
118
|
+
StorageProvider: 'SQLite',
|
|
119
|
+
StorageProviderModule: 'meadow-connection-sqlite',
|
|
120
|
+
FullMeadowSchemaPath: `${__dirname}/model/`,
|
|
121
|
+
FullMeadowSchemaFilename: 'MeadowModel-Extended.json'
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
_Fable.RetoldDataService.initializeService(
|
|
125
|
+
(pError) =>
|
|
126
|
+
{
|
|
127
|
+
console.log('REST API running with in-memory SQLite');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Behavior Injection
|
|
133
|
+
|
|
134
|
+
Add custom logic before or after any CRUD operation:
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
_Fable.MeadowEndpoints.Book.controller.BehaviorInjection.setBehavior(
|
|
138
|
+
'Create-PreOperation',
|
|
139
|
+
(pRequest, pRequestState, fRequestComplete) =>
|
|
140
|
+
{
|
|
141
|
+
if (!pRequestState.RecordToCreate.Title)
|
|
142
|
+
{
|
|
143
|
+
pRequest.CommonServices.sendCodedResponse(
|
|
144
|
+
pRequestState.response, 400, 'Title is required');
|
|
145
|
+
return fRequestComplete(true);
|
|
146
|
+
}
|
|
147
|
+
return fRequestComplete(false);
|
|
148
|
+
});
|
|
149
|
+
```
|
|
4
150
|
|
|
5
|
-
##
|
|
151
|
+
## Lifecycle Hooks
|
|
6
152
|
|
|
7
|
-
|
|
153
|
+
Customize initialization by subclassing:
|
|
8
154
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* Hybrid (configuration plus endpoint)
|
|
12
|
-
|
|
13
|
-
## Configuration-Driven Mode
|
|
14
|
-
|
|
15
|
-
The service looks for a `Retold` stanza in the configuration. For instance:
|
|
16
|
-
|
|
17
|
-
```
|
|
155
|
+
```javascript
|
|
156
|
+
class MyDataService extends libRetoldDataService
|
|
18
157
|
{
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
158
|
+
onAfterInitialize(fCallback)
|
|
159
|
+
{
|
|
160
|
+
this.fable.log.info('Injecting custom behaviors...');
|
|
161
|
+
this.fable.MeadowEndpoints.Book.controller.BehaviorInjection
|
|
162
|
+
.setBehavior('Read-PostOperation', myCustomHook);
|
|
163
|
+
return fCallback();
|
|
164
|
+
}
|
|
24
165
|
}
|
|
25
166
|
```
|
|
26
167
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
* `MeadowModel`
|
|
30
|
-
* `MeadowEntitySchema`
|
|
31
|
-
* `StrictureDDL`
|
|
168
|
+
## DAL Access
|
|
32
169
|
|
|
33
|
-
|
|
170
|
+
Query data directly alongside the REST endpoints:
|
|
34
171
|
|
|
35
|
-
|
|
172
|
+
```javascript
|
|
173
|
+
let tmpQuery = _Fable.DAL.Book.query
|
|
174
|
+
.addFilter('Genre', 'Science Fiction')
|
|
175
|
+
.addSort({ Column: 'PublicationYear', Direction: 'Descending' })
|
|
176
|
+
.setCap(25)
|
|
177
|
+
.setBegin(0);
|
|
36
178
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
179
|
+
_Fable.DAL.Book.doReads(tmpQuery,
|
|
180
|
+
(pError, pQuery, pRecords) =>
|
|
181
|
+
{
|
|
182
|
+
console.log(`Found ${pRecords.length} sci-fi books`);
|
|
183
|
+
});
|
|
41
184
|
```
|
|
42
185
|
|
|
43
|
-
|
|
186
|
+
## Backplane Endpoints
|
|
44
187
|
|
|
45
|
-
|
|
188
|
+
For dynamic model loading at runtime, Retold Data Service provides backplane endpoints:
|
|
46
189
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
190
|
+
| Endpoint | Method | Description |
|
|
191
|
+
|----------|--------|-------------|
|
|
192
|
+
| `/BackPlane/:Version/Load/MeadowModel` | POST | Load a full Meadow model |
|
|
193
|
+
| `/BackPlane/:Version/Load/MeadowSchema` | POST | Load a Meadow entity schema |
|
|
194
|
+
| `/BackPlane/:Version/Load/StrictureDDL` | POST | Load and compile a Stricture DDL |
|
|
195
|
+
| `/BackPlane/:Version/Model/Primary/` | GET | Get the primary service model |
|
|
196
|
+
| `/BackPlane/:Version/Model/Composite/` | GET | Get composite models |
|
|
197
|
+
| `/BackPlane/:Version/Settings` | POST | Merge in provider settings |
|
|
198
|
+
| `/BackPlane/:Version/SetProvider/:Name` | GET | Set the default provider |
|
|
199
|
+
| `/BackPlane/:Version/SetProvider/:Name/:Entity` | GET | Set a per-entity provider |
|
|
50
200
|
|
|
51
|
-
|
|
201
|
+
## Testing
|
|
52
202
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
POST /BackPlane/${VERSION}/Load/StrictureDDL
|
|
203
|
+
```bash
|
|
204
|
+
npm test
|
|
56
205
|
```
|
|
57
206
|
|
|
58
|
-
|
|
207
|
+
Tests use an in-memory SQLite provider and require no external database server.
|
|
59
208
|
|
|
209
|
+
## Documentation
|
|
60
210
|
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
GET /BackPlane/${VERSION}/Model/Primary/
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
GET /BackPlane/${VERSION}/Model/Composite/
|
|
211
|
+
Detailed documentation is available in the `docs/` folder and can be served locally:
|
|
67
212
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
POST /BackPlane/${VERSION}/Settings
|
|
213
|
+
```bash
|
|
214
|
+
npx docsify-cli serve docs
|
|
71
215
|
```
|
|
72
216
|
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
GET /BackPlane/${VERSION}/SetProvider/:ProviderName
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### Set an Entity-Specific Provider
|
|
79
|
-
```
|
|
80
|
-
GET /BackPlane/${VERSION}/SetProvider/:ProviderName/:Entity
|
|
81
|
-
```
|
|
217
|
+
## Related Packages
|
|
82
218
|
|
|
219
|
+
- [meadow](https://github.com/stevenvelozo/meadow) - Data access and ORM
|
|
220
|
+
- [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) - Auto-generated REST endpoints
|
|
221
|
+
- [orator](https://github.com/stevenvelozo/orator) - API server abstraction
|
|
222
|
+
- [fable](https://github.com/stevenvelozo/fable) - Application services framework
|
|
83
223
|
|
|
224
|
+
## License
|
|
84
225
|
|
|
226
|
+
MIT
|
|
85
227
|
|
|
228
|
+
## Contributing
|
|
86
229
|
|
|
230
|
+
Pull requests are welcome. For details on our code of conduct, contribution process, and testing requirements, see the [Retold Contributing Guide](https://github.com/stevenvelozo/retold/blob/main/docs/contributing.md).
|
package/docs/.nojekyll
ADDED
|
File without changes
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Retold Data Service
|
|
2
|
+
|
|
3
|
+
Retold Data Service is an all-in-one module that combines Fable, Meadow, Orator, and Meadow Endpoints into a single service. Given a compiled Stricture schema, it automatically creates a data access layer (DAL) and RESTful API endpoints for every entity in your model.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Schema-Driven** — load a compiled Stricture model and get full CRUD endpoints for every table automatically
|
|
8
|
+
- **Pluggable Storage** — configure any Meadow-compatible provider (MySQL, SQLite, MSSQL, ALASQL) via options
|
|
9
|
+
- **Fable Service** — extends `fable-serviceproviderbase`, integrating with the Fable ecosystem for logging, configuration, and service management
|
|
10
|
+
- **Lifecycle Hooks** — override `onBeforeInitialize`, `onInitialize`, and `onAfterInitialize` for custom startup logic
|
|
11
|
+
- **Behavior Injection** — add pre- and post-operation hooks to any CRUD endpoint
|
|
12
|
+
- **DAL Access** — query your data directly through `fable.DAL.<Entity>` for programmatic access alongside the REST API
|
|
13
|
+
- **Auto-Start** — optionally start the Orator web server automatically on initialization
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
const libFable = require('fable');
|
|
19
|
+
const libRetoldDataService = require('retold-data-service');
|
|
20
|
+
|
|
21
|
+
const _Fable = new libFable({
|
|
22
|
+
Product: 'MyApp',
|
|
23
|
+
APIServerPort: 8086,
|
|
24
|
+
MySQL: {
|
|
25
|
+
Server: '127.0.0.1',
|
|
26
|
+
Port: 3306,
|
|
27
|
+
User: 'root',
|
|
28
|
+
Password: 'secret',
|
|
29
|
+
Database: 'mydb',
|
|
30
|
+
ConnectionPoolLimit: 20
|
|
31
|
+
},
|
|
32
|
+
MeadowConnectionMySQLAutoConnect: true
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
_Fable.serviceManager.addServiceType('RetoldDataService', libRetoldDataService);
|
|
36
|
+
_Fable.serviceManager.instantiateServiceProvider('RetoldDataService', {
|
|
37
|
+
FullMeadowSchemaPath: `${__dirname}/model/`,
|
|
38
|
+
FullMeadowSchemaFilename: 'MeadowModel-Extended.json',
|
|
39
|
+
StorageProvider: 'MySQL',
|
|
40
|
+
StorageProviderModule: 'meadow-connection-mysql',
|
|
41
|
+
AutoStartOrator: true
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
_Fable.RetoldDataService.initializeService(
|
|
45
|
+
(pError) =>
|
|
46
|
+
{
|
|
47
|
+
if (pError) return console.error('Startup failed:', pError);
|
|
48
|
+
console.log('Data service running on port 8086');
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Installation
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npm install retold-data-service
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Related Packages
|
|
59
|
+
|
|
60
|
+
| Package | Purpose |
|
|
61
|
+
|---------|---------|
|
|
62
|
+
| [fable](https://github.com/stevenvelozo/fable) | Core service framework |
|
|
63
|
+
| [meadow](https://github.com/stevenvelozo/meadow) | Data access layer and ORM |
|
|
64
|
+
| [foxhound](https://github.com/stevenvelozo/foxhound) | Query DSL for SQL generation |
|
|
65
|
+
| [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) | REST endpoint generation |
|
|
66
|
+
| [orator](https://github.com/stevenvelozo/orator) | API server abstraction |
|
|
67
|
+
| [stricture](https://github.com/stevenvelozo/stricture) | Schema definition DDL compiler |
|
|
68
|
+
| [retold-harness](https://github.com/stevenvelozo/retold-harness) | Application harness using Retold Data Service |
|
|
69
|
+
|
|
70
|
+
## Testing
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
npm test
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Tests run against an in-memory SQLite database and require no external services.
|
package/docs/_sidebar.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
- Getting Started
|
|
2
|
+
- [Introduction](/)
|
|
3
|
+
- [Architecture](architecture.md)
|
|
4
|
+
- [Configuration](configuration.md)
|
|
5
|
+
- Usage
|
|
6
|
+
- [Initialization](initialization.md)
|
|
7
|
+
- [Endpoints](endpoints.md)
|
|
8
|
+
- [DAL Access](dal-access.md)
|
|
9
|
+
- [Behavior Injection](behavior-injection.md)
|
|
10
|
+
- Advanced
|
|
11
|
+
- [Lifecycle Hooks](lifecycle-hooks.md)
|
|
12
|
+
- [Storage Providers](storage-providers.md)
|
|
13
|
+
- [Schema Definition](schema-definition.md)
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
Retold Data Service orchestrates several Retold modules into a unified service that turns a schema into a running API.
|
|
4
|
+
|
|
5
|
+
## Component Stack
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
┌─────────────────────────────────────────────┐
|
|
9
|
+
│ Your Application Code │
|
|
10
|
+
│ - Configure options │
|
|
11
|
+
│ - Override lifecycle hooks │
|
|
12
|
+
│ - Inject behaviors │
|
|
13
|
+
└──────────────────┬──────────────────────────┘
|
|
14
|
+
│
|
|
15
|
+
┌──────────────────▼──────────────────────────┐
|
|
16
|
+
│ Retold Data Service │
|
|
17
|
+
│ - Loads Stricture model │
|
|
18
|
+
│ - Creates DAL per entity │
|
|
19
|
+
│ - Creates MeadowEndpoints per entity │
|
|
20
|
+
│ - Manages service lifecycle │
|
|
21
|
+
└──────────────────┬──────────────────────────┘
|
|
22
|
+
│
|
|
23
|
+
┌──────────────────▼──────────────────────────┐
|
|
24
|
+
│ Orator (API Server) │
|
|
25
|
+
│ - HTTP server via Restify │
|
|
26
|
+
│ - Route registration │
|
|
27
|
+
│ - Request handling │
|
|
28
|
+
└──────────────────┬──────────────────────────┘
|
|
29
|
+
│
|
|
30
|
+
┌──────────────────▼──────────────────────────┐
|
|
31
|
+
│ Meadow Endpoints (REST Layer) │
|
|
32
|
+
│ - CRUD route handlers │
|
|
33
|
+
│ - Behavior injection hooks │
|
|
34
|
+
│ - Session management │
|
|
35
|
+
│ - Authorization enforcement │
|
|
36
|
+
└──────────────────┬──────────────────────────┘
|
|
37
|
+
│
|
|
38
|
+
┌──────────────────▼──────────────────────────┐
|
|
39
|
+
│ Meadow (Data Access) │
|
|
40
|
+
│ - Schema management │
|
|
41
|
+
│ - Query building via FoxHound │
|
|
42
|
+
│ - Provider-based query execution │
|
|
43
|
+
│ - Audit stamping and soft deletes │
|
|
44
|
+
└──────────────────┬──────────────────────────┘
|
|
45
|
+
│
|
|
46
|
+
┌──────────────────▼──────────────────────────┐
|
|
47
|
+
│ Storage Provider │
|
|
48
|
+
│ MySQL │ SQLite │ MSSQL │ ALASQL │
|
|
49
|
+
└─────────────────────────────────────────────┘
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## How It Works
|
|
53
|
+
|
|
54
|
+
1. **Registration** — `RetoldDataService` is registered with Fable's service manager and instantiated with options
|
|
55
|
+
2. **Server Setup** — Orator and its Restify service server are registered and configured
|
|
56
|
+
3. **Initialization** — calling `initializeService()` triggers an ordered sequence:
|
|
57
|
+
- `onBeforeInitialize()` — your custom pre-initialization logic
|
|
58
|
+
- Orator web server start (if `AutoStartOrator` is true)
|
|
59
|
+
- Persistence engine initialization (loads the storage provider module)
|
|
60
|
+
- `onInitialize()` — your custom initialization logic
|
|
61
|
+
- Data endpoint initialization (loads model, creates DALs and endpoints)
|
|
62
|
+
- `onAfterInitialize()` — your custom post-initialization logic
|
|
63
|
+
4. **Serving** — the Restify server listens for HTTP requests and routes them through Meadow Endpoints to the DAL
|
|
64
|
+
|
|
65
|
+
## Key Objects
|
|
66
|
+
|
|
67
|
+
After initialization, these objects are available on the Fable instance:
|
|
68
|
+
|
|
69
|
+
| Object | Type | Description |
|
|
70
|
+
|--------|------|-------------|
|
|
71
|
+
| `fable.RetoldDataService` | Service | The data service instance |
|
|
72
|
+
| `fable.Orator` | Service | The Orator API server |
|
|
73
|
+
| `fable.OratorServiceServer` | Service | The Restify server |
|
|
74
|
+
| `fable.DAL.<Entity>` | Meadow | DAL for each entity in the model |
|
|
75
|
+
| `fable.MeadowEndpoints.<Entity>` | MeadowEndpoints | Endpoint controller for each entity |
|
|
76
|
+
|
|
77
|
+
## Service Provider Pattern
|
|
78
|
+
|
|
79
|
+
Retold Data Service follows the Fable service provider pattern:
|
|
80
|
+
|
|
81
|
+
```javascript
|
|
82
|
+
const libFableServiceProviderBase = require('fable-serviceproviderbase');
|
|
83
|
+
|
|
84
|
+
class RetoldDataService extends libFableServiceProviderBase
|
|
85
|
+
{
|
|
86
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
87
|
+
{
|
|
88
|
+
super(pFable, pOptions, pServiceHash);
|
|
89
|
+
this.serviceType = 'RetoldDataService';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
This means it inherits logging, configuration access, and service lifecycle management from the base class.
|