Skip to content

Examples

This section provides practical examples of using NpgsqlRest in various scenarios. Each example includes complete code samples and explanations.

Basic Examples

Simple Function API

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION calculate_tax(amount decimal, tax_rate decimal)
RETURNS decimal
LANGUAGE sql
AS $$
    SELECT amount * tax_rate / 100
$$;

.NET Application:

csharp
var builder = WebApplication.CreateSlimBuilder(args);
var app = builder.Build();

app.UseNpgsqlRest(new("Host=localhost;Database=store;Username=user;Password=pass"));
app.Run();

Usage:

bash
curl -X POST http://localhost:5000/api/calculate-tax/ \
  -H "Content-Type: application/json" \
  -d '{"amount": 100.00, "tax_rate": 8.5}'

Response:

8.50

JSON API with Custom Endpoints

PostgreSQL Setup:

sql
CREATE TABLE products (
    id serial PRIMARY KEY,
    name varchar(255) NOT NULL,
    price decimal(10,2) NOT NULL,
    category varchar(100),
    created_at timestamptz DEFAULT now()
);

CREATE OR REPLACE FUNCTION get_products_by_category(category_name text)
RETURNS json
LANGUAGE sql
AS $$
    SELECT json_agg(row_to_json(p)) 
    FROM products p 
    WHERE p.category = category_name
$$;

COMMENT ON FUNCTION get_products_by_category(text) IS '
HTTP GET /products/category/{category_name}
Content-Type: application/json';

Usage:

bash
curl http://localhost:5000/products/category/electronics

Authentication Examples

Role-Based Authorization

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION get_user_orders(user_id int)
RETURNS json
LANGUAGE sql
AS $$
    SELECT json_agg(o) FROM orders o WHERE o.user_id = $1
$$;

COMMENT ON FUNCTION get_user_orders(int) IS '
HTTP GET /users/{user_id}/orders
authorize user, admin';

CREATE OR REPLACE FUNCTION get_all_users()
RETURNS json
LANGUAGE sql
AS $$
    SELECT json_agg(row_to_json(u)) FROM users u
$$;

COMMENT ON FUNCTION get_all_users() IS '
HTTP GET /admin/users
authorize admin';

.NET Configuration:

csharp
var builder = WebApplication.CreateSlimBuilder(args);

// Add authentication
builder.Services.AddAuthentication("Bearer")
    .AddJwtBearer("Bearer", options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("your-secret-key")),
            ValidateIssuer = false,
            ValidateAudience = false
        };
    });

builder.Services.AddAuthorization(options =>
{
    options.AddPolicy("admin", policy => policy.RequireRole("admin"));
    options.AddPolicy("user", policy => policy.RequireRole("user", "admin"));
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.UseNpgsqlRest(new("connection_string")
{
    RequiresAuthorization = true
});

app.Run();

Custom Authorization Logic

csharp
app.UseNpgsqlRest(new("connection_string")
{
    AuthorizeCallback = context =>
    {
        // Custom authorization logic
        var userId = context.User?.FindFirst("user_id")?.Value;
        var requestedUserId = context.Request.RouteValues["user_id"]?.ToString();
        
        // Users can only access their own data
        return userId == requestedUserId || 
               context.User?.IsInRole("admin") == true;
    }
});

File Upload Examples

Basic File Upload

PostgreSQL Setup:

sql
CREATE TABLE file_uploads (
    id serial PRIMARY KEY,
    filename varchar(255),
    content_type varchar(100),
    size bigint,
    uploaded_at timestamptz DEFAULT now()
);

CREATE OR REPLACE FUNCTION handle_file_upload(
    filename text,
    content_type text,
    file_size bigint
)
RETURNS json
LANGUAGE sql
AS $$
    INSERT INTO file_uploads (filename, content_type, size)
    VALUES (filename, content_type, file_size)
    RETURNING row_to_json(file_uploads)
$$;

.NET Configuration:

csharp
app.UseNpgsqlRest(new("connection_string")
{
    UploadOptions = new()
    {
        AllowedExtensions = new[] { ".jpg", ".png", ".pdf", ".txt" },
        MaxFileSize = 10 * 1024 * 1024, // 10MB
        UploadPath = "/uploads"
    }
});

CSV Data Import

PostgreSQL Setup:

sql
CREATE TABLE customers (
    id serial PRIMARY KEY,
    name varchar(255),
    email varchar(255),
    phone varchar(50)
);

CREATE OR REPLACE FUNCTION import_customers_csv()
RETURNS int
LANGUAGE plpgsql
AS $$
DECLARE
    import_count int;
BEGIN
    -- This function works with NpgsqlRest CSV upload handler
    GET DIAGNOSTICS import_count = ROW_COUNT;
    RETURN import_count;
END;
$$;

COMMENT ON FUNCTION import_customers_csv() IS '
HTTP POST /customers/import
upload csv
target_table customers';

Real-Time Examples

Live Notifications

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION process_long_operation()
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    RAISE INFO 'Starting process...';
    
    PERFORM pg_sleep(2);
    RAISE INFO 'Step 1 completed: Data validation';
    
    PERFORM pg_sleep(2);
    RAISE INFO 'Step 2 completed: Processing records';
    
    PERFORM pg_sleep(1);
    RAISE INFO 'Process completed successfully';
END;
$$;

COMMENT ON FUNCTION process_long_operation() IS '
HTTP POST /operations/long-process
info_path /operations/events
info_scope all';

Client-Side (JavaScript):

javascript
// Start the long operation
fetch('/api/operations/long-process', { method: 'POST' });

// Listen for real-time updates
const eventSource = new EventSource('/operations/events');

eventSource.onmessage = function(event) {
    console.log('Progress update:', event.data);
    // Update UI with progress information
};

eventSource.onerror = function(event) {
    console.log('Operation completed or error occurred');
    eventSource.close();
};

Selective Notifications

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION admin_maintenance()
RETURNS void
LANGUAGE plpgsql
AS $$
BEGIN
    RAISE INFO 'Starting maintenance...' USING hint = 'all';
    RAISE INFO 'Updating user data...' USING hint = 'authorize admin';
    RAISE INFO 'Sensitive operation in progress...' USING hint = 'authorize super_admin';
    RAISE INFO 'Maintenance completed' USING hint = 'all';
END;
$$;

COMMENT ON FUNCTION admin_maintenance() IS '
HTTP POST /admin/maintenance
info_path /admin/events
authorize admin';

Advanced Examples

Custom Response Types

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION generate_report_pdf()
RETURNS bytea
LANGUAGE plpgsql
AS $$
BEGIN
    -- Generate PDF content (simplified example)
    RETURN decode('255044462d312e340a', 'hex'); -- PDF header
END;
$$;

COMMENT ON FUNCTION generate_report_pdf() IS '
HTTP GET /reports/monthly.pdf
Content-Type: application/pdf';

CREATE OR REPLACE FUNCTION get_dashboard_html()
RETURNS text
LANGUAGE sql
AS $$
    SELECT '<html><body><h1>Dashboard</h1><p>Welcome!</p></body></html>'
$$;

COMMENT ON FUNCTION get_dashboard_html() IS '
HTTP GET /dashboard
Content-Type: text/html';

Batch Operations

PostgreSQL Setup:

sql
CREATE OR REPLACE FUNCTION batch_update_prices(price_updates json)
RETURNS json
LANGUAGE plpgsql
AS $$
DECLARE
    update_record json;
    result json[];
BEGIN
    FOR update_record IN SELECT * FROM json_array_elements(price_updates)
    LOOP
        UPDATE products 
        SET price = (update_record->>'price')::decimal
        WHERE id = (update_record->>'id')::int;
        
        result := array_append(result, json_build_object(
            'id', update_record->>'id',
            'status', 'updated'
        ));
    END LOOP;
    
    RETURN array_to_json(result);
END;
$$;

COMMENT ON FUNCTION batch_update_prices(json) IS '
HTTP PUT /products/batch-update
Content-Type: application/json';

Usage:

bash
curl -X PUT http://localhost:5000/products/batch-update \
  -H "Content-Type: application/json" \
  -d '{
    "price_updates": [
      {"id": 1, "price": 29.99},
      {"id": 2, "price": 39.99}
    ]
  }'

Production Examples

Health Check Endpoint

sql
CREATE OR REPLACE FUNCTION health_check()
RETURNS json
LANGUAGE sql
AS $$
    SELECT json_build_object(
        'status', 'healthy',
        'timestamp', now(),
        'database', current_database(),
        'version', version()
    )
$$;

COMMENT ON FUNCTION health_check() IS '
HTTP GET /health
Content-Type: application/json';

API Versioning

sql
-- Version 1
CREATE OR REPLACE FUNCTION v1_get_user(user_id int)
RETURNS json
LANGUAGE sql
AS $$
    SELECT row_to_json(u) FROM users u WHERE id = user_id
$$;

COMMENT ON FUNCTION v1_get_user(int) IS '
HTTP GET /v1/users/{user_id}';

-- Version 2 with additional fields
CREATE OR REPLACE FUNCTION v2_get_user(user_id int)
RETURNS json
LANGUAGE sql
AS $$
    SELECT json_build_object(
        'id', u.id,
        'name', u.name,
        'email', u.email,
        'profile', u.profile_data,
        'last_login', u.last_login_at
    ) FROM users u WHERE id = user_id
$$;

COMMENT ON FUNCTION v2_get_user(int) IS '
HTTP GET /v2/users/{user_id}';

These examples demonstrate the flexibility and power of NpgsqlRest across various use cases. Each example can be adapted to fit your specific requirements.

Released under the MIT License.