meadow 2.0.23 → 2.0.27
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 +110 -141
- package/docs/README.md +34 -230
- package/docs/_cover.md +14 -0
- package/docs/_sidebar.md +44 -12
- package/docs/_topbar.md +5 -0
- package/docs/api/doCount.md +109 -0
- package/docs/api/doCreate.md +132 -0
- package/docs/api/doDelete.md +101 -0
- package/docs/api/doRead.md +122 -0
- package/docs/api/doReads.md +136 -0
- package/docs/api/doUndelete.md +98 -0
- package/docs/api/doUpdate.md +129 -0
- package/docs/api/getRoleName.md +84 -0
- package/docs/api/loadFromPackage.md +153 -0
- package/docs/api/marshalRecordFromSourceToObject.md +92 -0
- package/docs/api/query.md +133 -0
- package/docs/api/rawQueries.md +197 -0
- package/docs/api/reference.md +117 -0
- package/docs/api/setAuthorizer.md +103 -0
- package/docs/api/setDefault.md +90 -0
- package/docs/api/setDefaultIdentifier.md +84 -0
- package/docs/api/setDomain.md +56 -0
- package/docs/api/setIDUser.md +91 -0
- package/docs/api/setJsonSchema.md +92 -0
- package/docs/api/setProvider.md +87 -0
- package/docs/api/setSchema.md +107 -0
- package/docs/api/setScope.md +68 -0
- package/docs/api/validateObject.md +119 -0
- package/docs/architecture.md +316 -0
- package/docs/audit-tracking.md +226 -0
- package/docs/configuration.md +317 -0
- package/docs/providers/meadow-endpoints.md +306 -0
- package/docs/providers/mongodb.md +319 -0
- package/docs/providers/postgresql.md +312 -0
- package/docs/providers/rocksdb.md +297 -0
- package/docs/query-dsl.md +269 -0
- package/docs/quick-start.md +384 -0
- package/docs/raw-queries.md +193 -0
- package/docs/retold-catalog.json +61 -1
- package/docs/retold-keyword-index.json +15860 -4839
- package/docs/soft-deletes.md +224 -0
- package/package.json +44 -13
- package/scripts/bookstore-seed-postgresql.sql +135 -0
- package/scripts/dgraph-test-db.sh +144 -0
- package/scripts/meadow-test-cleanup.sh +5 -1
- package/scripts/mongodb-test-db.sh +98 -0
- package/scripts/postgresql-test-db.sh +124 -0
- package/scripts/solr-test-db.sh +135 -0
- package/source/Meadow.js +5 -0
- package/source/providers/Meadow-Provider-DGraph.js +679 -0
- package/source/providers/Meadow-Provider-MeadowEndpoints.js +1 -1
- package/source/providers/Meadow-Provider-MongoDB.js +527 -0
- package/source/providers/Meadow-Provider-PostgreSQL.js +361 -0
- package/source/providers/Meadow-Provider-RocksDB.js +1300 -0
- package/source/providers/Meadow-Provider-Solr.js +726 -0
- package/test/Meadow-Provider-DGraph_tests.js +741 -0
- package/test/Meadow-Provider-MongoDB_tests.js +661 -0
- package/test/Meadow-Provider-PostgreSQL_tests.js +787 -0
- package/test/Meadow-Provider-RocksDB_tests.js +887 -0
- package/test/Meadow-Provider-SQLiteBrowser-Headless_tests.js +657 -0
- package/test/Meadow-Provider-SQLiteBrowser_tests.js +895 -0
- package/test/Meadow-Provider-Solr_tests.js +679 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Meadow is configured through the Fable settings object. All settings are passed when constructing the Fable instance and are available to Meadow and its providers at runtime.
|
|
4
|
+
|
|
5
|
+
## Core Meadow Settings
|
|
6
|
+
|
|
7
|
+
### MeadowProvider
|
|
8
|
+
|
|
9
|
+
The name of the database provider to use by default when creating new Meadow instances.
|
|
10
|
+
|
|
11
|
+
- **Type:** `String`
|
|
12
|
+
- **Default:** `'None'`
|
|
13
|
+
- **Valid values:** `'MySQL'`, `'MSSQL'`, `'PostgreSQL'`, `'SQLite'`, `'MongoDB'`, `'RocksDB'`, `'ALASQL'`, `'MeadowEndpoints'`, `'None'`
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
var _Fable = new libFable(
|
|
17
|
+
{
|
|
18
|
+
MeadowProvider: 'MySQL'
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
When set, every `libMeadow.new(_Fable, 'SomeEntity')` call automatically uses this provider. You can override it per-DAL with `meadow.setProvider('OtherProvider')`.
|
|
23
|
+
|
|
24
|
+
### MeadowRoleNames
|
|
25
|
+
|
|
26
|
+
An ordered array of role names used by the authorization system. Role indices map to positions in this array.
|
|
27
|
+
|
|
28
|
+
- **Type:** `Array<String>`
|
|
29
|
+
- **Default:**
|
|
30
|
+
```javascript
|
|
31
|
+
[
|
|
32
|
+
'Unauthenticated',
|
|
33
|
+
'User',
|
|
34
|
+
'Manager',
|
|
35
|
+
'Director',
|
|
36
|
+
'Executive',
|
|
37
|
+
'Administrator'
|
|
38
|
+
]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
var _Fable = new libFable(
|
|
43
|
+
{
|
|
44
|
+
MeadowRoleNames:
|
|
45
|
+
[
|
|
46
|
+
'Anonymous',
|
|
47
|
+
'Viewer',
|
|
48
|
+
'Editor',
|
|
49
|
+
'Admin',
|
|
50
|
+
'SuperAdmin'
|
|
51
|
+
]
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Role names are retrieved with `meadow.getRoleName(pRoleIndex)`. If the index is out of bounds, `'Unauthenticated'` (or your first role name) is returned.
|
|
56
|
+
|
|
57
|
+
### QueryThresholdWarnTime
|
|
58
|
+
|
|
59
|
+
The threshold in milliseconds for slow query warnings. When a `doReads` or `doCount` operation exceeds this time, Meadow logs a warning with the full query details.
|
|
60
|
+
|
|
61
|
+
- **Type:** `Number`
|
|
62
|
+
- **Default:** `200`
|
|
63
|
+
- **Unit:** milliseconds
|
|
64
|
+
|
|
65
|
+
```javascript
|
|
66
|
+
var _Fable = new libFable(
|
|
67
|
+
{
|
|
68
|
+
QueryThresholdWarnTime: 500
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## MySQL Connection Settings
|
|
73
|
+
|
|
74
|
+
The `MySQL` settings object configures the MySQL provider and connection pool.
|
|
75
|
+
|
|
76
|
+
| Setting | Type | Default | Description |
|
|
77
|
+
|---------|------|---------|-------------|
|
|
78
|
+
| `Server` | `String` | `'localhost'` | Database server hostname |
|
|
79
|
+
| `Port` | `Number` | `3306` | Database server port |
|
|
80
|
+
| `User` | `String` | `'root'` | Database user |
|
|
81
|
+
| `Password` | `String` | `''` | Database password |
|
|
82
|
+
| `Database` | `String` | `''` | Database name |
|
|
83
|
+
| `ConnectionPoolLimit` | `Number` | `20` | Maximum connections in the pool |
|
|
84
|
+
| `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
|
|
85
|
+
|
|
86
|
+
```javascript
|
|
87
|
+
var _Fable = new libFable(
|
|
88
|
+
{
|
|
89
|
+
MeadowProvider: 'MySQL',
|
|
90
|
+
MySQL:
|
|
91
|
+
{
|
|
92
|
+
Server: 'db.example.com',
|
|
93
|
+
Port: 3306,
|
|
94
|
+
User: 'app_user',
|
|
95
|
+
Password: 'secret',
|
|
96
|
+
Database: 'my_application',
|
|
97
|
+
ConnectionPoolLimit: 20,
|
|
98
|
+
GlobalLogLevel: 0
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## MSSQL Connection Settings
|
|
104
|
+
|
|
105
|
+
The `MSSQL` settings object configures the Microsoft SQL Server provider. The connection pool is managed by the `meadow-connection-mssql` module.
|
|
106
|
+
|
|
107
|
+
| Setting | Type | Default | Description |
|
|
108
|
+
|---------|------|---------|-------------|
|
|
109
|
+
| `Server` | `String` | `'localhost'` | Database server hostname |
|
|
110
|
+
| `Port` | `Number` | `1433` | Database server port |
|
|
111
|
+
| `User` | `String` | `'sa'` | Database user |
|
|
112
|
+
| `Password` | `String` | `''` | Database password |
|
|
113
|
+
| `Database` | `String` | `''` | Database name |
|
|
114
|
+
| `ConnectionPoolLimit` | `Number` | `20` | Maximum connections in the pool |
|
|
115
|
+
| `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
var _Fable = new libFable(
|
|
119
|
+
{
|
|
120
|
+
MeadowProvider: 'MSSQL',
|
|
121
|
+
MSSQL:
|
|
122
|
+
{
|
|
123
|
+
Server: 'sqlserver.example.com',
|
|
124
|
+
Port: 1433,
|
|
125
|
+
User: 'sa',
|
|
126
|
+
Password: 'secret',
|
|
127
|
+
Database: 'my_application',
|
|
128
|
+
ConnectionPoolLimit: 20,
|
|
129
|
+
GlobalLogLevel: 0
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## PostgreSQL Connection Settings
|
|
135
|
+
|
|
136
|
+
The `PostgreSQL` settings object configures the PostgreSQL provider.
|
|
137
|
+
|
|
138
|
+
| Setting | Type | Default | Description |
|
|
139
|
+
|---------|------|---------|-------------|
|
|
140
|
+
| `Server` | `String` | `'localhost'` | Database server hostname |
|
|
141
|
+
| `Port` | `Number` | `5432` | Database server port |
|
|
142
|
+
| `User` | `String` | `'postgres'` | Database user |
|
|
143
|
+
| `Password` | `String` | `''` | Database password |
|
|
144
|
+
| `Database` | `String` | `''` | Database name |
|
|
145
|
+
| `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
|
|
146
|
+
|
|
147
|
+
```javascript
|
|
148
|
+
var _Fable = new libFable(
|
|
149
|
+
{
|
|
150
|
+
MeadowProvider: 'PostgreSQL',
|
|
151
|
+
PostgreSQL:
|
|
152
|
+
{
|
|
153
|
+
Server: 'pg.example.com',
|
|
154
|
+
Port: 5432,
|
|
155
|
+
User: 'postgres',
|
|
156
|
+
Password: 'secret',
|
|
157
|
+
Database: 'my_application',
|
|
158
|
+
GlobalLogLevel: 0
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## MeadowEndpoints Settings
|
|
164
|
+
|
|
165
|
+
The `MeadowEndpoints` settings object configures the REST API proxy provider. This provider translates CRUD operations into HTTP requests against a remote Meadow-Endpoints server.
|
|
166
|
+
|
|
167
|
+
| Setting | Type | Default | Description |
|
|
168
|
+
|---------|------|---------|-------------|
|
|
169
|
+
| `ServerProtocol` | `String` | `'http'` | Protocol (`'http'` or `'https'`) |
|
|
170
|
+
| `ServerAddress` | `String` | `'127.0.0.1'` | Remote server hostname |
|
|
171
|
+
| `ServerPort` | `String` | `'8086'` | Remote server port |
|
|
172
|
+
| `ServerEndpointPrefix` | `String` | `'1.0/'` | URL prefix for API endpoints |
|
|
173
|
+
|
|
174
|
+
```javascript
|
|
175
|
+
var _Fable = new libFable(
|
|
176
|
+
{
|
|
177
|
+
MeadowProvider: 'MeadowEndpoints',
|
|
178
|
+
MeadowEndpoints:
|
|
179
|
+
{
|
|
180
|
+
ServerProtocol: 'https',
|
|
181
|
+
ServerAddress: 'api.example.com',
|
|
182
|
+
ServerPort: '443',
|
|
183
|
+
ServerEndpointPrefix: '1.0/'
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## SQLite Settings
|
|
189
|
+
|
|
190
|
+
SQLite is configured through the `meadow-connection-sqlite` connection module. The connection provider manages the `better-sqlite3` database instance.
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
var _Fable = new libFable(
|
|
194
|
+
{
|
|
195
|
+
MeadowProvider: 'SQLite'
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
var libMeadowConnectionSQLite = require('meadow-connection-sqlite');
|
|
199
|
+
var tmpConnection = libMeadowConnectionSQLite.new(_Fable);
|
|
200
|
+
tmpConnection.connectAsync(':memory:');
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
SQLite supports both file-based databases (pass a file path) and in-memory databases (pass `':memory:'`).
|
|
204
|
+
|
|
205
|
+
## MongoDB Settings
|
|
206
|
+
|
|
207
|
+
The `MongoDB` settings object configures the MongoDB provider.
|
|
208
|
+
|
|
209
|
+
| Setting | Type | Default | Description |
|
|
210
|
+
|---------|------|---------|-------------|
|
|
211
|
+
| `URL` | `String` | `''` | MongoDB connection URL |
|
|
212
|
+
| `Database` | `String` | `''` | Database name |
|
|
213
|
+
| `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all query bodies |
|
|
214
|
+
|
|
215
|
+
```javascript
|
|
216
|
+
var _Fable = new libFable(
|
|
217
|
+
{
|
|
218
|
+
MeadowProvider: 'MongoDB',
|
|
219
|
+
MongoDB:
|
|
220
|
+
{
|
|
221
|
+
URL: 'mongodb://localhost:27017',
|
|
222
|
+
Database: 'my_application',
|
|
223
|
+
GlobalLogLevel: 0
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## RocksDB Settings
|
|
229
|
+
|
|
230
|
+
The `RocksDB` settings object configures the RocksDB key-value provider.
|
|
231
|
+
|
|
232
|
+
| Setting | Type | Default | Description |
|
|
233
|
+
|---------|------|---------|-------------|
|
|
234
|
+
| `KeyMode` | `String` | `'GUID'` | Key strategy: `'GUID'` or `'ID'` |
|
|
235
|
+
| `GlobalLogLevel` | `Number` | `0` | Set to `> 0` to trace all operations |
|
|
236
|
+
|
|
237
|
+
```javascript
|
|
238
|
+
var _Fable = new libFable(
|
|
239
|
+
{
|
|
240
|
+
MeadowProvider: 'RocksDB',
|
|
241
|
+
RocksDB:
|
|
242
|
+
{
|
|
243
|
+
KeyMode: 'GUID',
|
|
244
|
+
GlobalLogLevel: 0
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Full Example
|
|
250
|
+
|
|
251
|
+
A complete Fable settings object showing all available Meadow options:
|
|
252
|
+
|
|
253
|
+
```json
|
|
254
|
+
{
|
|
255
|
+
"MeadowProvider": "MySQL",
|
|
256
|
+
|
|
257
|
+
"MeadowRoleNames": [
|
|
258
|
+
"Unauthenticated",
|
|
259
|
+
"User",
|
|
260
|
+
"Manager",
|
|
261
|
+
"Director",
|
|
262
|
+
"Executive",
|
|
263
|
+
"Administrator"
|
|
264
|
+
],
|
|
265
|
+
|
|
266
|
+
"QueryThresholdWarnTime": 200,
|
|
267
|
+
|
|
268
|
+
"MySQL": {
|
|
269
|
+
"Server": "localhost",
|
|
270
|
+
"Port": 3306,
|
|
271
|
+
"User": "app_user",
|
|
272
|
+
"Password": "secret",
|
|
273
|
+
"Database": "my_application",
|
|
274
|
+
"ConnectionPoolLimit": 20,
|
|
275
|
+
"GlobalLogLevel": 0
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
"MSSQL": {
|
|
279
|
+
"Server": "localhost",
|
|
280
|
+
"Port": 1433,
|
|
281
|
+
"User": "sa",
|
|
282
|
+
"Password": "secret",
|
|
283
|
+
"Database": "my_application",
|
|
284
|
+
"ConnectionPoolLimit": 20,
|
|
285
|
+
"GlobalLogLevel": 0
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
"PostgreSQL": {
|
|
289
|
+
"Server": "localhost",
|
|
290
|
+
"Port": 5432,
|
|
291
|
+
"User": "postgres",
|
|
292
|
+
"Password": "secret",
|
|
293
|
+
"Database": "my_application",
|
|
294
|
+
"GlobalLogLevel": 0
|
|
295
|
+
},
|
|
296
|
+
|
|
297
|
+
"MeadowEndpoints": {
|
|
298
|
+
"ServerProtocol": "https",
|
|
299
|
+
"ServerAddress": "api.example.com",
|
|
300
|
+
"ServerPort": "443",
|
|
301
|
+
"ServerEndpointPrefix": "1.0/"
|
|
302
|
+
},
|
|
303
|
+
|
|
304
|
+
"MongoDB": {
|
|
305
|
+
"URL": "mongodb://localhost:27017",
|
|
306
|
+
"Database": "my_application",
|
|
307
|
+
"GlobalLogLevel": 0
|
|
308
|
+
},
|
|
309
|
+
|
|
310
|
+
"RocksDB": {
|
|
311
|
+
"KeyMode": "GUID",
|
|
312
|
+
"GlobalLogLevel": 0
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
Note that you only need to include configuration for the provider you are using. Including unused provider settings has no effect.
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# MeadowEndpoints Provider
|
|
2
|
+
|
|
3
|
+
> HTTP proxy to remote Meadow REST APIs using the same Meadow interface
|
|
4
|
+
|
|
5
|
+
The MeadowEndpoints provider enables client-side JavaScript to use the same Meadow CRUD interface while delegating actual data operations to a remote Meadow REST API server. Instead of connecting to a database directly, it translates Meadow operations into HTTP requests using [simple-get](https://github.com/feross/simple-get). No external connection module is required -- the HTTP transport is built in.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
### Install Dependencies
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install meadow
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
No external connection module is needed. The MeadowEndpoints provider uses `simple-get` (bundled with Meadow) for HTTP communication.
|
|
16
|
+
|
|
17
|
+
### Configure the Remote Server
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const libFable = require('fable').new(
|
|
21
|
+
{
|
|
22
|
+
MeadowEndpoints:
|
|
23
|
+
{
|
|
24
|
+
ServerProtocol: 'http',
|
|
25
|
+
ServerAddress: '127.0.0.1',
|
|
26
|
+
ServerPort: 8086,
|
|
27
|
+
ServerEndpointPrefix: '1.0/'
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Create a Meadow DAL
|
|
33
|
+
|
|
34
|
+
```javascript
|
|
35
|
+
const libMeadow = require('meadow');
|
|
36
|
+
|
|
37
|
+
const meadow = libMeadow.new(libFable, 'Book')
|
|
38
|
+
.setProvider('MeadowEndpoints')
|
|
39
|
+
.setDefaultIdentifier('IDBook')
|
|
40
|
+
.setSchema([
|
|
41
|
+
{ Column: 'IDBook', Type: 'AutoIdentity' },
|
|
42
|
+
{ Column: 'GUIDBook', Type: 'AutoGUID' },
|
|
43
|
+
{ Column: 'Title', Type: 'String', Size: '255' },
|
|
44
|
+
{ Column: 'Author', Type: 'String', Size: '128' },
|
|
45
|
+
{ Column: 'CreateDate', Type: 'CreateDate' },
|
|
46
|
+
{ Column: 'CreatingIDUser', Type: 'CreateIDUser' },
|
|
47
|
+
{ Column: 'UpdateDate', Type: 'UpdateDate' },
|
|
48
|
+
{ Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
|
|
49
|
+
{ Column: 'DeleteDate', Type: 'DeleteDate' },
|
|
50
|
+
{ Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
|
|
51
|
+
{ Column: 'Deleted', Type: 'Deleted' }
|
|
52
|
+
]);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Connection Configuration
|
|
56
|
+
|
|
57
|
+
| Setting | Type | Default | Description |
|
|
58
|
+
|---------|------|---------|-------------|
|
|
59
|
+
| `MeadowEndpoints.ServerProtocol` | string | -- | HTTP protocol (`'http'` or `'https'`) |
|
|
60
|
+
| `MeadowEndpoints.ServerAddress` | string | -- | Remote server hostname or IP address |
|
|
61
|
+
| `MeadowEndpoints.ServerPort` | number | -- | Remote server port |
|
|
62
|
+
| `MeadowEndpoints.ServerEndpointPrefix` | string | -- | URL path prefix for API endpoints (e.g., `'1.0/'`) |
|
|
63
|
+
|
|
64
|
+
### URL Construction
|
|
65
|
+
|
|
66
|
+
The provider constructs endpoint URLs from the configuration settings:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
{ServerProtocol}://{ServerAddress}:{ServerPort}/{ServerEndpointPrefix}{Scope}/{Operation}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
For example, with the default configuration and a `Book` scope:
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
http://127.0.0.1:8086/1.0/Book
|
|
76
|
+
http://127.0.0.1:8086/1.0/Books
|
|
77
|
+
http://127.0.0.1:8086/1.0/Book/42
|
|
78
|
+
http://127.0.0.1:8086/1.0/Books/Count
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## HTTP Method Mapping
|
|
82
|
+
|
|
83
|
+
Each Meadow CRUD operation maps to a standard HTTP method:
|
|
84
|
+
|
|
85
|
+
| HTTP Method | Meadow Operation | Endpoint Pattern |
|
|
86
|
+
|-------------|------------------|------------------|
|
|
87
|
+
| `POST` | Create | `/{prefix}{Scope}` |
|
|
88
|
+
| `GET` | Read | `/{prefix}{Scope}/{ID}` |
|
|
89
|
+
| `GET` | Reads | `/{prefix}{Scope}s` |
|
|
90
|
+
| `GET` | Count | `/{prefix}{Scope}s/Count` |
|
|
91
|
+
| `PUT` | Update | `/{prefix}{Scope}` |
|
|
92
|
+
| `DELETE` | Delete | `/{prefix}{Scope}/{ID}` |
|
|
93
|
+
|
|
94
|
+
This mapping follows the standard Meadow REST conventions generated by [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) on the server side.
|
|
95
|
+
|
|
96
|
+
## Cookie and Header Forwarding
|
|
97
|
+
|
|
98
|
+
The MeadowEndpoints provider forwards cookies and headers from the client to the remote server. This enables transparent authentication and session management -- if the client has an authenticated session with the server, the provider carries those credentials through on every request.
|
|
99
|
+
|
|
100
|
+
## CRUD Operations
|
|
101
|
+
|
|
102
|
+
### Create
|
|
103
|
+
|
|
104
|
+
Sends a POST request with the record data as the JSON body.
|
|
105
|
+
|
|
106
|
+
```javascript
|
|
107
|
+
meadow.doCreate(
|
|
108
|
+
meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' }),
|
|
109
|
+
(pError, pCreateQuery, pReadQuery, pRecord) =>
|
|
110
|
+
{
|
|
111
|
+
console.log('New ID:', pRecord.IDBook);
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**HTTP request:**
|
|
116
|
+
```
|
|
117
|
+
POST http://127.0.0.1:8086/1.0/Book
|
|
118
|
+
Content-Type: application/json
|
|
119
|
+
|
|
120
|
+
{ "Title": "Dune", "Author": "Frank Herbert" }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Read
|
|
124
|
+
|
|
125
|
+
Sends a GET request to retrieve a single record by identifier.
|
|
126
|
+
|
|
127
|
+
```javascript
|
|
128
|
+
meadow.doRead(
|
|
129
|
+
meadow.query.addFilter('IDBook', 42),
|
|
130
|
+
(pError, pQuery, pRecord) =>
|
|
131
|
+
{
|
|
132
|
+
console.log('Title:', pRecord.Title);
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**HTTP request:**
|
|
137
|
+
```
|
|
138
|
+
GET http://127.0.0.1:8086/1.0/Book/42
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Reads
|
|
142
|
+
|
|
143
|
+
Sends a GET request to retrieve multiple records with optional filtering and pagination.
|
|
144
|
+
|
|
145
|
+
```javascript
|
|
146
|
+
meadow.doReads(
|
|
147
|
+
meadow.query.setCap(25).setBegin(0),
|
|
148
|
+
(pError, pQuery, pRecords) =>
|
|
149
|
+
{
|
|
150
|
+
pRecords.forEach((pBook) => console.log(pBook.Title));
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**HTTP request:**
|
|
155
|
+
```
|
|
156
|
+
GET http://127.0.0.1:8086/1.0/Books
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Update
|
|
160
|
+
|
|
161
|
+
Sends a PUT request with the updated record data as the JSON body.
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
meadow.doUpdate(
|
|
165
|
+
meadow.query
|
|
166
|
+
.addFilter('IDBook', 42)
|
|
167
|
+
.addRecord({ Title: 'Updated Title' }),
|
|
168
|
+
(pError, pUpdateQuery, pReadQuery, pRecord) =>
|
|
169
|
+
{
|
|
170
|
+
console.log('Updated:', pRecord.Title);
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**HTTP request:**
|
|
175
|
+
```
|
|
176
|
+
PUT http://127.0.0.1:8086/1.0/Book
|
|
177
|
+
Content-Type: application/json
|
|
178
|
+
|
|
179
|
+
{ "IDBook": 42, "Title": "Updated Title" }
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Delete
|
|
183
|
+
|
|
184
|
+
Sends a DELETE request to soft-delete a record by identifier.
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
meadow.doDelete(
|
|
188
|
+
meadow.query.addFilter('IDBook', 42),
|
|
189
|
+
(pError, pQuery, pResult) =>
|
|
190
|
+
{
|
|
191
|
+
console.log('Deleted:', pResult);
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
**HTTP request:**
|
|
196
|
+
```
|
|
197
|
+
DELETE http://127.0.0.1:8086/1.0/Book/42
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Count
|
|
201
|
+
|
|
202
|
+
Sends a GET request to the count endpoint.
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
meadow.doCount(
|
|
206
|
+
meadow.query,
|
|
207
|
+
(pError, pQuery, pCount) =>
|
|
208
|
+
{
|
|
209
|
+
console.log('Total books:', pCount);
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**HTTP request:**
|
|
214
|
+
```
|
|
215
|
+
GET http://127.0.0.1:8086/1.0/Books/Count
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Use Case: Unified Client-Server Interface
|
|
219
|
+
|
|
220
|
+
The primary use case for MeadowEndpoints is enabling client-side JavaScript to use the same Meadow data access interface that the server uses. This means your application logic can be written once and run in either context:
|
|
221
|
+
|
|
222
|
+
```
|
|
223
|
+
Browser / Client Server
|
|
224
|
+
┌──────────────────┐ ┌──────────────────┐
|
|
225
|
+
│ Application Code │ │ Application Code │
|
|
226
|
+
│ │ │ │
|
|
227
|
+
│ Meadow DAL │ │ Meadow DAL │
|
|
228
|
+
│ Provider: │ HTTP/REST │ Provider: │
|
|
229
|
+
│ MeadowEndpoints ─┼──────────────────>│ MySQL │
|
|
230
|
+
│ │ │ │
|
|
231
|
+
└──────────────────┘ └──────────────────┘
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
- **Server side:** Meadow uses a database provider (MySQL, MSSQL, PostgreSQL, etc.) to interact with the database directly
|
|
235
|
+
- **Client side:** Meadow uses MeadowEndpoints to proxy the same operations over HTTP to the server's REST API
|
|
236
|
+
- **Application code:** Identical CRUD calls in both environments
|
|
237
|
+
|
|
238
|
+
This pattern is especially powerful when combined with [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) on the server, which auto-generates REST routes from Meadow entity definitions.
|
|
239
|
+
|
|
240
|
+
## Full Setup Example
|
|
241
|
+
|
|
242
|
+
A complete working example showing client-side Meadow proxying to a remote server:
|
|
243
|
+
|
|
244
|
+
```javascript
|
|
245
|
+
const libFable = require('fable').new(
|
|
246
|
+
{
|
|
247
|
+
MeadowEndpoints:
|
|
248
|
+
{
|
|
249
|
+
ServerProtocol: 'https',
|
|
250
|
+
ServerAddress: 'api.example.com',
|
|
251
|
+
ServerPort: 443,
|
|
252
|
+
ServerEndpointPrefix: '1.0/'
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const libMeadow = require('meadow');
|
|
257
|
+
|
|
258
|
+
// Create the DAL with MeadowEndpoints provider
|
|
259
|
+
const meadow = libMeadow.new(libFable, 'Book')
|
|
260
|
+
.setProvider('MeadowEndpoints')
|
|
261
|
+
.setDefaultIdentifier('IDBook')
|
|
262
|
+
.setSchema([
|
|
263
|
+
{ Column: 'IDBook', Type: 'AutoIdentity' },
|
|
264
|
+
{ Column: 'GUIDBook', Type: 'AutoGUID' },
|
|
265
|
+
{ Column: 'Title', Type: 'String', Size: '255' },
|
|
266
|
+
{ Column: 'Author', Type: 'String', Size: '128' },
|
|
267
|
+
{ Column: 'CreateDate', Type: 'CreateDate' },
|
|
268
|
+
{ Column: 'CreatingIDUser', Type: 'CreateIDUser' },
|
|
269
|
+
{ Column: 'UpdateDate', Type: 'UpdateDate' },
|
|
270
|
+
{ Column: 'UpdatingIDUser', Type: 'UpdateIDUser' },
|
|
271
|
+
{ Column: 'DeleteDate', Type: 'DeleteDate' },
|
|
272
|
+
{ Column: 'DeletingIDUser', Type: 'DeleteIDUser' },
|
|
273
|
+
{ Column: 'Deleted', Type: 'Deleted' }
|
|
274
|
+
]);
|
|
275
|
+
|
|
276
|
+
// These calls transparently proxy to the remote server
|
|
277
|
+
meadow.doCreate(
|
|
278
|
+
meadow.query.addRecord({ Title: 'Dune', Author: 'Frank Herbert' }),
|
|
279
|
+
(pError, pCreateQuery, pReadQuery, pRecord) =>
|
|
280
|
+
{
|
|
281
|
+
console.log('Created book with ID:', pRecord.IDBook);
|
|
282
|
+
|
|
283
|
+
// Read it back from the server
|
|
284
|
+
meadow.doRead(
|
|
285
|
+
meadow.query.addFilter('IDBook', pRecord.IDBook),
|
|
286
|
+
(pError, pQuery, pRecord) =>
|
|
287
|
+
{
|
|
288
|
+
console.log('Read back:', pRecord.Title, 'by', pRecord.Author);
|
|
289
|
+
});
|
|
290
|
+
});
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Error Handling
|
|
294
|
+
|
|
295
|
+
HTTP-related errors follow the standard pattern:
|
|
296
|
+
|
|
297
|
+
- Network errors (connection refused, timeouts) are returned as `pError` in the callback
|
|
298
|
+
- HTTP error status codes (4xx, 5xx) are stored in `pQuery.parameters.result.error`
|
|
299
|
+
- Response parsing failures are logged and reported through the error callback
|
|
300
|
+
|
|
301
|
+
## Related Documentation
|
|
302
|
+
|
|
303
|
+
- [Providers Overview](providers/README.md) -- Comparison of all providers
|
|
304
|
+
- [MySQL Provider](providers/mysql.md) -- Server-side database provider
|
|
305
|
+
- [ALASQL Provider](providers/alasql.md) -- Client-side in-memory alternative
|
|
306
|
+
- [meadow-endpoints](https://github.com/stevenvelozo/meadow-endpoints) -- Server-side REST API generation
|