The primary way that JavaScript code can interact with HarperDB is through the global variables, which has several objects and classes that provide access to the tables, server hooks, and resources that HarperDB provides for building applications. As global variables, these can be directly accessed in any module.
These global variables are also available through the harperdb
module/package, which can provide better typing in TypeScript. To use this with your own directory, make sure you link the package to your current harperdb
installation:
npm link harperdb
The harperdb
package is automatically linked for all installed components. Once linked, if you are using EcmaScript module syntax you can import function from harperdb
like:
import { tables, Resource } from 'harperdb';
Or if you are using CommonJS format for your modules:
const { tables, Resource } = require('harperdb');
The global variables include:
This is an object that holds all the tables for the default database (called data
) as properties. Each of these property values is a table class that subclasses the Resource interface and provides access to the table through the Resource interface. For example, you can get a record from a table (in the default database) called 'my-table' with:
import { tables } from 'harperdb';
const { MyTable } = tables;
async function getRecord() {
let record = await MyTable.get(recordId);
}
It is recommended that you define a database for all the tables that are required to exist in your application. This will ensure that the tables exist on the tables
object. Also note that the property names follow a CamelCase convention for use in JavaScript and in the GraphQL Schemas, but these are translated to snake_case for the actual table names, and converted back to CamelCase when added to the tables
object.
This is an object that holds all the databases in HarperDB, and can be used to explicitly access a table by database name. Each database will be a property on this object, each of these property values will be an object with the set of all tables in that database. The default database, databases.data
should equal the tables
export. For example, if you want to access the "dog" table in the "dev" database, you could do so:
import { databases } from 'harperdb';
const { Dog } = databases.dev;
This is the base class for all resources, including tables and external data sources. This is provided so that you can extend it to implement custom data source providers. See the Resource API documentation for more details about implementing a Resource class.
This returns the user object with permissions/authorization information based on the provided username. If a password is provided, the password will be verified before returning the user object (if the password is incorrect, an error will be thrown).
This provides methods trace
, debug
, info
, warn
, error
, fatal
, and notify
for logging. See the logging documentation for more information.
The server
global object provides a number of functions and objects to interact with Harper's HTTP service.
Alias: server.request
Add a handler method to the HTTP server request listener middleware chain.
Returns an array of server instances based on the specified options.port
and options.securePort
.
Example:
server.http((request, next) => {
return request.url === '/graphql'
? handleGraphQLRequest(request)
: next(request);
}, {
runFirst: true, // run this handler first
});
Type: (request: Request, next: RequestListener) => Promise<Response>
The HTTP request listener to be added to the middleware chain. To continue chain execution pass the request
to the next
function such as return next(request);
.
An implementation of WHATWG Request class. This Request is designed to follow the standard as closely as possible, but has some additional properties, methods and behaviors that facilitate its use as a server API:
request.url
- This is the resource target of the request, which will includes the full path and query string that comes after the hostname and port in the URL.request.sendEarlyHints(link)
- This sends an early hints response to the client. This is useful for sending link headers to the client before the final response is sent so that browsers can preload resources. This is generally most helpful in a cache resolution function, where you can send hints if the data is not in the cache and is resolving from an origin:
class Origin {
async get(request) {
// if we are fetching data from origin, send early hints
this.getContext().requestContext.sendEarlyHints('<link rel="preload" href="/my-resource" as="fetch">');
let response = await fetch(request);
...
}
}
Cache.sourcedFrom(Origin);
An implementation of WHATWG Response class.
Type: Object
Properties:
runFirst
- optional -boolean
- Add listener to the front of the middleware chain. Defaults tofalse
port
- optional -number
- Specify which HTTP server middleware chain to add the listener to. Defaults to the Harper system default HTTP port configured byharperdb-config.yaml
, generally9926
securePort
- optional -number
- Specify which HTTPS server middleware chain to add the listener to. Defaults to the Harper system default HTTP secure port configured byharperdb-config.yaml
, generally9927
Node.js http.Server
or https.SecureServer
instance.
Creates a socket server on the specified options.port
or options.securePort
.
Only one socket server will be created. A securePort
takes precedence.
Node.js socket server connection listener as documented in net.createServer
or tls.createServer
port
- optional -number
- Specify the port for thenet.Server
instance.securePort
- optional -number
- Specify the port for thetls.Server
instance.
Node.js net.Server
or tls.Server
instance.
Add a listener to the WebSocket connection listener middleware chain. The WebSocket server is associated with the HTTP server specified by the options.port
or options.securePort
. Use the server.upgrade()
method to add a listener to the upgrade middleware chain.
Example:
server.ws((ws, request, chainCompletion) => {
chainCompletion.then(() => {
ws.on('error', console.error);
ws.on('message', function message(data) {
console.log('received: %s', data);
});
ws.send('something');
});
});
Type: (ws: WebSocket, request: Request, chainCompletion: ChainCompletion, next: WsListener): Promise<void>
The WebSocket connection listener.
- The
ws
argument is the WebSocket instance as defined by thews
module. - The
request
argument is Harper's transformation of theIncomingMessage
argument of the standard 'connection' listener event for a WebSocket server. - The
chainCompletion
argument is aPromise
of the associated HTTP server's request chain. Awaiting this promise enables the user to ensure the HTTP request has finished being processed before operating on the WebSocket. - The
next
argument is similar to that of othernext
arguments in Harper's server middlewares. To continue execution of the WebSocket connection listener middleware chain, pass all of the other arguments to this one such as:next(ws, request, chainCompletion)
Type: Object
Properties:
maxPayload
- optional -number
- Set the max payload size for the WebSocket server. Defaults to 100 MB.runFirst
- optional -boolean
- Add listener to the front of the middleware chain. Defaults tofalse
port
- optional -number
- Specify which WebSocket server middleware chain to add the listener to. Defaults to the Harper system default HTTP port configured byharperdb-config.yaml
, generally9926
securePort
- optional -number
- Specify which WebSocket secure server middleware chain to add the listener to. Defaults to the Harper system default HTTP secure port configured byharperdb-config.yaml
, generally9927
Add a listener to the HTTP Server upgrade event. If a WebSocket connection listener is added using server.ws()
, a default upgrade handler will be added as well. The default upgrade handler will add a __harperdb_request_upgraded
boolean to the request
argument to signal the connection has already been upgraded. It will also check for this boolean before upgrading and if it is true
, it will pass the arguments along to the next
listener.
This method should be used to delegate HTTP upgrade events to an external WebSocket server instance.
Example:
This example is from the HarperDB Next.js component. See the complete source code here
server.upgrade(
(request, socket, head, next) => {
if (request.url === '/_next/webpack-hmr') {
return upgradeHandler(request, socket, head).then(() => {
request.__harperdb_request_upgraded = true;
next(request, socket, head);
});
}
return next(request, socket, head);
},
{ runFirst: true }
);
Type: (request, socket, head, next) => void
The arguments are passed to the middleware chain from the HTTP server 'upgrade'
event.
Type: Object
Properties:
runFirst
- optional -boolean
- Add listener to the front of the middleware chain. Defaults tofalse
port
- optional -number
- Specify which HTTP server middleware chain to add the listener to. Defaults to the Harper system default HTTP port configured byharperdb-config.yaml
, generally9926
securePort
- optional -number
- Specify which HTTP secure server middleware chain to add the listener to. Defaults to the Harper system default HTTP secure port configured byharperdb-config.yaml
, generally9927
This provides access to the HarperDB configuration object. This comes from the harperdb-config.yaml (parsed into object form).
This records the provided value as a metric into HarperDB's analytics. HarperDB efficiently records and tracks these metrics and makes them available through analytics API. The values are aggregated and statistical information is computed when many operations are performed. The optional parameters can be used to group statistics. For the parameters, make sure you are not grouping on too fine of a level for useful aggregation. The parameters are:
value
- This is a numeric value for the metric that is being recorded. This can be a value measuring time or bytes, for example.metric
- This is the name of the metric.path
- This is an optional path (like a URL path). For a URL like /my-resource/, you would typically include a path of "my-resource", not including the id so you can group by all the requests to "my-resource" instead of individually aggregating by each individual id.method
- Optional method to group by.type
- Optional type to group by.