This package implements a standalone HTTP server with a Condict GraphQL API. The server can be started programmatically through the CondictHttpServer
class, or through the condict-server
command-line interface, and supports minimal configuration. The server uses an Apollo server to implement the GraphQL protocol, and the schema and its resolvers come from @condict/server.
This file does not document the GraphQL queries and mutations that Condict exposes. For that, examine the schema of a running server through introspection queries, or visit the source files in the graphql-schema folder.
Load a config file and start a server:
import {CondictHttpServer, loadConfigFile} from '@condict/http-server';
import {CondictServer, createLogger} from '@condict/server';
async function main() {
const config = loadConfigFile('config.json');
const logger = createLogger(config.log);
const server = new CondictServer(logger, config);
const httpServer = await CondictHttpServer.startNew(server, config.http);
// The HTTP server is now ready to accept connections
// Close the server when it's no longer needed
await httpServer.stop();
}
The CondictHttpServer
class is a standalone HTTP server with minimal configuration. It uses an ApolloServer
under the hood, and uses a CondictServer
to manage database access, get the executable schema, and other tasks. This class is designed to be easy to use, not to be flexible or perfect for every situation.
Full documentation on the underlying server is available on the Apollo server website. To summarise:
- Condict's HTTP server listens on its configured port (default: 4000).
- The route
GET /
returns a GraphQL sandbox, where you can execute operations and explore the schema. - The route
POST /
accepts GraphQL operations in accordance with the spec. - The route
/events
is used for WebSocket connections that wish to receive real-time events with dictionary changes. This is not a GraphQL subscription, but a custom solution. The upgrade request must include appropriate authentication headers: unauthenticated users cannot subscribe to dictionary events.
In addition, for user authentication, the default HTTP server uses the custom request header X-Condict-Session-Id
, which is set to the session ID returned by the logIn
mutation. See more under @condict/server > Users.
startNew(server: CondictServer, config: HttpOptions): Promise<CondictHttpServer>
Creates a new CondictHttpServer
from an underlying Condict server and the specified HTTP options. The HTTP server will use the same logger as the Condict server. If the CondictServer
is not already started, this function will start it. When the promise resolves, the server will be started and ready to accept connections.
The promise is rejected if the server could not be started for any reason, including if the database file is inaccessible or if the HTTP port is already occupied. In that case, the CondictServer
is always stopped, regardless of whether it was already running or not.
stop(): Promise<void>
Stops the server. The underlying Apollo server is stopped first, followed by the Condict server. The Condict server is stopped even if it was already running when the CondictHttpServer
was constructed.
loadConfigFile(fileName: string): HttpServerConfig
Loads a server configuration from a JSON file. This function reads the file synchronously, so will block until the file has been parsed and processed. The JSON file contents are described under Configuration.
If the config file is invalid, the function throws an error.
The command-line interface for Condict exposes commands for starting a standalone server and managing users. When run without a command name, condict-server
simply starts the server.
Commands:
condict-server start
condict-server add-user
condict-server edit-user
condict-server log-out-user
condict-server delete-user
Running condict-server
without a command name is equivalent to condict-server start
.
Global arguments:
-c <file>
/--config=<file>
: Specifies the file name of the configuration file.
This can be used with all commands. It can come before or after the command name.
Starts the server. The server will stay running until it is terminated by Ctrl+C/SIGINT or SIGTERM.
condict-server start
Adds a user to the database. The program will prompt for omitted user details.
If there is already a user with the specified name, or if the password is invalid, the process exits with the code 1.
condict-server add-user [-p <password>] [[-n] <name>]
-n <name>
/--name=<name>
: The name of the user to create. If omitted, the program will prompt for it.-p <password>
/--password=<password>
: The password of the new user. If omitted, the program will prompt for it.
Edits an existing user. This command can rename a user and change their password, by name or ID. If the options specify at least one of -n
/--new-name
or -p
/--new-password
, then the other is not prompted for. If both are omitted, the program prompts for both. Editing a user does not invalidate existing sessions.
If there is a user with the new name, or if the new password is invalid, the process exits with the code 1.
condict-server edit-user [-n <new-name>] [-p <new-password>] (--id <id> | [-u] <name>)
-u <name>
/--user=<name>
: The name of the user to edit. Cannot be combined with--id
.--id=<id>
: The ID of the user to edit. Cannot be combined with a username.-n <new-name>
/--new-name=<new-name>
: The name to rename the user to.-p <new-password>
/--new-password=<new-password>
: The new password to assign the user.
Terminates every session associated with the specified user. This method is used to force the user to log out, for example in case credentials have been compromised.
Note: This command is spelled log-out-user
, not logout-user
.
condict-server log-out-user (--id <id> | [-u] name)
-u <name>
/--user=<name>
: The name of the user to log out. Cannot be combined with--id
.--id=<id>
: The ID of the user to log out. Cannot be combined with a username.
Deletes a user. This command can delete a user by name or ID. If there is no user matching the supplied name or ID, the process exits with the code 2. If any other error occurs, the exit code is 1.
condict-server delete-user (--id <id> | [-u] <name>)
-u <name>
/--user=<name>
: The name of the user to delete. Cannot be combined with--id
.--id=<id>
: The ID of the user to delete. Cannot be combined with a username.
Configuration files are JSON files with the following structure:
database
: An object:file
: The path to the SQLite file containing the dictionary database.
log
: An optional object:stdout
: The highest log level that will be written to stdout, orfalse
to disable stdout logging.true
is an alias for'debug'
(everything written to stdout). If omitted, defaults tofalse
in production and'debug'
in development (based on the environment variableNODE_ENV
).files
: An array of objects that specify log files to write to:path
: The path to the log file.level
: The highest log level that will be written to the file. If omitted or null, defaults to'info'
.
http
: An optional object:port
: The port that the HTTP server will listen on. This must be a number between 1 and 65535, inclusive. If omitted or null, defaults to4000
.
The recognised log levels, from lowest to highest, are:
'error'
'warn'
'info'
'verbose'
'debug'