- A single executable file (written in Go);
- HTTP/JSON access, with client libraries for convenience;
- Directly call
ws4sqliteon a database (as above), many options available using a YAML companion file; - [In-memory DBs] are supported (https://germ.gitbook.io/ws4sqlite/documentation/configuration-file#path);
- Serving of multiple databases in the same server instance;
- Batching of multiple value sets for a single statement;
- Parameters may be passed to statements positionally (lists) or by name (maps);
- Results of queries may be returned as key-value maps, or as values lists;
- All queries of a call are executed in a transaction;
- For each query/statement, specify if a failure should rollback the whole transaction, or the failure is limited to that query;
- "Stored Statements": define SQL in the server, and call it from the client;
- CORS mode, configurable per-db;
- Scheduled tasks, cron-like and/or at startup, also configurable per-db;
- Scheduled tasks can be: backup (with rotation), vacuum and/or a set of SQL statements;
- Provide initialization statements to execute when a DB is created;
- WAL mode enabled by default, can be disabled;
- Embedded web server to directly serve web pages that can access ws4sqlite without CORS;- Quite fast!
- Compact codebase (~850 lines of code);
- Comprehensive test suite (
make do-test); - Docker images, both for amd64 and arm32.
- Authentication can be configured
- on the client, either using HTTP Basic Authentication or specifying the credentials in the request;
- on the server, either by specifying credentials (also with hashed passwords) or providing a query to look them up in the db itself;
- customizable
Not Authorizederror code (if 401 is not optimal)
- A database can be opened in read-only mode (only queries will be allowed);
- It's possible to enforce using only stored statements, to avoid some forms of SQL injection and receiving SQL from the client altogether;
- CORS Allowed Origin can be configured and enforced;
- It's possible to bind to a network interface, to limit access.
Some design choices:
- Very thin layer over SQLite. Errors and type translation, for example, are those provided by the SQLite driver;
- Doesn't include HTTPS, as this can be done easily (and much more securely) with a reverse proxy;
- Doesn't support SQLite extensions, to improve portability.