Deprecated: Function get_magic_quotes_gpc() is deprecated in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 99

Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 619

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1169

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176

Warning: Cannot modify header information - headers already sent by (output started at /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php:99) in /hermes/walnacweb04/walnacweb04ab/b2791/pow.jasaeld/htdocs/De1337/nothing/index.php on line 1176
8000 GitHub - ditas/esupa: An OTP application to simplify requests to Supabase API
Nothing Special   »   [go: up one dir, main page]

Skip to content

ditas/esupa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

67 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

esupa

License Erlang/OTP

esupa is an Erlang/OTP library that provides a comprehensive client interface for Supabase, supporting both REST API operations and real-time WebSocket connections for PostgreSQL change streams.

Features

🚀 HTTP REST API Client

  • Complete CRUD Operations: SELECT, INSERT, UPDATE, DELETE
  • Advanced Querying: Filters, joins, ordering, pagination
  • Connection Pooling: Efficient HTTP client management
  • Schema Support: Multi-schema database operations
  • Type Safety: Comprehensive type specifications

🔄 Real-time WebSocket Integration

  • PostgreSQL Change Streams: Listen to database changes in real-time
  • Automatic Reconnection: Robust connection handling with failover
  • Event Filtering: Subscribe to specific tables, schemas, and operations
  • Connection Pooling: Multiple WebSocket connection management
  • Heartbeat Support: Automatic connection health monitoring

Installation (examples in Elixir)

Add esupa to your mix.exs dependencies:

defp deps do
[
    {:esupa, git: "https://github.com/ditas/esupa.git", tag: "0.6.2"}
]

Quick Start (examples in Elixir)

1. Configuration

Configure your Supabase connection:

config :esupa,
  env: :prod,
  esupa_logger_level: :error,
  http_handler_pool_size: 10,
  project_url: <YOUR_PROJECT>,
  base_url: ~c".supabase.co",
  rest_url: ~c"/rest/v1/",
  key: <YOUR-ANON-OR-SERVICE_KEY>,
  ws_url: ~c"/realtime/v1/websocket",
  max_ws_handler_pool_size: 10,
  httpc_options: [
    keep_alive_timeout: 100,
    max_pipeline_length: 100,
    max_sessions: 100
  ]

2. Basic HTTP API Usage

# Get a client connection
{:ok, client} = :esupa.get_client()

# Build and execute a query
result = :esupa.request(client, get, 'public')
    |> :esupa.supa_from('users')
    |> :esupa.supa_select(['id', 'name', 'email'])
    |> :esupa.supa_eq('active', true)
    |> :esupa.supa_order('created_at', desc)
    |> :esupa.supa_range(0, 10)
    |> :esupa.execute()

3. Real-time WebSocket Usage

# Subscribe to table changes
:esupa_websocket_service.subscribe(
    self(),                           # Receiver PID
    {'public', 'users', 'INSERT', ''}, # {schema, table, event, filter}
    1                                 # Number of subscribers
)

# Handle incoming changes
receive
    %{"event" => "postgres_changes", "payload" => payload} ->
        do_something(payload)
end

HTTP API Reference (examples in Erlang)

Connection Management

get_client() -> {ok, pid()} | {error, string()}

Retrieves an available HTTP client from the connection pool.

{ok, Client} = esupa:get_client().

Request Building

request(Client, Method, Schema) -> request()

Creates a new request targeting the specified schema.

Request = esupa:request(Client, get, "public").

Parameters:

  • Client: HTTP client PID
  • Method: HTTP method (get, post, patch, delete)
  • Schema: Database schema name

Query Operations

supa_from(Request, Table) -> request()

Specifies the target table for the operation.

Request2 = esupa:supa_from(Request, "users").

supa_select(Request, Columns) -> request()

Defines which columns to return. Use [] for all columns.

%% Select specific columns
Request3 = esupa:supa_select(Request2, ["id", "name", "email"]),

%% Select all columns
Request3 = esupa:supa_select(Request2, []).

supa_join(Request, Joins) -> request()

Adds JOIN operations with related tables.

%% Join with profiles table
Joins = [{"profiles", ["avatar_url", "bio"]}],
Request4 = esupa:supa_join(Request3, Joins).

Filters and Conditions

Comparison Operators

%% Equality
Request = esupa:supa_eq(Request, "status", "active"),

%% Greater than
Request = esupa:supa_gt(Request, "age", 18),

%% Greater than or equal
Request = esupa:supa_gte(Request, "score", 100),

%% Less than
Request = esupa:supa_lt(Request, "price", 50),

%% Less than or equal
Request = esupa:supa_lte(Request, "quantity", 10),

%% IN clause
Request = esupa:supa_in(Request, "category", ["electronics", "books"]).

Complex Conditions

%% OR conditions
OrConditions = [
    {"age", "gte", "21"},
    {"verified", "eq", "true"}
],
Request = esupa:supa_or(Request, OrConditions).

Query Modifiers

supa_order(Request, Column, Direction) -> request()

Orders results by the specified column.

%% Ascending order
Request = esupa:supa_order(Request, "created_at", asc),

%% Descending order
Request = esupa:supa_order(Request, "updated_at", desc).

supa_range(Request, Min, Max) -> request()

Implements pagination by limiting the result range.

%% Get records 0-19 (first page, 20 items)
Request = esupa:supa_range(Request, 0, 19),

%% Get records 20-39 (second page, 20 items)
Request = esupa:supa_range(Request, 20, 39).

Execution

execute(Request) -> term()

Executes the built request and returns the response.

Result = esupa:execute(Request).

WebSocket Real-time API (examples in Erlang)

Subscription Management

esupa_websocket_service:subscribe(ReceiverPid, Request, NumSubscribers)

Subscribes to real-time database changes.

Parameters:

  • ReceiverPid: Process that will receive change notifications
  • Request: Tuple of {Schema, Table, Event, Filter}
  • NumSubscribers: Number of WebSocket connections to establish

Events:

  • "INSERT": New records created
  • "UPDATE": Existing records modified
  • "DELETE": Records deleted
  • "*": All change events

Example:

%% Listen to all INSERT events on users table
esupa_websocket_service:subscribe(
    self(),
    {"public", "users", "INSERT", ""},
    1
),

%% Listen to UPDATE events for specific user
esupa_websocket_service:subscribe(
    self(),
    {"public", "users", "UPDATE", "id=eq.123"},
    1
).

Configuration Options

HTTP Configuration

{esupa, [
    {base_url, ".supabase.co"},
    {project_url, "<YOUR_PROJECT>"}.
    {rest_url, "/rest/v1/"},
    {key, "<YOUR-ANON-OR-SERVICE_KEY>"},
    {http_handler_pool_size, 10},
    {httpc_options, [
        {keep_alive_timeout, 120000},
        {max_pipeline_length, 10},
        {max_sessions, 20}
    ]}
]}

WebSocket Configuration

{esupa, [
    {ws_url, "/realtime/v1/websocket"},
    {max_ws_handler_pool_size, 5}
]}

Building and Running

Development Build

$ rebar3 compile
$ rebar3 shell

Release Build

# Local development release
$ rebar3 as local release
$ ./_build/local/rel/esupa/bin/esupa console

# Test environment
$ rebar3 as test release
$ ./_build/test/rel/esupa/bin/esupa console

# Production release
$ rebar3 as prod release
$ ./_build/prod/rel/esupa/bin/esupa daemon

Testing

TBD

Documentation

Generate documentation using ExDoc:

$ rebar3 ex_doc

License

This project is licensed under the Apache License 2.0 - see the LICENSE.md file for details.

Dependencies

  • Erlang/OTP 25+: Required runtime
  • gun: HTTP/WebSocket client
  • jsx: JSON encoding/decoding
  • recon: Production debugging tools

Support

  • Issues: GitHub Issues
  • Documentation: Generated docs available in /docs (TBD)
  • Examples: See /examples directory for more use cases (TBD)

Made with ❤️ for the Erlang and Supabase communities.

About

An OTP application to simplify requests to Supabase API

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

0