Sign in Join
Wiki copytemporary

SQLDBRestBridge: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11## Purpose
22
33More and more applications move to Web: today Pas2JS allows to program pascal for the web.
44
55Data needs to be stored on a server, and REST is the architecture of choice these days for doing so. Most often, the data ends up in a database.
66
77So, an easy way to make data available through a REST service is needed.
88
99The `SQLDBRestBridge` unit in *fpc/packages/fcl-web/src/restbridge/sqldbrestbridge.pp* offers a means to expose any database that can be accessed by SQLDB using a REST API.
1010
1111It is not meant as a general REST API framework, for this other frameworks exist. It is also not a RPC framework.
1212
1313The design is such that a complete database can be exposed using a single line of code, with reasonable default settings.
1414
1515### What does it do ?
1616
1717Basically, `SQLDBRestBridge` can be used in a FCL-Web application to turn it into a REST server:
1818
1919The server will then accept the usual REST GET/POST/PUT/Delete commands and automatically translate these to the appropriate database CRUD (Create/Read/Update/Delete) statements.
2020
2121It can be used simply: one line of code is enough to expose a complete database in this way.
2222
2323Or it can be completely customized and fine tuned: The schema can be completely specified: all SQL statements can be specified, field lists can be defined, aliases can be given, business rules can be implemented.
2424
2525The resulting server can be used in a client/server setup (using pas2js as a client, for example) to serve data without needing to writing all the plumbing code needed in a REST server.
2626
2727### What it does not do ?
2828
2929- This is a server-side technology.
3030
3131
3232To consume the data served by this component, you need to write a client.
3333
3434No assumptions are made about the client, except that it knows how to execute HTTP requests, and that it understands one of the available data formats.
3535
3636- This does not expose objects as REST resources.
3737
3838
3939Using some tricks, this could be done, but this is not a design goal.
4040
4141Eventually, all data ends up in a database, and this component uses a direct mechanism to achieve that.
4242
4343## Features
4444
4545### SQL Database side.
4646
47471. Every REST resource is defined by up to 4 SQL statements, corresponding to the 4 CRUD operations.
48482. The CRUD Statements can be auto generated on the fly, based on a table name and field definitions.
49493. For every field, an alias can be provided.
50504. The following client-side types are available, automatically mapped from the native database type:
5151 1. String
5252 2. 64-bit integer
5353 3. 32-bit integer
5454 4. Boolean
5555 5. Date, Time, DateTime
5656 6. Blob (base64-encoded)
57575. Support for a sequence to generate IDs is built-in.
58586. Full control over which operations (GET,POST,PUT,DELETE) are allowed.
59597. Resources are collected in a schema.
60608. Multiple schemas can be attached to the service.
61619. Multiple databases (connections) can be defined.
626210. A schema can be tied to a single connection, or connections can share a schemas (use case: a different connection per client).
636311. Business processor components can be hooked to a resource, to make it easier to implement business logic.
646412. SQL Statements can contain parameters, values for the parameters will be picked up from the request URL.
656513. Support to get custom datasets.
666614. Support for client-side provided SQL SELECT statements (optional, disabled by default)
676715. Full support for configuration through an `.ini` file out of the box.
6868
6969### HTTP side
7070
71711. Authentication is handled using the HTTP protocol.
72722. Basic authentication is included by default, but is completely pluggable.
73733. Basic authentication can look up valid users in a database (by default the database being exposed)
74744. Output format can be fixed or detected per request (`?fmt=format`). Detection based on content-type is also available.
75755. list of fields to include in output can be specified in the URL:\
7676 `fl=field1,field2`
77776. Field list of fields to exclude from output can be specified in the URL:\
7878 `fe=field1,field2`
79797. Various output formats are available out of the box
8080 1. JSON (the default)
8181 2. XML (a custom format)
8282 3. CSV (for in and output)
8383 4. CDS (Format used by Delphi `TClientDataset`)
8484 5. Planned: ADO data packets (as used by MS Access)
85858. A factory pattern is used, new formats can be added at will.
86869. Simple URL schemes. 2 basic schemes are available
8787 BASEURL/Resource/
8888 BASEURL/Resource/ID
8989
9090 or using the connection as prefix:
9191
9292 BASEURL/Connection/Resource/
9393 BASEURL/Connection/Resource/ID
949410. Support for introspection/discovery or metadata:
9595 BASEURL/metadata/
9696
9797 returns the list of available resources and their operation.
9898
9999 BASEURL/metadata/resourcename
100100
101101 returns the structure of the resource: fields, types, etc.
10210211. `limit` and `offset` parameters for paging of results:
103103 BASEURL/resourcename?limit=10
104104 BASEURL/resourcename?limit=10&Offset=50
105105
106106 A maximum limit can be enforced. When the SQL statements support it, the limit and offset are translated to SQL fetch/offset clauses.
10710712. Sort order can be specified in the request URL, if the resource definition allows it, using `?sort=fieldname`. The ability to sort can be specified on a field basis.
108108 BASEURL/resourcename?sort=MyField
109109 BASEURL/resourcename?sort=MyField%20desc
110110
111111 Multiple sort fields can be specified, separated by a comma.
11211213. Filtering can be specified on a field basis in the request URL, and the filter operation is translated to SQL Where:
113113 BASEURL/resourcename?MyField=10
114114 BASEURL/resourcename?MyField_null=1
115115 BASEURL/resourcename?MyField_null=0
116116 BASEURL/resourcename?MyField_lt=10
117117 BASEURL/resourcename?MyField_lte=10
118118 BASEURL/resourcename?MyField_gt=10
119119 BASEURL/resourcename?MyField_gte=10
120120
121121 is translated to a SQL where clause:
122122
123123 (MyField=10)
124124 (MyField is null)
125125 (MyField is not null)
126126 (MyField<10)
127127 (MyField_lte<=10)
128128 (MyField>10)
129129 (MyField>=10)
130130
131131 The ability to filter on a field can be specified in the schema for each field.
13213214. The request can specify whether metadata should be included in the response:
133133 BASEURL/resourcename?metadata=1
13413415. The request can specify whether the result should be human-readable or not
135135 BASEURL/resourcename?humanreadable=1
136136
137137 If set to 1, the request result will be formatted. Not all formats support this.
138138
139139## Available Components
140140
141141### TSQLDBRestSchema
142142
143143Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestschema.pp*
144144
145145Represents a REST schema : a list of available resources, with their allowed operations, fields definitions, SQL statements. A schema can be designed visually using a [[SQLDBRestSchemaEditor]] in a separate application or in the lazarus IDE.
146146
147147#### Properties
148148
149149- **Resources** A collection of resources. Each item is of type *TSQLDBRestResource*
150150- **ConnectionName** Set this to a connection name if you want all resources of this schema to use this connection.
151151
152152#### Methods
153153
154154- **SaveToFile** save the resource definitions to file (as JSON)
155155
156156```delphi
157157Procedure SaveToFile(Const aFileName : UTF8String);
158158```
159159
160160- **SaveToStream** save the resource definitions to stream (as JSON).
161161
162162```delphi
163163Procedure SaveToStream(Const aStream : TStream);
164164```
165165
166166- **AsJSON** return the resource definitions as a JSON object.
167167
168168```delphi
169169function AsJSON(const aPropName: UTF8String=''): TJSONData;
170170```
171171
172172If specified, **aPropName** is the name of the property below which all definitions are stored.
173173
174174- **LoadFromFile** Load the resource definitions from a JSON file.
175175
176176```delphi
177177Procedure LoadFromFile(Const aFileName : UTF8String);
178178```
179179
180180- **LoadFromStream** Load the resource definitions from a JSON file.
181181
182182```delphi
183183Procedure LoadFromStream(Const aStream : TStream);
184184```
185185
186186- **FromJSON** Load the resource definitions from a JSON file.
187187
188188```delphi
189189Procedure FromJSON(aData: TJSONData;const aPropName: UTF8String='');
190190```
191191
192192If specified, **aPropName** is the name of the property below which all definitions are located.
193193
194194- **PopulateResourceFields** create resource fields based on table name.
195195
196196```delphi
197197procedure PopulateResourceFields(aConn: TSQLConnection; aRes: TSQLDBRestResource; aMinFieldOpts : TRestFieldOptions = []);
198198```
199199
200200*PopulateResourceFields* populates the field definitions in *aRes* by checking the table in database connection *aConn*. Every created field gets at least *aMinFieldOptions* in its *Options* property.
201201
202202- **PopulateResources** creates a resource definition for each table in a database connection.
203203
204204```delphi
205205procedure PopulateResources(aConn: TSQLConnection; aTables: array of string; aMinFieldOpts: TRestFieldOptions= []);
206206Procedure PopulateResources(aConn : TSQLConnection; aTables : TStrings = Nil; aMinFieldOpts : TRestFieldOptions = []);
207207```
208208
209209- *PopulateResources* retrieves the list of tables from *aConn*, creates a resource definition for the table and calls *PopulateResourceFields* to fill the resource with fields. If *aTables* is specified, definitions will only be created for the tables in that list.
210210
211211### TSQLDBRestDispatcher
212212
213213Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestbridge.pp*
214214
215215#### Properties
216216
217217- **Active** (Boolean) Register or unregister HTTP routes.
218218- **Connections** (TSQLDBRestConnectionList) List of database connections to connect to.
219219- **Schemas** (TSQLDBRestSchemaList) List of REST schemas to serve
220220- **BasePath** (UTF8String) Base URL for REST URLS.
221221- **DefaultConnection** (UTF8String) Default connection to use if none is detected from request/schema
222222- **Strings** (TRestStringsConfig Property) Input/Output strings configurations
223223- **OutputOptions** (TRestOutputOptions) default Output options, modifiable by query. One or more of
224224
2252251. *ooMetadata* Send metadata in request
2262262. *ooSparse* Do not send null values (if format allows it)
2272273. *ooHumanReadable* Pretty-print output.
228228
229229- **InputFormat** (string) Name of Input format to use for all requests.
230230- **OutputFormat** (string) Name of Output format to use for all requests.
231231- **DispatchOptions** (TRestDispatcherOptions) Dispatcher options. One or more of
232232
2332331. *rdoConnectionInURL* Use the connection as a path element in the URL.
2342342. *rdoExposeMetadata* Expose the metadata URL.
2352353. *rdoConnectionResource* Expose the connection resource, allowing to manage connections through the REST protocol.
2362364. *rdoCustomView* allow the use of a customview URL (Select SQL specified in request)
2372375. *rdoEmptyCorsDomainToOrigin* if the CORDAllowedOrigins is empty, then the request server will be echoed to the client.
2382386. *rdoHandleCORS* Handle CORS preflight request.
2392397. *rdoAccessCheckNeedsDB* This controls when the access check is done for resources: before or after a connection with the database is made. If you need to make additional queries on a database to decide whether access is granted (such as checking ACLs in the Db) then this option should be enabled.
240240
241241- **AdminUserIDs** A list of user IDs (one per line) which are allowed to use the connection resource. If empty, all users can use it.
242242- **LogOptions** Logging options. Logging happens through the OnLog event handler. This property controls which events are logged. The following values can be specified:
243243
2442441. *rloUser* Include username in log messages, when available
2452452. *rtloHTTP* Log HTTP request (remote, URL)
2462463. *rloResource* Log resource requests (operation, resource)
2472474. *rloConnection* Log database connections (connect to database)
2482485. *rloAuthentication* Log authentication attempt
2492496. *rloSQL* Log SQL statements. (not on user-supplied connection)
2502507. *rloResultStatus* Log result status.
251251
252252- **LogSQLOptions** SQL Logging options. if rloSQL is specified, this option controls which SQLDB events are logged for new connections.
253253- **Authenticator** (TRestAuthenticator) Authenticator for requests. If *OnBasicAuthentication* is set, this can be left empty.
254254- **EnforceLimit** (Integer) If larger than zero, Enforce a limit on output results.
255255- **CORSAllowedOrigins** (String) Comma separated list of Domains that are allowed to use this REST service. If empty, * will be returned in preflight request.
256256- **CORSMaxAge** (Integer) Value for HTTP *Access-Control-Max-Age* header. If zero, the header is not sent.
257257- **CORSAllowCredentials** (Boolean) value for HTTP header *Access-Control-Allow-Credentials*. Set to false not to send the header
258258
259259#### Methods
260260
261261- **ExposeDatabase** exposes a database as a REST service. This will creates a connection definition with the provided parameters and calls **ExposeConnection** with this definition.
262262 ```delphi
263263 Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : Array of String; aMinFieldOp
264264 Function ExposeDatabase(Const aType,aHostName,aDatabaseName,aUserName,aPassword : String; aTables : TStrings = nil; aMinFieldOpt
265265 ```
266266
267267 The connection gets the name **ConnectionN**, where N is a unique number, and the schema is named **SchemaConnectionN**. The Tables and aMinFieldOpt arguments are the same as in the *PopulateResources* call of **TSQLDBRestSchema**
268268- **ExposeConnection** exposes a database (represented by *aConnection*) as a REST service. This will create a schema with a resource definition.
269269 ```delphi
270270 Function ExposeConnection(Const aConnection : TSQLDBRestConnection; aTables : TStrings = nil; aMinFieldOpts : TRestFieldOptions
271271 ```
272272
273273 The Tables and aMinFieldOpt arguments are the same as in the *PopulateResources* call of **TSQLDBRestSchema**
274274
275275### TRestBasicAuthenticator
276276
277277Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestauth.pp*
278278
279279This class implements HTTP Basic authentication for the SQLDB REST Dispatcher
280280
281281- AuthConnection (TSQLConnection) a SQL connection that will be used to run the SQL. By default the connection of the request is used. Set this if your users are in a separate database.
282282- AuthenticateUserSQL (TStrings) an SQL Statement that will be executed on the connection (AuthConnection or connection of the request). This must contain 2 parameters **userName** and **password** and return a single field. This field will be used as **UserID** (available in the rest of the request flow.
283283- DefaultUserName (UTF8String) a valid username, not in the database.
284284- DefaultPassword (UTF8String) password of a default user.
285285- DefaultUserID (UTF8String) the user ID reported if the default user is authenticated.
286286- AuthenticationRealm : (UTF8String) Real sent in the **WWW-Authenticate** challenge to the client.
287287- OnBasicAuthentication (event) triggered when basic authentication is requested. Here you can enter custom code to validate the user.
288288
289289### TSQLDBRestModule
290290
291291Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestmodule.pp*
292292
293293- This is a simple **TWebModule** descendant which is usable in Lazarus IDE. It has a single *Dispatcher* property which must be set to a **TSQLDBRestDispatcher** instance.
294294
295295### TSQLDBRestResource
296296
297297Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestschema.pp*
298298
299299This is a collection item, found in the 'Resources' property of the **TSQLDBRestSchema**. It represents a single REST resource.
300300
301301#### properties
302302
303303It has the following properties:
304304
305305- **Fields** (TSQLDBRestFieldList) A list of fields that will be included in the output, or can be supplied in the input.
306306- **Enabled** (Boolean) Is this resource enabled ?
307307- **InMetadata** (Boolean) Should this resource be shown in the metadata list ?
308308- **ConnectionName** (UTF8String) Connection name to use for this resource.
309309- **TableName** (UTF8String) Database table name. This must only be specified if the SQL is auto generated.
310310- **ResourceName** (UTF8String) Name of this resource as exposed to the outside world.
311311- **AllowedOperations** (TRestOperations) The operations allowed on this resources (Get/Put/Post/Delete/Options/Head)
312312- **SQLSelect** (TStrings) SQL select statement for a GET request. Left empty, it is autogenerated based on the table name. The where clause uses the fields with the *foInKey* flag set for single resources.
313313- **SQLInsert** (TStrings) SQL INSERT statement for a POST request. Left empty, it is autogenerated based on the table name.
314314- **SQLUpdate** (TStrings) SQL UPDATE statement for a PUT request. Left empty, it is autogenerated based on the table name. The where clause uses the fields with the *foInKey* flag set.
315315- **SQLDelete** (TStrings) SQL DELETE statement for a DELETE request. Left empty, it is autogenerated based on the table name. The where clause uses the fields with the *foInKey* flag set.
316316- *'SQL* an array of SQL statements, based on the previous ones.
317317- **BusinessProcessor** (TSQLDBRestCustomBusinessProcessor) at runtime this contains the business processor for this resource (if any)
318318
319319#### Events
320320
321321The following events are available:
322322
323323- **OnResourceAllowed** (TSQLDBRestAllowResourceEvent) Called to check whether the user is allowed to access this resource.
324324- **OnAllowedOperations** (TSQLDBRestAllowedOperationsEvent) Called to allow to fine-tune the allowed operations for the user.
325325- **OnGetDataset** (TSQLDBRestGetDatasetEvent) You can return a custom dataset for GET operations.
326326- **OnCheckParams** (TSQLDBRestCheckParamsEvent) You can check the INSERT/UPDATE/DELETE SQL Statement parameters in this request/
327327- **OnAllowRecord** (TSQLDBRestAllowRecordEvent) Called for each record, you can ddecide whether the record should be included in the output.
328328
329329Note: when set, the corresponding event in the business processor is not triggered.
330330
331331#### Methods
332332
333333The following methods exist:
334334
335-` Function GetDataset(aContext : TBaseRestContext; aFieldList : TRestFieldPairArray; aOrderBy : TRestFieldOrderPairArray; aLimit, aOffset : Int64) : TDataset;`
335+``` pascal
336+ Function GetDataset(aContext : TBaseRestContext; aFieldList : TRestFieldPairArray; aOrderBy : TRestFieldOrderPairArray; aLimit, aOffset : Int64) : TDataset;
337+```
336338
337339Get the custom dataset for this resource.
338340
339-` function GenerateDefaultSQL(aKind: TSQLKind): UTF8String; virtual;`
341+``` pascal
342+ function GenerateDefaultSQL(aKind: TSQLKind): UTF8String; virtual;
343+```
340344
341345Get the default SQL for this resource if none was specified.
342346
343-` function GetFieldList(aListKind: TFieldListKind): UTF8String;`
347+``` pascal
348+ function GetFieldList(aListKind: TFieldListKind): UTF8String;
349+```
344350
345351Return a list of fields as a string, separated by a correct separator token
346352
347-` function GetFieldArray(aListKind: TFieldListKind): TSQLDBRestFieldArray;`
353+``` pascal
354+ function GetFieldArray(aListKind: TFieldListKind): TSQLDBRestFieldArray;
355+```
348356
349357Return a list of fields, similar to GetFieldList, but returns the raw fields.
350358
351-` Function GetResolvedSQl(aKind : TSQLKind; Const AWhere : UTF8String; Const aOrderBy : UTF8String = `*`; aLimit : UTF8String =`*`) : UTF8String;`
359+``` pascal
360+ Function GetResolvedSQl(aKind : TSQLKind; Const AWhere : UTF8String; Const aOrderBy : UTF8String = ; aLimit : UTF8String = ) : UTF8String;
361+```
352362
353363Return the actual SQL Statement that will be executed, with macros
354364
355-` Procedure PopulateFieldsFromFieldDefs(Defs : TFieldDefs; aIndexFields : TStringArray; aProcessIdentifier : TProcessIdentifier; aMinFieldOpts : TRestFieldOptions);`
365+``` pascal
366+ Procedure PopulateFieldsFromFieldDefs(Defs : TFieldDefs; aIndexFields : TStringArray; aProcessIdentifier : TProcessIdentifier; aMinFieldOpts : TRestFieldOptions);
367+```
356368
357369Populate the fields collection from a TFieldDefs collection.
358370
359371### TSQLDBRestField
360372
361373Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestschema.pp*
362374
363375The TSQLDBREstResource has a collection of fields (TSQLDBRestField) that determine the output fields of the REST resource
364376
365377It has the following properties;
366378
367379- FieldName (UTF8String Read FFieldName Write FFieldName;
368380- PublicName (UTF8String Read GetPublicName Write FPublicName;
369381- GeneratorName (String) name of a generator to privide a unique value.
370382- FieldType (TRestFieldType) Data type of the exposed field.One of (the names speak for themselves)
371383 - rftInteger
372384 - rftLargeInt
373385 - rftFloat
374386 - rftDate
375387 - rftTime
376388 - rftDateTime
377389 - rftString
378390 - rftBoolean
379391 - rftBlob (sent as base64-encoded data)
380392- NativeFieldType (TFieldType) Native database field type of this field.
381393- Options (TRestFieldOptions) options for this field. One of more of:
382394 - foInKey This is a key field.
383395 - foInInsert The field can be inserted (if statement is autogenerated)
384396 - foInUpdate The field can be updated (if statement is autogenerated)
385397 - foRequired A field value is required.
386398 - foFilter Filtering is allowed on this field.
387399 - foOrderBy Ordering is allowed on this field.
388400 - foOrderByDesc Ordering (descendent) is allowed on this field.
389401- Filters (TRestFieldFilters) Allowed filter expressions for this field. One or more of:
390402 - rfEqual
391403 - rfLessThan
392404 - rfGreaterThan
393405 - rfLessThanEqual
394406 - rfGreaterThanEqual
395407 - rfNull
396408- MaxLen (integer) for string fields, the maximum allowed length of the field.
397409
398410### TSQLDBRestBusinessProcessor
399411
400412Unit: *fpc/packages/fcl-web/src/restbridge/sqldbrestschema.pp*
401413
402414This class serves to implement any business rules you want to attach to your rest resource. You can drop one TSQLDBRestBusinessProcessor instance per resource on a module, set the schema and resource name (a list of resource names is available in the Object Inspector) and implement the events.
403415
404416The following properties and events are available:
405417
406418- **Schema** : The schema in which the resource resides.
407419- **ResourceName** The resource for which the business rules are valid.
408420- **OnGetDataset** : Event called when you want to create a custom dataset. You must free the dataset yourself.
409421- **OnCheckParams** : Event in which you can verify whether the parameters for insert/update/delete/select queries are OK.
410422- **OnAllowResource** : Event to decide whether a property is allowed for a request. You can use this e.g. to forbid certain users from accessing a resource.
411423- **OnAllowedOperations** : Event to decide whether a REST operation is allowed for a request. You can use this to forbid certain users from writing to a resource, but allow them to read.
412424- **OnAllowRecord** : Called for each record which will be output. This can be used to prevent certain records from being streamed to the output. Note that if *Limit* is specified, this will not be taken into account, i.e. if the limit is 10, and you forbid 2 records from being streamed at this point, only 8 records will be returned.
413425
414426All calls get passed a TRestContext instance. This contains 2 properties and a method:
415427
416-`  Function GetVariable(Const aName : UTF8String; aSources : TVariableSources; Out aValue : UTF8String) : Boolean;`
428+``` pascal
429+ Function GetVariable(Const aName : UTF8String; aSources : TVariableSources; Out aValue : UTF8String) : Boolean;
430+```
417431
418432Call this to get a HTTP Query variable, header,... The function returns true if the variable was found.
419433
420-`  Property UserID : UTF8String`
434+```text
435+ Property UserID : UTF8String
436+```
421437
422438This will be set when calling.
423439
424-`  Property Data : TObject`
440+```text
441+ Property Data : TObject
442+```
425443
426444You can attach data to this if you want to. It will be kept for the duration of the request. You are responsible for freeing this data, though.
427445
428446## Special Resources
429447
430448### metaData
431449
432450The */baseURL/metaData* resource lists all the resources defined in the schema, together with the allowed operations.
433451
434452The usual formats and parameters are supported.
435453
436454### metaData/resourceName
437455
438456The */baseURL/metaData/resourceName* resource lists all the fields in the **resourceName** resource, together with the properties.
439457
440458The usual formats and parameters are supported for this resource.
441459
442460### customview
443461
444462The customView resource is special. Its availability must be enabled using the *Dispatcher*'s Options. When *rdoCustomView* is included in the options, the
445463
446-` baseURL/customView`
464+```text
465+ baseURL/customView
466+```
447467
448468URL becomes available. It allows the client to specify an SQL Select statement using the *SQL* parameter:
449469
450-` baseURL/customView?SQL=select count(*) as thecount from person`
470+```text
471+ baseURL/customView?SQL=select count(*) as thecount from person
472+```
451473
452474(you must encode the sql using the usual URI encoding mechanism, it is omitted for readability reasons here) The usual parameters for fieldlists, format are supported, but not the *limit* and *offset* parameters.
453475
454476The engine will check that only SELECT statements passed on. Nevertheless, this is an inherently less safe mechanism which should only be used in case of need.
455477
456478### _connection
457479
458480This is a resource that allows you to manage the connections through REST. This can be useful in development environments, where you can simply create a single binary that does not need any configuration, the whole configuration can be done through REST, including the management of the available connections.
459481
460482Because this is security-wise a dangerous option to enable, it is disabled by default, and must be enabled explicitly with the *rdoConnectionResource* option of the dispatcher.
461483
462484Use cases are a development environment where this can be used to confiure the restserver from within the IDE. When moving to production, the option can be disabled, and only fixed and known connections will be allowed/
463485
464486## Available Output formats
465487
466488### JSON (the default)
467489
468490- A simple JSON object encapsulating data, metadata and possibly error nodes.
469491- rows are exported as JSON objects, field names are property names of the object.
470492- Name: 'json'
471493- Content-type: 'application/json'
472494- Input and output.
473495- Data by default under 'data'
474496- Metadata by default under 'metaData'
475497- Errors reported under 'error'
476498- Property names are configurable in REST dispatcher.
477499
478500### XML (a custom format)
479501
480502- A simple XML document encapsulating data, metadata and possibly error nodes, under a root element 'datapacket'
481503- rows are exported as XML elements (named 'row') , the contents as text in the element.
482504- Name: 'xml'
483505- Content-type: 'text/xml'
484506- Input and output.
485507- Data by default under 'data'
486508- Metadata by default under 'metadata'
487509- Errors reported under 'error'
488510- Element names are configurable in REST dispatcher.
489511
490512### CSV
491513
492514- Simple comma-separated CSV list.
493515- Name: 'csv'
494516- Content-type: 'text/csv'
495517- Input and output.
496518- Separator: Comma
497519- Quotes when needed.
498520- Metadata means first line contains fieldnames.
499521
500522### CDS
501523
502524- XML package using the XMLFormat used by Delphi `TClientDataset`.
503525- Name: 'cds'
504526- Content-type: 'text/csv'
505527- Input and output.
506528
507529A Delphi demo program is provided.
508530
509531### ADO
510532
511533- XML format as used by ADO recordsets (as used by MS Access)
512534- Name: 'ado'
513535- Input and output.
514536
515537## Ini file Support
516538
517539The following classes can load/save their configuration settings from/to an .ini file
518540
519541- TSQLDBRestDispatcher
520542- TRestBasicAuthenticator
521543- TSQLDBRestConnection
522544- TRestStringsConfig
523545
524546The support for this is implemented in 2 units;
525547
526548- the sqldbauthini unit has a type helper for the TRestBasicAuthenticator class.
527549- The sqldbrestini unit has the type helpers for TSQLDBRestDispatcher and TSQLDBRestConnection and TRestStringsConfig.
528550
529551The helpers implement LoadFromFile/SaveToFile methods, as well as LoadFromIni/SaveToIni methods. There are some options to control the level of depth.
530552
531553The schemas (if so required) are saved as JSON files in the same directory as the .ini file, using the name of the schema as the filename.
532554
533555## Lazarus Support
534556
535557Requires Lazarus 2.1+
536558
537559Lazarus support for the SQLDB REST Bridge is implemented in 2 packages under the **components/sqldbrest** directory:
538560
5395611. The design/sqldbrestschemadesigner.lpk package.
5405622. The lazsqldbrest.lpk package.
541563
542564The latter package registers the **TSQLDBRestDispatcher**, **TSQLDBRestSchema** and **TRestBasicAuthenticator** components on the component palette: The former includes the schema editor. They should be compiled and installed in the order presented here.
543565
544566![](/wiki-images/d/d6/Sqldbrestcomponents.png)
545567
546568Additionally it registers some component- and property editors. In particular the GUI schema editor can be called from the **TSQLDBRestSchema** component context menu.
547569
548570The GUI schema editor is included in the IDE, it is discussed in a separate page [[SQLDBRestSchemaEditor]]
549571
550572Further integration with Lazarus is planned: 1. Let the IDE act as a REST server. (alternatively, add a tool with a menu entry under tools for easy configuration)
551573
552574Lazarus support can work with FPC 3.0.4. To make this work, the files can be copied from SVN or a 3.2 release to the lazarus components/sqldbrest/src directory.
553575
554576To this end,
555577
5565781. create a directory **src** below the **components/sqldbrest directory** (where the package is located)
5575792. copy all files in directory
558580
559-` fpc/packages/fcl-web/src/restbridge`
581+```text
582+ fpc/packages/fcl-web/src/restbridge
583+```
560584
561585
562586to the new *src* directory
563587
564-` lazarus/components/sqldbrest/src`
588+```text
589+ lazarus/components/sqldbrest/src
590+```
565591
5665921. compile the **lazarus/components/sqldbrest/design/sqldbrestschemadesigner.lpk** package. It has unitpath ../src, so it should find the files in the *src* directory.
5675932. compile the **lazarus/components/sqldbrest/lazsqldbrest.lpk** package.
568594
569595## Pas2JS Support
570596
571597The SQLDB Rest bridge will be integrated in the compile server that comes with pas2JS: This means that pas2js will come with a toll that
572598
573599- Can recompile your web project on the fly
574600- Can serve files on disc
575601- Can act as a REST server.
576602
577603So no actual server is needed during development.
578604
579605## Usage
580606
581607### In a fcl-web application.
582608
583609The rest bridge was designed to be simple to use.
584610
585611#### Expose a single database, no authentication.
586612
587613Simple expose of a database. Run the following code in the startup of your program (for example, DoRun of the web application class, or startup code of the program)
588614
589615```delphi
590616FDisp:=TSQLDBRestDispatcher.Create(Self);
591617FDisp.ExposeDatabase(
592618 'postgres','localhost','expensetracker','me','secret'
593619 ,Nil,
594620 [foFilter,foInInsert,foInUpdate,foOrderByDesc]);
595621FDisp.Active:=True;
596622FDisp.SaveToFile('demo.ini');
597623```
598624
599625This exposes all tables of the database 'expenstracker', allows to filter,update and sort on all fields. The connection will be named 'Connection1', the schema 'SchemaConnection1'
600626
601627The configuration will be saved in a file called 'demo.ini'.\
602628It can be reused to quickly set up a REST dispatcher.
603629
604630#### Expose single database, HTTP Basic authentication.
605631
606632Similar to the previous example, but with HTTP BASIC authentication for a single user:
607633
608634```delphi
609635FAuth:=TRestBasicAuthenticator.Create(Self);
610636FAuth.DefaultUserName:='me';
611637FAuth.DefaultPassword:='secret';
612638FDisp:=TSQLDBRestDispatcher.Create(Self);
613639FDisp.Authenticator:=Fauth;
614640FDisp.ExposeDatabase(
615641 'postgres','localhost','expensetracker','me','secret'
616642 ,Nil,
617643 [foFilter]);
618644FDisp.Active:=True;
619645```
620646
621647This exposes all tables of the database 'expenstracker', allows to filter,update and sort on all fields. The connection will be named 'Connection1', the schema 'SchemaConnection1'. No updates are possible: the fields will not be in update/insert statements. Sorting is also not allowed.
622648
623649#### Expose single database, HTTP Basic authentication (2)
624650
625651Smilar to the previous example, but with HTTP BASIC authentication, using the database to authenticate a user:
626652
627653```delphi
628654FAuth:=TRestBasicAuthenticator.Create(Self);
629655FAuth.AuthenticateUserSQL.Text:='select uID from users where (uLogin=:UserName) and (uPassword=:Password)';
630656FDisp:=TSQLDBRestDispatcher.Create(Self);
631657FDisp.Authenticator:=Fauth;
632658FDisp.ExposeDatabase(
633659 'postgres','localhost','expensetracker','me','secret'
634660 ,['projects','expenses'],
635661 []);
636662FDisp.Active:=True;
637663```
638664
639665Here only the 'projects' and 'expenses' tables are exposed, read-only.
640666
641667#### Using a Config file and schema files.
642668
643669Start a dispatcher, loading the file demo.ini. The dioSkipReadSchemas tells it not to load schema files, the schemas will be created from the connections.
644670
645671```delphi
646672FDisp:=TSQLDBRestDispatcher.Create(Self);
647673FDisp.LoadFromFile('demo.ini',[dioSkipReadSchemas]);
648674FDisp.Active:=True;
649675```
650676
651677The .ini file can be created using SaveToFile on a configured dispatcher instance.
652678
653679### In the lazarus IDE.
654680
655681To work in the lazarus IDE with the SQLDB Rest bridge, you must install the **lazsqldbrest** package, which can be found in the directory components/sqldbrest.
656682
657683#### Using a datamodule
658684
659685In this approach, a datamodule is created that is in memory throughout the whole lifetime of the application (fcl-web application)
660686
6616871. Create a HTTP server application or FCGI application. (a CGI will also work but is very inefficient)
6626882. Add a plain datamodule to the application.
6636893. Drop a TSQLDBRestSchema class from the 'FCL-Web' tab of the component palette
6646904. Edit the schema (property resources), or import it from file using the component editor context menu
6656915. Drop a TSQLDBRestDispatcher class from the 'FCL-Web' tab of the component palette
6666926. Edit the connections
6676937. Add an item to the Schemas property and point it to the TSQLDBRestSchema added previously
6686948. For HTTP Basic authentication, add a TRESTBAsicAuthenticator class, and set the TSQLDBRestDispatcher instance's Authentocator property to it.
669695
670696The end result should look more or less like this:
671697
672698![](/wiki-images/2/2a/Restmodule.png)
673699
674700That's it. The project is ready to run.
675701
676702#### Using a SQLDBRestdatamodule
677703
678704This approach is basically the same as the previous one.
679705
6807061. Create a HTTP application
6817072. Under File - New, create a SQLDB Rest Bridge Module.
6827083. Drop a SQLDBRestDispatcher component on the module.
6837094. The Dispatcher property of the module should be set to the SQLDBRestDispatcher component.
6847105. Set up the component as required, as in the previous example.
685711
686712## Examples
687713
688714### FPC
689715
690716- in FPC Packages, the fcl-web/examples/restbridge directory, there is a small example that serves a expenses tracker database.
691717- The directory (delphiclient) below contains a small Delphi project that shows how to connect a TClientDataset to the SQLDB Rest bridge.
692718
693719
694720Design time view:
695721
696722![](/wiki-images/9/9a/Delphirestclientdesign.png)
697723
698724Run time view:
699725
700726![](/wiki-images/7/7b/Delphirestclient.png)
701727
702728### Lazarus
703729
704730Requires Lazarus 2.1+
705731
706732There are 2 server examples available, and several client examples. The client examples are all the same, they just use a different kind of *TDataset* to show the data coming from the server: the **buf**, **json** and **CSV** formats are demonstrated in this way.
707733
708734#### Server examples
709735
710736- The lazarus/components/sqldbrest/demo/restbridge directory contains the same example program restserver.lpi, using a datamodule.
711737- The lazarus/components/sqldbrest/demo/restmodule directory contains the same example program demorestmodule.lpi, using a SQLDB Rest Web datamodule.
712738
713739#### TBufDataset client example
714740
715741- The lazarus/components/sqldbrest/demo/bufclient directory contains a demo, that shows how to load data from a SQLDB REST bridge server in a TBUFDataset dataset. It uses the 'buf' format to do so.
716742
717743
718744![](/wiki-images/2/2a/Sqldbrestbufclientdata.png)
719745
720746
721747![](/wiki-images/2/2c/Sqldbrestbufclientraw.png)
722748
723749it also demonstrates how to use the metadata resource of the server to list the available resources
724750
725751#### TJSONDataset client example
726752
727753- The lazarus/components/sqldbrest/demo/jsonclient directory contains a demo that is similar to the bufclient demo:
728754
729755
730756it shows how to load data from a SQLDB REST bridge server in a TBaseJSONDataset dataset, using the 'csv' format
731757
732758![](/wiki-images/2/29/Sqldbrestjsonclientdata.png)
733759
734760
735761![](/wiki-images/3/33/Sqldbrestjsonclientraw.png)
736762
737763Like the bufdataset demo, it also demonstrates how to use the metadata resource of the server to list the available resources
738764
739765#### TCSVDataset client example
740766
741767- The lazarus/components/sqldbrest/demo/csvclient directory contains a demo that is similar to the bufclient demo:
742768
743769
744770it shows how to load data from a SQLDB REST bridge server in a TCSVDataset dataset, using the 'csv' format
745771
746772### Pas2JS
747773
748774Requires pas2js 1.5+
749775
750776- A similar application to the lazarus buffclient/jsonclient programs exists for pas2JS in pas2js/demo/restbridge/simple/restbridgeclient.lpi
751777
752778
753779![](/wiki-images/c/ca/Sqldbrestbridgepas2js.png)
754780
755781## TODO
756782
757783The following extensions are still planned:
758784
759785- Support for `?q=filterexpression` in URL filters.
760786- Connection management API. (zero-config service)
761787- Use HTTP credentials to connect to the database.
762788- Unknown query params are now ignored. Allow to check for valid query parameters and raise error if unknown query param is encountered.
763789
764790---
765791*From the Free Pascal wiki, page "SQLDBRestBridge", as it stood on 2023-03-01 after a change by Michael, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
766792Category: Databases

Back to history