Simple HTTP GET Request

Basic HTTP/1.1 request with automatic protocol negotiation

Make a simple GET request to any HTTPS endpoint:

  • ✓ Automatic TLS/SSL
  • ✓ Custom headers
  • ✓ Response handling
#include "jvr/client.h"
#include <stdio.h>

int main() {
    jvr_client_t* client = jvr_client_create();
    
    jvr_request_t* req = jvr_request_create(
        "GET", "https://api.github.com/users/github");
    jvr_request_set_header(req, "User-Agent", "JVR/1.0");
    
    jvr_response_t* res = jvr_client_send(client, req);
    
    if (res && res->status_code == 200) {
        printf("Success: %.*s\n", 
               (int)res->body_size, res->body);
    }
    
    jvr_response_destroy(res);
    jvr_request_destroy(req);
    jvr_client_destroy(client);
    return 0;
}

POST Request with JSON

Send JSON data to a REST API

POST JSON payload to an API endpoint:

  • ✓ JSON body
  • ✓ Content-Type header
  • ✓ Response parsing
#include "jvr/client.h"

int main() {
    jvr_client_t* client = jvr_client_create();
    
    const char* json = "{\"name\":\"John\",\"age\":30}";
    
    jvr_request_t* req = jvr_request_create(
        "POST", "https://api.example.com/users");
    jvr_request_set_header(req, "Content-Type", 
                           "application/json");
    jvr_request_set_body(req, json, strlen(json));
    
    jvr_response_t* res = jvr_client_send(client, req);
    
    printf("Status: %d\n", res->status_code);
    
    jvr_response_destroy(res);
    jvr_request_destroy(req);
    jvr_client_destroy(client);
    return 0;
}

HTTP/2 Multiplexing

Multiple concurrent requests over one connection

Send multiple requests simultaneously:

  • ✓ Single TCP connection
  • ✓ Concurrent streams
  • ✓ Lower latency
#include "jvr/client.h"

int main() {
    jvr_client_config_t config = {
        .prefer_http2 = true,
        .max_concurrent_streams = 100
    };
    jvr_client_t* client = 
        jvr_client_create_with_config(&config);
    
    jvr_request_t* req1 = jvr_request_create(
        "GET", "https://example.com/api/users");
    jvr_request_t* req2 = jvr_request_create(
        "GET", "https://example.com/api/posts");
    jvr_request_t* req3 = jvr_request_create(
        "GET", "https://example.com/api/comments");
    
    // All three use the same connection!
    jvr_response_t* res1 = jvr_client_send(client, req1);
    jvr_response_t* res2 = jvr_client_send(client, req2);
    jvr_response_t* res3 = jvr_client_send(client, req3);
    
    // Process responses...
    
    return 0;
}

HTTP/3 over QUIC

Ultra-fast HTTP/3 requests

Use HTTP/3 for maximum performance:

  • ✓ QUIC transport
  • ✓ Faster than HTTP/2
  • ✓ Built-in encryption
#include "jvr/client.h"

int main() {
    jvr_client_config_t config = {
        .prefer_http3 = true
    };
    jvr_client_t* client = 
        jvr_client_create_with_config(&config);
    
    jvr_request_t* req = jvr_request_create(
        "GET", "https://cloudflare.com");
    
    jvr_response_t* res = jvr_client_send(client, req);
    
    printf("Protocol: HTTP/3 over QUIC\n");
    printf("Status: %d\n", res->status_code);
    
    jvr_response_destroy(res);
    jvr_request_destroy(req);
    jvr_client_destroy(client);
    return 0;
}

Connection Migration

Switch networks without dropping connection

Seamlessly migrate between WiFi and cellular:

  • ✓ Network switching
  • ✓ Zero downtime
  • ✓ Mobile-friendly
#include "jvr/quic_advanced.h"

int main() {
    jvr_quic_connection_t* conn = 
        jvr_quic_connection_create(&config);
    
    // Enable migration
    jvr_quic_enable_migration(conn);
    jvr_quic_connect(conn);
    
    // Use connection...
    
    // Network changed? Migrate!
    if (network_switched_to_cellular) {
        jvr_quic_migrate_connection(conn, 
            cellular_ip, 443);
        // Connection continues seamlessly!
    }
    
    jvr_quic_migration_state_t state;
    jvr_quic_get_migration_state(conn, &state);
    if (state.status == JVR_QUIC_MIGRATION_COMPLETED) {
        printf("Migrated successfully!\n");
    }
    
    return 0;
}

0-RTT Fast Reconnection

50% faster reconnections with 0-RTT

Resume connections instantly:

  • ✓ Session resumption
  • ✓ Early data support
  • ✓ Minimal latency
#include "jvr/quic_advanced.h"

// First connection - save session
jvr_quic_connection_t* conn = 
    jvr_quic_connection_create(&config);
jvr_quic_enable_0rtt(conn);
jvr_quic_connect(conn);

uint8_t* ticket;
size_t ticket_len;
jvr_quic_save_session(conn, &ticket, &ticket_len);

// Store ticket to disk/database...
jvr_quic_close(conn, 0, "done");

// Later: Fast reconnect with 0-RTT!
jvr_quic_connection_t* new_conn = 
    jvr_quic_connection_create(&config);
jvr_quic_enable_0rtt(new_conn);
jvr_quic_restore_session(new_conn, ticket, ticket_len);

// Send data BEFORE handshake completes!
jvr_quic_send_early_data(new_conn, "GET /api/data", 13);

if (jvr_quic_is_0rtt_accepted(new_conn)) {
    printf("0-RTT accepted - super fast!\n");
}

WebSocket Chat Client

Real-time bidirectional communication

Build real-time applications:

  • ✓ Full-duplex communication
  • ✓ Event-driven API
  • ✓ Secure WSS support
#include "jvr/websocket.h"

void on_message(jvr_websocket_t* ws, 
                const char* data, size_t len, 
                bool is_binary) {
    printf("Received: %.*s\n", (int)len, data);
}

void on_open(jvr_websocket_t* ws) {
    printf("Connected!\n");
    jvr_websocket_send_text(ws, "Hello!");
}

int main() {
    jvr_websocket_t* ws = jvr_websocket_create(
        "wss://echo.websocket.org");
    
    jvr_websocket_set_on_open(ws, on_open);
    jvr_websocket_set_on_message(ws, on_message);
    
    jvr_websocket_connect(ws);
    
    // Send messages
    jvr_websocket_send_text(ws, "Hello Server!");
    
    return 0;
}

Circuit Breaker Pattern

Prevent cascading failures

Build resilient applications:

  • ✓ Failure detection
  • ✓ Automatic recovery
  • ✓ Half-open state
#include "jvr/circuit_breaker.h"

jvr_circuit_breaker_config_t config = {
    .failure_threshold = 5,
    .timeout_ms = 60000,
    .success_threshold = 2
};
jvr_circuit_breaker_t* cb = 
    jvr_circuit_breaker_create(&config);

// Use circuit breaker
if (jvr_circuit_breaker_allow_request(cb)) {
    jvr_response_t* res = make_api_call();
    
    if (res && res->status_code == 200) {
        jvr_circuit_breaker_record_success(cb);
    } else {
        jvr_circuit_breaker_record_failure(cb);
    }
} else {
    printf("Circuit OPEN - request rejected!\n");
}

Middleware Pipeline

Composable request/response processing

Chain multiple middlewares:

  • ✓ Logging
  • ✓ Authentication
  • ✓ Compression
#include "jvr/middleware.h"

jvr_middleware_pipeline_t* pipeline = 
    jvr_middleware_pipeline_create();

// Add middlewares
jvr_middleware_pipeline_add(pipeline, 
    jvr_middleware_logger_create());
jvr_middleware_pipeline_add(pipeline, 
    jvr_middleware_auth_create("Bearer", token));
jvr_middleware_pipeline_add(pipeline, 
    jvr_middleware_compression_create());

// Use with client
jvr_client_t* client = jvr_client_create();
jvr_client_set_middleware(client, pipeline);

// All requests go through the pipeline!
jvr_response_t* res = jvr_client_send(client, req);

Intelligent Caching

HTTP-compliant response caching

Cache responses for better performance:

  • ✓ Cache-Control support
  • ✓ ETag validation
  • ✓ LRU eviction
#include "jvr/response_cache.h"

// Create cache (10 MB, 1000 entries)
jvr_response_cache_t* cache = 
    jvr_response_cache_create(
        10 * 1024 * 1024, 1000);

jvr_client_t* client = jvr_client_create();
jvr_client_set_cache(client, cache);

// First request - MISS
jvr_response_t* res1 = 
    jvr_client_send(client, req);

// Second request - HIT!
jvr_response_t* res2 = 
    jvr_client_send(client, req);

jvr_cache_stats_t stats;
jvr_response_cache_get_stats(cache, &stats);
printf("Hit rate: %.2f%%\n", stats.hit_rate * 100);

Observability & Metrics

Built-in production metrics

Track everything automatically:

  • ✓ Request latency
  • ✓ Error rates
  • ✓ Prometheus export
#include "jvr/metrics.h"

jvr_metrics_registry_t* metrics = 
    jvr_metrics_get_global();

// Track request
jvr_request_tracker_t* tracker = 
    jvr_metrics_track_request(metrics, 
        "GET", "/api/users");

// ... handle request ...

// Auto-records latency and status
jvr_metrics_complete_request(tracker, 200);

// Get stats
jvr_http_metrics_t stats;
jvr_metrics_get_http(metrics, &stats);
printf("Requests: %llu\n", stats.total_requests);

// Export to Prometheus
char* prom_text;
size_t prom_size;
jvr_metrics_export_prometheus(metrics, 
    &prom_text, &prom_size);

Complete Production App

All features combined

Production-ready example with all features:

  • ✓ HTTP/3 support
  • ✓ Circuit breaker
  • ✓ Caching & metrics
#include "jvr/client.h"
#include "jvr/middleware.h"
#include "jvr/circuit_breaker.h"
#include "jvr/response_cache.h"
#include "jvr/metrics.h"

int main() {
    // Configure client
    jvr_client_config_t config = {
        .prefer_http3 = true,
        .prefer_http2 = true
    };
    jvr_client_t* client = 
        jvr_client_create_with_config(&config);
    
    // Add middleware
    jvr_middleware_pipeline_t* pipeline = 
        jvr_middleware_pipeline_create();
    jvr_middleware_pipeline_add(pipeline, 
        jvr_middleware_logger_create());
    jvr_client_set_middleware(client, pipeline);
    
    // Add cache
    jvr_response_cache_t* cache = 
        jvr_response_cache_create(10*1024*1024, 1000);
    jvr_client_set_cache(client, cache);
    
    // Circuit breaker
    jvr_circuit_breaker_t* cb = 
        jvr_circuit_breaker_create(&cb_config);
    
    // Track metrics
    jvr_metrics_registry_t* metrics = 
        jvr_metrics_get_global();
    
    // Make request
    if (jvr_circuit_breaker_allow_request(cb)) {
        jvr_request_tracker_t* tracker = 
            jvr_metrics_track_request(metrics, 
                "GET", "/api/data");
        
        jvr_request_t* req = jvr_request_create(
            "GET", "https://api.example.com/data");
        jvr_response_t* res = 
            jvr_client_send(client, req);
        
        if (res && res->status_code == 200) {
            jvr_circuit_breaker_record_success(cb);
            jvr_metrics_complete_request(tracker, 200);
        }
    }
    
    return 0;
}

Ready to Start Building?

Download JVR NetStack and start coding today.