docs: every example imports what it uses
This commit is contained in:
+18
-1
@@ -3,10 +3,21 @@
|
|||||||
The core answers a plain request object, so it fits any framework:
|
The core answers a plain request object, so it fits any framework:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import pg from 'pg';
|
||||||
|
import { createREST } from '@crudy/restloom';
|
||||||
|
import { postgres } from '@crudy/restloom-postgres';
|
||||||
|
|
||||||
|
const rest = createREST({
|
||||||
|
db: postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL })),
|
||||||
|
expose: { schemas: ['app'] },
|
||||||
|
});
|
||||||
|
|
||||||
const response = await rest.handle({ method, path, query, headers, body, context });
|
const response = await rest.handle({ method, path, query, headers, body, context });
|
||||||
// { status, headers, body }
|
// { status, headers, body }
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The examples below use this `rest`.
|
||||||
|
|
||||||
`handle` never throws: every failure is a response. `path` is the path below where the API is mounted (`/todos/4`), `query` a `URLSearchParams`, `body` the parsed JSON.
|
`handle` never throws: every failure is a response. `path` is the path below where the API is mounted (`/todos/4`), `query` a `URLSearchParams`, `body` the parsed JSON.
|
||||||
|
|
||||||
## Node, without a framework
|
## Node, without a framework
|
||||||
@@ -15,7 +26,7 @@ const response = await rest.handle({ method, path, query, headers, body, context
|
|||||||
|
|
||||||
```ts
|
```ts
|
||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import { createREST, nodeListener } from '@crudy/restloom';
|
import { nodeListener } from '@crudy/restloom';
|
||||||
|
|
||||||
const api = nodeListener(rest, { prefix: '/api', context: (req) => userFrom(req) });
|
const api = nodeListener(rest, { prefix: '/api', context: (req) => userFrom(req) });
|
||||||
http.createServer(api).listen(3000);
|
http.createServer(api).listen(3000);
|
||||||
@@ -24,6 +35,8 @@ http.createServer(api).listen(3000);
|
|||||||
To serve other pages from the same server, hand only the API's paths to it:
|
To serve other pages from the same server, hand only the API's paths to it:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import http from 'node:http';
|
||||||
|
|
||||||
http.createServer((req, res) => (req.url?.startsWith('/api/') ? api(req, res) : site(req, res))).listen(3000);
|
http.createServer((req, res) => (req.url?.startsWith('/api/') ? api(req, res) : site(req, res))).listen(3000);
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -36,8 +49,10 @@ npm install @crudy/restloom-fastify
|
|||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import Fastify from 'fastify';
|
||||||
import { restloom } from '@crudy/restloom-fastify';
|
import { restloom } from '@crudy/restloom-fastify';
|
||||||
|
|
||||||
|
const app = Fastify();
|
||||||
await app.register(restloom(rest, { context: (req) => req.user }), { prefix: '/api' });
|
await app.register(restloom(rest, { context: (req) => req.user }), { prefix: '/api' });
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -50,8 +65,10 @@ npm install @crudy/restloom-express
|
|||||||
```
|
```
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import express from 'express';
|
||||||
import { restloom } from '@crudy/restloom-express';
|
import { restloom } from '@crudy/restloom-express';
|
||||||
|
|
||||||
|
const app = express();
|
||||||
app.use('/api', express.json(), restloom(rest, { context: (req) => req.user }));
|
app.use('/api', express.json(), restloom(rest, { context: (req) => req.user }));
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
+4
-2
@@ -14,9 +14,10 @@ Every dialect passes the same conformance suite, so a request answers the same r
|
|||||||
## Postgres
|
## Postgres
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import pg from 'pg';
|
||||||
import { postgres } from '@crudy/restloom-postgres';
|
import { postgres } from '@crudy/restloom-postgres';
|
||||||
|
|
||||||
const db = postgres(pool);
|
const db = postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL }));
|
||||||
```
|
```
|
||||||
|
|
||||||
- **Transactions:** every request is one transaction, `READ ONLY` for reads, with `SET LOCAL statement_timeout` from `limits.timeoutMs`.
|
- **Transactions:** every request is one transaction, `READ ONLY` for reads, with `SET LOCAL statement_timeout` from `limits.timeoutMs`.
|
||||||
@@ -76,6 +77,7 @@ const db = sqlite(new Database('app.db'));
|
|||||||
Every piece of SQL comes from one overridable method of the dialect's renderer. To change one, subclass it and pass it in:
|
Every piece of SQL comes from one overridable method of the dialect's renderer. To change one, subclass it and pass it in:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import pg from 'pg';
|
||||||
import { PostgresRenderer, postgres } from '@crudy/restloom-postgres';
|
import { PostgresRenderer, postgres } from '@crudy/restloom-postgres';
|
||||||
|
|
||||||
class Renderer extends PostgresRenderer {
|
class Renderer extends PostgresRenderer {
|
||||||
@@ -84,7 +86,7 @@ class Renderer extends PostgresRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const db = postgres(pool, { renderer: new Renderer() });
|
const db = postgres(new pg.Pool({ connectionString: process.env.DATABASE_URL }), { renderer: new Renderer() });
|
||||||
```
|
```
|
||||||
|
|
||||||
The pieces are listed in [writing a dialect](./writing-a-dialect.md).
|
The pieces are listed in [writing a dialect](./writing-a-dialect.md).
|
||||||
|
|||||||
+4
-2
@@ -55,7 +55,7 @@ resources: {
|
|||||||
import { createREST, DEFAULT_SENSITIVE } from '@crudy/restloom';
|
import { createREST, DEFAULT_SENSITIVE } from '@crudy/restloom';
|
||||||
|
|
||||||
createREST({
|
createREST({
|
||||||
db,
|
db, // from a database package, see Dialects
|
||||||
expose: { schemas: ['app'] },
|
expose: { schemas: ['app'] },
|
||||||
sensitive: new RegExp(`${DEFAULT_SENSITIVE.source}|(^|_)(iban|ssn)(_|$)`, 'i'),
|
sensitive: new RegExp(`${DEFAULT_SENSITIVE.source}|(^|_)(iban|ssn)(_|$)`, 'i'),
|
||||||
});
|
});
|
||||||
@@ -64,8 +64,10 @@ createREST({
|
|||||||
## Hooks
|
## Hooks
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { createREST, RestError } from '@crudy/restloom';
|
||||||
|
|
||||||
createREST({
|
createREST({
|
||||||
db,
|
db, // from a database package, see Dialects
|
||||||
expose: { schemas: ['app'] },
|
expose: { schemas: ['app'] },
|
||||||
hooks: {
|
hooks: {
|
||||||
authorize(request, target) { /* throw a RestError to refuse */ },
|
authorize(request, target) { /* throw a RestError to refuse */ },
|
||||||
|
|||||||
+3
-1
@@ -28,8 +28,10 @@ procedures: {
|
|||||||
For an API that writes everywhere, set `write` once, beside `expose`:
|
For an API that writes everywhere, set `write` once, beside `expose`:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import { createREST } from '@crudy/restloom';
|
||||||
|
|
||||||
createREST({
|
createREST({
|
||||||
db,
|
db, // from a database package, see Dialects
|
||||||
expose: { schemas: ['app'] },
|
expose: { schemas: ['app'] },
|
||||||
write: true,
|
write: true,
|
||||||
resources: {
|
resources: {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
A dialect implements one interface:
|
A dialect implements one interface:
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
|
import type { Catalog, RestError, SqlRenderer, Tx } from '@crudy/restloom';
|
||||||
|
|
||||||
interface Dialect {
|
interface Dialect {
|
||||||
name: string;
|
name: string;
|
||||||
capabilities: { returning: boolean; estimatedCount: boolean; rowSecurity: boolean; procedures: boolean };
|
capabilities: { returning: boolean; estimatedCount: boolean; rowSecurity: boolean; procedures: boolean };
|
||||||
|
|||||||
Reference in New Issue
Block a user