Repository navigation
Quick Start
This page builds a small JSON API with a path parameter, middleware, a
database and graceful shutdown. It assumes CWIST is installed (see
Installation) and pkg-config can find cwist.pc.
/* main.c */
#include <cwist/app.h>
static void hello(cwist_http_request *req, cwist_http_response *res) {
CWIST_UNUSED(req);
cwist_sstring_assign(res->body, "Hello from CWIST!");
}
int main(void) {
cwist_app *app = cwist_app_create();
cwist_app_get(app, "/", hello);
cwist_app_listen(app, 8080);
cwist_app_destroy(app);
return 0;
}cc -std=c17 -o server main.c $(pkg-config --cflags --libs --static cwist)
./server &
curl http://127.0.0.1:8080/cwist_app_listen() blocks until SIGTERM, SIGINT or
cwist_shutdown_request(). By default it forks one worker process per online
CPU core and serves with the reactor; see Server Modes and
Configuration and Environment.
#include <cwist/app.h>
#include <cwist/core/utils/json_builder.h>
static void get_user(cwist_http_request *req, cwist_http_response *res) {
const char *id = cwist_query_map_get(req->path_params, "id");
const char *fields = cwist_query_map_get(req->query_params, "fields"); /* NULL if absent */
cwist_json_builder *jb = cwist_json_builder_create();
cwist_json_begin_object(jb);
cwist_json_add_string(jb, "id", id);
cwist_json_add_string(jb, "fields", fields ? fields : "all");
cwist_json_end_object(jb);
cwist_http_header_add(&res->headers, "Content-Type", "application/json");
cwist_sstring_assign(res->body, cwist_json_get_raw(jb));
cwist_json_builder_destroy(jb);
}Register it with cwist_app_get(app, "/users/:id", get_user);. A request to
/users/7?fields=name returns {"id":"7","fields":"name"}. See
Routing, Query Maps and JSON.
#include <cwist/sys/app/middleware.h>
cwist_app_use(app, cwist_mw_request_id(NULL)); /* X-Request-Id */
cwist_app_use(app, cwist_mw_access_log(CWIST_LOG_COMBINED));
cwist_app_use(app, cwist_mw_cors());Middleware runs in registration order around every route. See Middleware for the built-ins and for writing your own.
cwist_app_use_db(app, "app.db"); /* SQLite; ":memory:" also works */
static void list_posts(cwist_http_request *req, cwist_http_response *res) {
cJSON *rows = NULL;
cwist_error_t err = cwist_db_query(req->db, "SELECT id, title FROM posts", &rows);
if (!cwist_error_is_ok(&err)) {
res->status_code = CWIST_HTTP_INTERNAL_ERROR;
return;
}
char *json = cJSON_PrintUnformatted(rows);
cwist_sstring_assign(res->body, json);
cJSON_free(json);
cJSON_Delete(rows);
}Every request carries the app's database handle in req->db. See
Database for pools, migrations, Nuke DB and encryption, and
ORM for the query helpers.
cwist_app_use_https(app, "server.crt", "server.key");
cwist_app_use_pqc_layer(app, true); /* TLS 1.3 only, X25519MLKEM768 first */
cwist_app_use_https2(app, true); /* negotiate h2 via ALPN */
cwist_app_use_https3(app, true); /* serve HTTP/3 on the same port over UDP */See HTTPS and TLS, HTTP/2 and HTTP/3 and QUIC.
cwist_app_enable_metrics(app); /* GET /metrics in Prometheus text format */
cwist_app_enable_healthz(app); /* GET /healthz, /live, /ready */Send SIGTERM (or call cwist_shutdown_request() from any thread) and
cwist_app_listen() stops accepting, drains in-flight requests for
CWIST_DRAIN_TIMEOUT seconds (default 5) and returns. See
Graceful Shutdown and Metrics and Health.
#include <cwist/sys/app/test_client.h>
cwist_test_client *tc = cwist_test_client_create(app);
cwist_http_response *res = cwist_test_client_get(tc, "/users/7");
CWIST_ASSERT_STATUS(res, 200);
CWIST_ASSERT_BODY_CONTAINS(res, "\"id\":\"7\"");
cwist_http_response_destroy(res);
cwist_test_client_destroy(tc);See Testing.
- The 30 numbered modules under
tutorials/cover one feature each; see Examples and Tutorials. - The single-page Tutorial walks through a complete app.
-
cwist new project NAMEscaffolds a project with hot reload; see Project CLI.
CWIST wiki, written against the dev branch of c4punks/CWIST. Pages marked "Source:" are generated from files under docs/; fix those in the repository. Questions: Discord.
Getting started
- Installation
- Quick Start
- Linking
- Server Modes
- Configuration and Environment
- Project CLI
- Tutorial / Korean
- Examples and Tutorials
Guides
Core
- API Reference
- Application
- Routing
- Middleware
- Requests and Responses
- Async Handlers
- Streaming Responses
- Error Handling
- Graceful Shutdown
- Multiport
Protocols
- HTTPS and TLS
- HTTP/2
- HTTP/3 and QUIC
- WebTransport
- WebSocket
- Server-Sent Events
- gRPC Server
- gRPC Client
- Protobuf and Codegen
- GraphQL
- WebRTC DataChannels
- HTTP Clients
Web features
- Static Files and Assets
- Big Dumb Reply Cache
- Compression
- Cookies
- Sessions and Flash
- Query Maps
- Multipart Uploads
- HTML Components
- Templates
- JSON
- Validation
- OpenAPI
Security
Data
Runtime
- Memory Management
- Full GC
- Async GC Ownership
- SString
- Reactor and I/O
- Metrics and Health
- Logging
- Testing
Platforms
Performance notes
- Benchmark Methodology
- C1M File Limits
- Reactor Fairness
- Cooperative Queuing
- Classic Pool Starvation
- Reactor Wakeup
- wrk Dual Histogram
- FIXED Endpoint Cache
- ADR-0001
- Durable Queue Gate
- Mux References
Project