rest

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2025 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package rest provides a PostgreSQL REST API server similar to PostgREST.

The server automatically exposes database tables and views as REST endpoints. Each endpoint supports standard HTTP methods: GET, POST, PATCH, DELETE.

Query parameters control filtering, pagination, and ordering:

Parameter         | Description
------------------|------------------------------------------------
?select=col1,col2 | Select specific columns
?order=col.desc   | Order results (supports nullsfirst/nullslast)
?limit=100        | Limit number of results (default: 100)
?offset=0         | Pagination offset (default: 0)
?col=eq.val       | Filter by column equality
?col=gt.val       | Filter with greater than comparison
?col=lt.val       | Filter with less than comparison
?col=gte.val      | Filter with greater than or equal comparison
?col=lte.val      | Filter with less than or equal comparison
?col=like.val     | Filter with pattern matching
?col=in.(a,b,c)   | Filter with value lists
?col=is.null      | Filter for null values
?or=(a.eq.x,b.lt.y) | Combine filters with logical operators

API is compatible with PostgREST. For more details, see: https://docs.postgrest.org/en/stable/references/api/tables_views.html

Example usage:

server, err := rest.NewServer("postgres://user:pass@localhost/db", "")
if err != nil {
	log.Fatal(err)
}
defer server.Shutdown()
log.Fatal(server.Start(":8080"))

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AGEHandler

type AGEHandler struct {
	// contains filtered or unexported fields
}

AGEHandler exposes AGE (Apache Graph Extension) graphs via REST WIP: only basic queries / functionalities have been tested

Example
package main

import (
	"cmp"
	"context"
	"fmt"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"

	"github.com/edgeflare/pgo/pkg/rest"
	"github.com/jackc/pgx/v5/pgxpool"
)

func main() {
	// Initialize a connection pool
	ctx := context.Background()
	graphName := "test_cypher"

	pool, err := pgxpool.New(ctx, cmp.Or(os.Getenv("DATABASE_URL"), "postgres://postgres:secret@localhost:5432/testdb"))
	if err != nil {
		log.Fatalf("failed to create connection pool: %v", err)
	}
	defer pool.Close()

	// Create an AGE handler with a default graph
	handler, err := rest.NewAGEHandler(ctx, pool, graphName)
	if err != nil {
		log.Fatalf("failed to create AGE handler: %v", err)
	}
	defer handler.Close()

	// Setup a test HTTP server
	server := httptest.NewServer(handler)
	defer server.Close()

	// // or mount on specific /path
	// mux := http.NewServeMux()
	// mux.Handle("POST /graph", handler)
	// if err = http.ListenAndServe(":8080", mux); err != nil {
	// 	log.Fatalf("Server error: %v", err)
	// }

	// Example 1: Create a vertex
	createReq := `{
		"cypher": "CREATE (n:Person {name: 'Alice', age: 30}) RETURN n", 
		"columnCount": 1
	}`

	resp, err := http.Post(server.URL, "application/json", strings.NewReader(createReq))
	if err != nil {
		log.Fatalf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	fmt.Printf("Create vertex status: %d\n", resp.StatusCode)

	// Example 2: Query vertices
	queryReq := `{
		"cypher": "MATCH (n:Person) RETURN n", 
		"columnCount": 1
	}`

	resp, err = http.Post(server.URL, "application/json", strings.NewReader(queryReq))
	if err != nil {
		log.Fatalf("failed to send request: %v", err)
	}
	defer resp.Body.Close()

	fmt.Printf("Query vertices status: %d\n", resp.StatusCode)

}
Output:

Create vertex status: 200
Query vertices status: 200

func NewAGEHandler

func NewAGEHandler(ctx context.Context, pool *pgxpool.Pool, graphName string) (*AGEHandler, error)

NewAGEHandler creates and configures a new API server

func (*AGEHandler) Close

func (s *AGEHandler) Close()

Close performs cleanup when shutting down the server

func (*AGEHandler) ServeHTTP

func (s *AGEHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP processes Cypher queries

type AGERequest

type AGERequest struct {
	Cypher      string `json:"cypher"`
	ColumnCount int    `json:"columnCount,omitempty"` // for read requests. not required for write requests
}

AGERequest is the expected format for incoming API requests

type AGEResponse

type AGEResponse struct {
	Success bool   `json:"success"`
	Data    any    `json:"data,omitempty"`
	Error   string `json:"error,omitempty"`
}

AGEResponse is the format for API responses

type FilterParam

type FilterParam struct {
	Operator string
	Value    any
}

type JoinParam

type JoinParam struct {
	Table    string
	JoinType string
	On       string
}

type OrderParam

type OrderParam struct {
	Column        string
	Direction     string // asc or desc
	NullsPosition string // first or last
}

type QueryParams

type QueryParams struct {
	Select     []string                 // Columns to select
	Order      []OrderParam             // Order by columns
	Limit      int                      // Limit results
	Offset     int                      // Offset results
	Filters    map[string][]FilterParam // Column filters
	EmbedJoins []JoinParam              // Embedded resource joins (foreign keys)
}

QueryParams holds parsed query parameters in a structured way

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(connString, baseURL string, omitempty ...bool) (*Server, error)

func (*Server) AddMiddleware

func (s *Server) AddMiddleware(middleware ...httputil.Middleware)

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

func (*Server) Start

func (s *Server) Start(addr string) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL