Skip to content

Commit

Permalink
Use fetch
Browse files Browse the repository at this point in the history
Known issues: ArangoDB rejects FormData (Foxx).
  • Loading branch information
pluma4345 committed Mar 26, 2024
1 parent 8019fa0 commit 4255067
Show file tree
Hide file tree
Showing 33 changed files with 837 additions and 1,234 deletions.
59 changes: 59 additions & 0 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,65 @@ Note that ArangoDB may reject non-normalized unicode names and identifiers.
This change is intended to make it easier to recognize normalization issues in
code interacting with ArangoDB that were previously masked by arangojs.

### Request and Response changes

Version 9 now uses native `fetch` in all environments. This means that the
request and response objects exposed by ArangoJS now extend the fetch API's
`Request` and `Response` objects rather than those from Node's `http` module
and ArangoJS no longer provides the `agentOptions` or `agent` config options.

#### Config changes

The relevant `agentOptions` have been moved up into the `config` type and
in most cases renamed:

```diff
const db = new Database({
url: "http://localhost:8529",
- agentOptions: {
- maxSockets: 10,
- keepAlive: true,
- before: (req) => console.log(String(new Date()), 'requesting', req.url),
- after: (res) => console.log(String(new Date()), 'received', res.request.url)
- }
+ poolSize: 10,
+ keepalive: true,
+ beforeRequest: (req) => console.log(String(new Date()), 'requesting', req.url),
+ afterResponse: (res) => console.log(String(new Date()), 'received', res.request.url)
});
```

If you need to modify the request agent beyond what is possible using the fetch
API, you can override Node's default `fetch` Agent using the `undici` module:

```js
const { Agent, setGlobalDispatcher } = require("undici");

setGlobalDispatcher(
new Agent({
// your agent options here
})
);
```

Note that you will have to add `undici` as a dependency to your project. There
is currently no built-in way to override these options in Node.js without this
module.

#### Request and Response objects

This change mostly affects code that uses the `db.route` API to perform
arbitrary requests to the ArangoDB HTTP API.

```diff
const myFoxxApi = db.route('my/foxx');
const res = await myFoxxApi.get();
- const token = res.headers['x-auth-token'];
- if (res.statusCode === 200) console.log(res.body);
+ const token = res.headers.get('x-auth-token');
+ if (res.status === 200) console.log(res.parsedBody);
```

## v7 to v8

Version 8 drops support for Internet Explorer 11 and Node.js 10 and 12. If you
Expand Down
49 changes: 26 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,36 +282,39 @@ environment and may need to be explicitly told you are targetting Node instead.

### Node.js with self-signed HTTPS certificates

If you need to support self-signed HTTPS certificates, you may have to add
your certificates to the `agentOptions`, e.g.:
If you need to support self-signed HTTPS certificates in Node.js, you may have
to override the global fetch agent. At the time of this writing, there is no
official way to do this for the native `fetch` implementation in Node.js.

```diff
const { Database } = require("arangojs");
However as Node.js uses the `undici` module for its `fetch` implementation
internally, you can override the global agent by adding `undici` as a
dependency to your project and using its `setGlobalDispatcher` as follows:

const db = new Database({
url: ARANGODB_SERVER,
+ agentOptions: {
+ ca: [
+ fs.readFileSync(".ssl/sub.class1.server.ca.pem"),
+ fs.readFileSync(".ssl/ca.pem")
+ ]
+ },
});
```js
const { Agent, setGlobalDispatcher } = require("undici");

setGlobalDispatcher(
new Agent({
ca: [
fs.readFileSync(".ssl/sub.class1.server.ca.pem"),
fs.readFileSync(".ssl/ca.pem"),
],
})
);
```

Although this is **strongly discouraged**, it's also possible to disable
HTTPS certificate validation entirely, but note this has
**extremely dangerous** security implications:

```diff
const { Database } = require("arangojs");
```js
const { Agent, setGlobalDispatcher } = require("undici");

const db = new Database({
url: ARANGODB_SERVER,
+ agentOptions: {
+ rejectUnauthorized: false
+ },
});
setGlobalDispatcher(
new Agent({
rejectUnauthorized: false,
})
);
```

When using arangojs in the browser, self-signed HTTPS certificates need to
Expand Down Expand Up @@ -348,11 +351,11 @@ Transactions have
in a cluster.

When using arangojs in a cluster with load balancing, you may need to adjust
the value of `agentOptions.maxSockets` to accommodate the number of transactions
the value of `config.poolSize` to accommodate the number of transactions
you need to be able to run in parallel. The default value is likely to be too
low for most cluster scenarios involving frequent streaming transactions.

**Note**: When using a high value for `agentOptions.maxSockets` you may have
**Note**: When using a high value for `config.poolSize` you may have
to adjust the maximum number of threads in the ArangoDB configuration using
[the `server.maximal-threads` option](https://www.arangodb.com/docs/3.7/programs-arangod-server.html#server-threads)
to support larger numbers of concurrent transactions on the server side.
Expand Down
8 changes: 2 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@
],
"main": "build/index.js",
"browser": {
"./src/lib/btoa.ts": "./src/lib/btoa.web.ts",
"./src/lib/bytelength.ts": "./src/lib/bytelength.web.ts",
"./src/lib/joinPath.ts": "./src/lib/joinPath.web.ts",
"./src/lib/multipart.ts": "./src/lib/multipart.web.ts",
"./src/lib/request.ts": "./src/lib/request.web.ts"
"./src/lib/joinPath.ts": "./src/lib/joinPath.web.ts"
},
"files": [
"**/*",
Expand Down Expand Up @@ -78,7 +74,7 @@
"babel-eslint": "^10.1.0",
"babel-loader": "^9.1.3",
"babel-preset-env": "^1.7.0",
"chai": "^5.1.0",
"chai": "^4.4.1",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.1.3",
Expand Down
56 changes: 30 additions & 26 deletions src/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* @packageDocumentation
*/
import { AqlLiteral, AqlQuery, isAqlLiteral, isAqlQuery } from "./aql";
import { ArangoApiResponse, Params } from "./connection";
import { ArangoApiResponse } from "./connection";
import { ArrayCursor, BatchedArrayCursor } from "./cursor";
import { Database } from "./database";
import {
Expand Down Expand Up @@ -3604,7 +3604,7 @@ export class Collection<T extends Record<string, any> = any>
return computedValue;
});
}
const qs: Params = {};
const qs: Record<string, any> = {};
if (typeof waitForSyncReplication === "boolean") {
qs.waitForSyncReplication = waitForSyncReplication ? 1 : 0;
}
Expand Down Expand Up @@ -3655,7 +3655,7 @@ export class Collection<T extends Record<string, any> = any>
this._name
)}/recalculateCount`,
},
(res) => res.body.result
(res) => res.parsedBody.result
);
}

Expand Down Expand Up @@ -3704,7 +3704,7 @@ export class Collection<T extends Record<string, any> = any>
this._name
)}/loadIndexesIntoMemory`,
},
(res) => res.body.result
(res) => res.parsedBody.result
);
}

Expand Down Expand Up @@ -3740,7 +3740,7 @@ export class Collection<T extends Record<string, any> = any>
)}/responsibleShard`,
body: document,
},
(res) => res.body.shardId
(res) => res.parsedBody.shardId
);
}

Expand All @@ -3766,7 +3766,7 @@ export class Collection<T extends Record<string, any> = any>
headers,
},
(res) => {
if (ifNoneMatch && res.statusCode === 304) {
if (ifNoneMatch && res.status === 304) {
throw new HttpError(res);
}
return true;
Expand Down Expand Up @@ -3819,10 +3819,10 @@ export class Collection<T extends Record<string, any> = any>
allowDirtyRead,
},
(res) => {
if (ifNoneMatch && res.statusCode === 304) {
if (ifNoneMatch && res.status === 304) {
throw new HttpError(res);
}
return res.body;
return res.parsedBody;
}
);
if (!graceful) return result;
Expand All @@ -3844,7 +3844,7 @@ export class Collection<T extends Record<string, any> = any>
body: data,
qs: options,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3856,7 +3856,7 @@ export class Collection<T extends Record<string, any> = any>
body: data,
qs: options,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3878,7 +3878,7 @@ export class Collection<T extends Record<string, any> = any>
body: newData,
qs: opts,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3893,7 +3893,7 @@ export class Collection<T extends Record<string, any> = any>
body: newData,
qs: options,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3915,7 +3915,7 @@ export class Collection<T extends Record<string, any> = any>
body: newData,
qs: opts,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3932,7 +3932,7 @@ export class Collection<T extends Record<string, any> = any>
body: newData,
qs: options,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3949,7 +3949,7 @@ export class Collection<T extends Record<string, any> = any>
headers,
qs: opts,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand All @@ -3964,7 +3964,7 @@ export class Collection<T extends Record<string, any> = any>
body: selectors,
qs: options,
},
(res) => (options?.silent ? undefined : res.body)
(res) => (options?.silent ? undefined : res.parsedBody)
);
}

Expand Down Expand Up @@ -4030,7 +4030,7 @@ export class Collection<T extends Record<string, any> = any>
edgeCollection: this._name,
},
},
(res) => res.body.result
(res) => res.parsedBody.result
);
}
//#endregion
Expand All @@ -4044,7 +4044,8 @@ export class Collection<T extends Record<string, any> = any>
body: { type, collection: this._name },
},
(res) =>
new BatchedArrayCursor(this._db, res.body, res.arangojsHostUrl).items
new BatchedArrayCursor(this._db, res.parsedBody, res.arangojsHostUrl)
.items
);
}

Expand All @@ -4059,7 +4060,8 @@ export class Collection<T extends Record<string, any> = any>
},
},
(res) =>
new BatchedArrayCursor(this._db, res.body, res.arangojsHostUrl).items
new BatchedArrayCursor(this._db, res.parsedBody, res.arangojsHostUrl)
.items
);
}

Expand All @@ -4070,7 +4072,7 @@ export class Collection<T extends Record<string, any> = any>
path: "/_api/simple/any",
body: { collection: this._name },
},
(res) => res.body.document
(res) => res.parsedBody.document
);
}

Expand All @@ -4089,7 +4091,8 @@ export class Collection<T extends Record<string, any> = any>
},
},
(res) =>
new BatchedArrayCursor(this._db, res.body, res.arangojsHostUrl).items
new BatchedArrayCursor(this._db, res.parsedBody, res.arangojsHostUrl)
.items
);
}

Expand All @@ -4103,7 +4106,7 @@ export class Collection<T extends Record<string, any> = any>
collection: this._name,
},
},
(res) => res.body.document
(res) => res.parsedBody.document
);
}

Expand Down Expand Up @@ -4166,7 +4169,7 @@ export class Collection<T extends Record<string, any> = any>
collection: this._name,
},
},
(res) => res.body.documents
(res) => res.parsedBody.documents
);
}

Expand All @@ -4190,7 +4193,7 @@ export class Collection<T extends Record<string, any> = any>
path: "/_api/index",
qs: { collection: this._name },
},
(res) => res.body.indexes
(res) => res.parsedBody.indexes
);
}

Expand Down Expand Up @@ -4242,7 +4245,8 @@ export class Collection<T extends Record<string, any> = any>
},
},
(res) =>
new BatchedArrayCursor(this._db, res.body, res.arangojsHostUrl).items
new BatchedArrayCursor(this._db, res.parsedBody, res.arangojsHostUrl)
.items
);
}

Expand All @@ -4252,7 +4256,7 @@ export class Collection<T extends Record<string, any> = any>
method: "PUT",
path: `/_api/collection/${this._name}/compact`,
},
(res) => res.body
(res) => res.parsedBody
);
}
//#endregion
Expand Down
Loading

0 comments on commit 4255067

Please sign in to comment.