|
cwist
Modern C web framework with libttak runtime
|
GraphQL subscriptions over the graphql-ws WebSocket subprotocol (supported since v3.8). More...
#include <cwist/net/graphql/graphql.h>#include <cwist/sys/io/reactor.h>#include <cjson/cJSON.h>#include <stdbool.h>#include <stddef.h>#include <stdint.h>

Go to the source code of this file.
Typedefs | |
| typedef struct cwist_graphql_ws | cwist_graphql_ws_t |
| typedef struct cwist_graphql_event_source | cwist_graphql_event_source_t |
| typedef cwist_graphql_event_source_t *(* | cwist_graphql_subscribe_fn) (const cJSON *args, const cJSON *variables, void *ctx) |
GraphQL subscriptions over the graphql-ws WebSocket subprotocol (supported since v3.8).
Implements the graphql-transport-ws subprotocol on top of the non-blocking WebSocket transport (cwist/net/websocket/websocket_async.h): connection_init -> connection_ack, subscribe -> one next message per published event -> complete on unsubscribe, error on operation failure, and ping/pong keepalive at any time after init.
Subscription fields resolve through the same schema/resolver model as queries and mutations: a subscription resolver returns an event source (a set of broker topics) and application code fans events out with cwist_graphql_publish(). The broker is in-process and thread-safe: publish may be called from any thread; delivery to the wire happens on the owning reactor thread.
Opt-in only; no existing behavior changes when unused. Requires the C1M (callback-shaped) WebSocket path.
Definition in file graphql_ws.h.
| typedef struct cwist_graphql_event_source cwist_graphql_event_source_t |
Definition at line 34 of file graphql_ws.h.
| typedef cwist_graphql_event_source_t *(* cwist_graphql_subscribe_fn) (const cJSON *args, const cJSON *variables, void *ctx) |
Subscription field resolver. Invoked once per incoming subscribe operation (on the reactor thread).
| args | Parsed root-field arguments (cJSON object) or NULL when none. Borrowed: do not store or free. |
| variables | The subscribe message's variables member (borrowed, may be NULL). |
| ctx | Opaque pointer registered with cwist_graphql_ws_add_subscription(). |
error message). Definition at line 46 of file graphql_ws.h.
| typedef struct cwist_graphql_ws cwist_graphql_ws_t |
Definition at line 33 of file graphql_ws.h.
| bool cwist_graphql_event_source_add_topic | ( | cwist_graphql_event_source_t * | src, |
| const char * | topic | ||
| ) |
Add a topic to an event source.
Register interest in a broker topic. Events published to topic are delivered to every active subscription whose event source lists it. Returns false on invalid input or allocation failure.
Idempotent: adding a topic that is already present succeeds without duplicating it. The topic string is copied, so the caller keeps ownership of topic.
| src | Event source to modify; must not be NULL. |
| topic | Topic name to add; must be a non-empty string. |
Definition at line 76 of file graphql_ws.c.
References cap, cwist_alloc_array(), cwist_free(), and cwist_strdup().
| cwist_graphql_event_source_t * cwist_graphql_event_source_create | ( | void | ) |
Create an empty event source (topic interest set).
Create an empty event source for use as a subscription resolver's return value.
Definition at line 60 of file graphql_ws.c.
References cwist_alloc().
| void cwist_graphql_event_source_destroy | ( | cwist_graphql_event_source_t * | src | ) |
Destroy an event source, freeing all topic strings and the set.
Destroy an event source. Called automatically for active subscriptions when their operation ends (client complete, socket close) or the endpoint is destroyed.
| src | Event source to free; NULL is a no-op. |
Definition at line 101 of file graphql_ws.c.
References cap, and cwist_free().
Publish an event to the in-process broker. The payload becomes the field value inside each delivered next message's data (null when payload is NULL). Thread-safe: may be called from any thread; matched subscriptions are queued and delivered on their connection's reactor thread.
| topic | Broker topic (non-empty string). |
| payload | Event payload (borrowed) or NULL. |
next messages queued. Definition at line 468 of file graphql_ws.c.
References cap, cwist_alloc_array(), and cwist_free().
| bool cwist_graphql_ws_add_subscription | ( | cwist_graphql_ws_t * | gws, |
| const char * | field, | ||
| cwist_graphql_subscribe_fn | subscribe_fn, | ||
| void * | ctx | ||
| ) |
Register (or replace) the resolver for a subscription root field.
Register or replace a subscription field resolver on the endpoint.
If the field is already registered, its resolver and context are replaced in place; otherwise a new entry is prepended to the registry. The field name is copied.
| gws | Endpoint to register on; must not be NULL. |
| field | Subscription root field name; must be a non-empty string. |
| subscribe_fn | Resolver invoked per subscribe for field; must not be NULL. It receives the parsed arguments and variables and returns an event source (owned by the broker) or NULL to reject the operation. |
| ctx | Opaque pointer passed through to subscribe_fn. |
Definition at line 190 of file graphql_ws.c.
References cap, cwist_alloc(), cwist_free(), and cwist_strdup().
| bool cwist_graphql_ws_attach | ( | cwist_graphql_ws_t * | gws, |
| int | fd, | ||
| cwist_reactor_t * | reactor, | ||
| const uint8_t * | initial, | ||
| size_t | initial_len | ||
| ) |
Attach the graphql-ws protocol handler to a connected, upgraded fd. The fd is driven reactively by reactor (same ownership contract as cwist_websocket_async_attach): the HTTP layer must not touch the fd after a successful call.
| gws | Endpoint whose schema resolves subscriptions. |
| fd | Connected client socket (set non-blocking here). |
| reactor | Reactor that will own the connection. |
| initial | Bytes already read past the upgrade request (may be NULL). |
| initial_len | Number of valid bytes at initial. |
Definition at line 730 of file graphql_ws.c.
References cap, and cwist_websocket_async_attach_ex().
| cwist_graphql_ws_t * cwist_graphql_ws_create | ( | cwist_graphql_schema_t * | schema | ) |
Create a graphql-ws endpoint holding a subscription field registry.
Create a graphql-ws endpoint bound to schema. The schema is not owned and must outlive the endpoint.
| schema | GraphQL schema the endpoint answers to; not owned, must outlive the endpoint. |
schema is NULL or allocation fails. Free with cwist_graphql_ws_destroy(). Definition at line 144 of file graphql_ws.c.
References cap, and cwist_alloc().
| void cwist_graphql_ws_destroy | ( | cwist_graphql_ws_t * | gws | ) |
Destroy an endpoint and its subscription field registry.
Destroy an endpoint and free all subscription field registrations. Must be called only after every connection attached to the endpoint has been torn down (i.e. after the owning reactors have stopped); active connections keep the endpoint alive from the protocol layer's point of view and must be gone first.
Does not touch active connections or broker operations still referencing the endpoint's resolvers.
| gws | Endpoint to free; NULL is a no-op. |
Definition at line 162 of file graphql_ws.c.
References cap, and cwist_free().