{"id":31287734,"url":"https://github.com/excalibase/excalibase-rest","last_synced_at":"2026-04-09T12:03:11.491Z","repository":{"id":314937785,"uuid":"1056705529","full_name":"excalibase/excalibase-rest","owner":"excalibase","description":"Auto-generates REST APIs from your database with Spring Boot. It supports CRUD, filtering, relationship expansion, batch ops, and OpenAPI docs — no boilerplate required.","archived":false,"fork":false,"pushed_at":"2025-09-15T17:52:01.000Z","size":154,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-15T19:29:16.470Z","etag":null,"topics":["api-generation","auto-generated-api","crud-operations","database-api","database-to-api","filtering","java","low-code","lowcode","maven","openapi","postgresql","relationship-expansion","rest-api","schema-discovery","spring-boot","swagger"],"latest_commit_sha":null,"homepage":"","language":"Groovy","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/excalibase.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-14T16:33:58.000Z","updated_at":"2025-09-15T17:52:04.000Z","dependencies_parsed_at":"2025-09-15T19:39:40.053Z","dependency_job_id":null,"html_url":"https://github.com/excalibase/excalibase-rest","commit_stats":null,"previous_names":["excalibase/excalibase-rest"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/excalibase/excalibase-rest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excalibase%2Fexcalibase-rest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excalibase%2Fexcalibase-rest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excalibase%2Fexcalibase-rest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excalibase%2Fexcalibase-rest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/excalibase","download_url":"https://codeload.github.com/excalibase/excalibase-rest/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/excalibase%2Fexcalibase-rest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276737524,"owners_count":25695700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-24T02:00:09.776Z","response_time":97,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-generation","auto-generated-api","crud-operations","database-api","database-to-api","filtering","java","low-code","lowcode","maven","openapi","postgresql","relationship-expansion","rest-api","schema-discovery","spring-boot","swagger"],"created_at":"2025-09-24T11:05:30.727Z","updated_at":"2026-04-09T12:03:11.473Z","avatar_url":"https://github.com/excalibase.png","language":"Groovy","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Excalibase REST API\n[![CI](https://github.com/excalibase/excalibase-rest/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/excalibase/excalibase-rest/actions/workflows/ci.yml)\n[![E2E Tests](https://github.com/excalibase/excalibase-rest/actions/workflows/e2e.yml/badge.svg?branch=main)](https://github.com/excalibase/excalibase-rest/actions/workflows/e2e.yml)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![Java Version](https://img.shields.io/badge/Java-21+-orange.svg)](https://openjdk.java.net/)\n[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-3.5.0-brightgreen.svg)](https://spring.io/projects/spring-boot)\n[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-15+-blue.svg)](https://www.postgresql.org/)\n\n## 🚀 Overview\n\nExcalibase REST is a powerful Spring Boot application that **automatically generates REST API endpoints from your existing PostgreSQL database tables**. It eliminates the need for manual API development and provides instant REST APIs with advanced features like pagination, filtering, relationship expansion, and comprehensive CRUD operations.\n\n### ✨ Current Features\n- **🔄 Automatic Endpoint Generation**: Creates REST endpoints from PostgreSQL tables\n- **📊 Rich Querying**: Advanced filtering, sorting, and pagination\n- **🗓️ Enhanced Date/Time Filtering**: Comprehensive date and timestamp operations\n- **🔍 Advanced Filter Types**: String, numeric, boolean filters with operators like eq, neq, gt, gte, lt, lte, in, notin, like, ilike\n- **🔎 Full-Text Search**: FTS operators (fts, plfts, phfts, wfts) with configurable language\n- **🎯 Custom PostgreSQL Types**: Full support for custom enum and composite types\n- **📄 Enhanced PostgreSQL Data Types**: JSON/JSONB with object support, arrays with proper mapping, network types (INET, CIDR), datetime, and XML support\n- **🔗 Relationship Expansion**: Parameterized and nested expand with single-CTE compilation\n- **🛠️ CRUD Operations**: Full create, read, update, delete support with **composite key support**\n- **🔑 Composite Primary Keys**: Complete support for tables with multi-column primary keys\n- **🔄 Composite Foreign Keys**: Seamless handling of multi-column foreign key relationships\n- **📄 Offset \u0026 Cursor Pagination**: Both traditional offset-based and GraphQL-style cursor pagination\n- **⚡ N+1 Prevention**: Single-CTE query compilation with jsonb_agg pattern\n- **🔧 OR Operations**: Complex logical conditions with SQL-style syntax\n- **🛡️ Security Controls**: Input validation, SQL injection prevention, and request limiting\n- **📋 Bulk Operations**: Transaction-safe bulk create, update, and delete operations via array input\n- **🐳 Docker Support**: Container images with Docker Compose setup\n- **📖 OpenAPI 3.0**: Auto-generated API documentation with Swagger UI compatibility (JSON/YAML formats)\n- **🔍 Schema Introspection**: Dynamic PostgreSQL schema discovery with type information endpoints\n- **💾 Schema Caching**: CDC DDL-invalidated schema cache (no polling)\n- **🔄 CI/CD Pipeline**: GitHub Actions integration with automated testing\n- **🧩 3-Module Architecture**: Starter (interfaces) + Postgres (implementations) + API (controllers)\n\n- **📡 Real-time CDC Subscriptions**: Server-Sent Events (SSE) and WebSocket change streams via NATS JetStream\n- **🔍 Prefer Header**: `Prefer: count=exact` for optional total counts\n- **📊 Observability Stack**: OpenTelemetry traces/metrics, Grafana, Prometheus, Tempo, Loki\n- **⚡ Virtual Threads**: Java 21 virtual threads for high-concurrency workloads\n- **🔀 RPC Functions**: Call PostgreSQL functions via dedicated RPC endpoints\n- **📊 Aggregations**: Server-side aggregation queries with filter support\n\n### 🚧 Planned Features\n\n- [ ] **Response Caching** - HTTP-level and query result caching\n- [ ] **MySQL Support** - Complete MySQL database integration\n- [ ] **Oracle Support** - Add Oracle database compatibility\n- [ ] **SQL Server Support** - Microsoft SQL Server implementation\n- [ ] **Authentication/Authorization** - Role-based access control\n\n## 📋 Quick Start\n\n### Prerequisites\n\n- Java 21+\n- Maven 3.8+\n- PostgreSQL 15+\n\n### Installation\n\n#### Option 1: Docker (Recommended)\n\n1. **Clone the repository**\n   ```bash\n   git clone https://github.com/excalibase/excalibase-rest.git\n   cd excalibase-rest\n   ```\n\n2. **Configure your database**\n\n   Edit `docker-compose.yml` or set environment variables:\n   ```yaml\n   environment:\n     - SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/your_database\n     - SPRING_DATASOURCE_USERNAME=your_username\n     - SPRING_DATASOURCE_PASSWORD=your_password\n     - APP_ALLOWED_SCHEMA=your_schema\n     # Optional configuration\n     - APP_MAX_PAGE_SIZE=1000\n     - APP_DEFAULT_PAGE_SIZE=100\n   ```\n\n3. **Run with Docker Compose**\n   ```bash\n   docker-compose up -d\n   ```\n\n4. **Access REST API endpoints**\n\n   Your REST API will be available at: `http://localhost:20000/api/v1`\n   \n   - API Documentation: `http://localhost:20000/api/v1/docs`\n   - OpenAPI JSON: `http://localhost:20000/api/v1/openapi.json`\n   - Swagger UI: `http://localhost:20000/swagger-ui.html`\n\n#### Option 2: Local Development\n\n1. **Clone the repository**\n   ```bash\n   git clone https://github.com/excalibase/excalibase-rest.git\n   cd excalibase-rest\n   ```\n\n2. **Configure your database**\n\n   Create `application-dev.yml` or set environment variables:\n   ```yaml\n   spring:\n     datasource:\n       url: jdbc:postgresql://localhost:5432/your_database\n       username: your_username\n       password: your_password\n\n   app:\n     allowed-schema: your_schema\n     database-type: postgres\n   ```\n\n3. **Run the application**\n   ```bash\n   mvn clean install\n   mvn spring-boot:run\n   ```\n\n4. **Access your API**\n   ```\n   http://localhost:20000/api/v1\n   ```\n\n### Quick Development Setup\n\n```bash\n# Clone and setup\ngit clone https://github.com/excalibase/excalibase-rest.git\ncd excalibase-rest\n\n# Start development environment\nmake dev-setup\nmake quick-start\n\n# Your API is ready at http://localhost:20000/api/v1\n```\n\n## 🎯 API Usage Examples\n\n### Basic CRUD Operations\n\n```bash\n# Get all records with pagination\ncurl \"http://localhost:20000/api/v1/users?limit=10\u0026offset=0\"\n\n# Get single record\ncurl \"http://localhost:20000/api/v1/users/123\"\n\n# Create new record\ncurl -X POST \"http://localhost:20000/api/v1/users\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"John Doe\", \"email\": \"john@example.com\"}'\n\n# Update record\ncurl -X PUT \"http://localhost:20000/api/v1/users/123\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\": \"John Smith\", \"email\": \"john.smith@example.com\"}'\n\n# Partial update\ncurl -X PATCH \"http://localhost:20000/api/v1/users/123\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"john.updated@example.com\"}'\n\n# Delete record\ncurl -X DELETE \"http://localhost:20000/api/v1/users/123\"\n```\n\n### Advanced Filtering\n\n```bash\n# Equality filtering\ncurl \"http://localhost:20000/api/v1/users?name=eq.John\"\n\n# Range filtering\ncurl \"http://localhost:20000/api/v1/users?age=gte.18\u0026age=lt.65\"\n\n# Text search\ncurl \"http://localhost:20000/api/v1/users?email=like.*@gmail.com\"\n\n# Multiple values\ncurl \"http://localhost:20000/api/v1/users?status=in.(active,pending)\"\n\n# OR conditions\ncurl \"http://localhost:20000/api/v1/users?or=(name.like.John*,email.like.*@company.com)\"\n\n# JSON filtering (for JSONB columns)\ncurl \"http://localhost:20000/api/v1/users?metadata=haskey.preferences\"\n\n# Full-text search (uses to_tsvector/to_tsquery)\ncurl \"http://localhost:20000/api/v1/posts?body=fts.postgresql\"\n\n# Plain full-text search\ncurl \"http://localhost:20000/api/v1/posts?body=plfts.search+terms\"\n\n# Phrase full-text search\ncurl \"http://localhost:20000/api/v1/posts?body=phfts.exact+phrase\"\n\n# Websearch-style full-text search\ncurl \"http://localhost:20000/api/v1/posts?body=wfts.search+terms+-excluded\"\n```\n\n### Relationship Expansion\n\n```bash\n# Expand related data (many-to-one)\ncurl \"http://localhost:20000/api/v1/orders?expand=customer\"\n\n# Expand with parameters (limit, select, order)\ncurl \"http://localhost:20000/api/v1/customers?expand=orders(limit:5,select:id,order:total.desc)\"\n\n# Multiple expansions\ncurl \"http://localhost:20000/api/v1/orders?expand=customer,items\"\n\n# Nested expand (multi-level traversal)\ncurl \"http://localhost:20000/api/v1/customers?expand=orders.order_items\"\n```\n\n### Field Selection and Sorting\n\n```bash\n# Select specific fields\ncurl \"http://localhost:20000/api/v1/users?select=name,email,created_at\"\n\n# Sorting\ncurl \"http://localhost:20000/api/v1/users?orderBy=name\u0026orderDirection=asc\"\n\n# SQL-style ordering\ncurl \"http://localhost:20000/api/v1/users?order=name.asc,created_at.desc\"\n```\n\n### Pagination\n\n```bash\n# Offset-based pagination\ncurl \"http://localhost:20000/api/v1/users?limit=10\u0026offset=20\"\n\n# Cursor-based pagination (GraphQL connections style)\ncurl \"http://localhost:20000/api/v1/users?first=10\u0026after=eyJpZCI6MTIzfQ==\"\n```\n\n### Bulk Operations\n\n```bash\n# Bulk create (array input to POST endpoint)\ncurl -X POST \"http://localhost:20000/api/v1/users\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[{\"name\": \"User1\"}, {\"name\": \"User2\"}, {\"name\": \"User3\"}]'\n\n# Bulk update (array input to PUT endpoint)\ncurl -X PUT \"http://localhost:20000/api/v1/users\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '[{\"id\": \"1\", \"name\": \"Updated User1\"}, {\"id\": \"2\", \"name\": \"Updated User2\"}]'\n\n# Bulk delete (query-based filtering)\ncurl -X DELETE \"http://localhost:20000/api/v1/users?status=eq.inactive\"\n\n# Bulk update with filters (advanced filtering)\ncurl -X PUT \"http://localhost:20000/api/v1/users?status=eq.pending\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"status\": \"active\"}'\n\n# Upsert operations (with prefer header)\ncurl -X POST \"http://localhost:20000/api/v1/users?prefer=resolution=merge-duplicates\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"email\": \"john@example.com\", \"name\": \"John Doe\"}'\n```\n\n### Real-time CDC Subscriptions\n\nExcalibase REST supports real-time change data capture (CDC) via SSE and WebSocket. Changes made through the API **or directly in PostgreSQL** are streamed to subscribers.\n\n**Prerequisites**: Requires [excalibase-watcher](https://github.com/excalibase/excalibase-watcher) and NATS JetStream (included in `docker-compose.yml`).\n\n```bash\n# SSE — subscribe to changes on a table\ncurl -N \"http://localhost:20000/api/v1/customers/changes\"\n\n# Events arrive as:\n# event:INSERT\n# data:{\"id\":\"...\",\"name\":\"John Doe\",\"email\":\"john@example.com\",...}\n#\n# event:UPDATE\n# data:{\"new\":{\"id\":\"...\",\"name\":\"Jane Doe\",...}}\n#\n# event:DELETE\n# data:{\"id\":\"...\"}\n```\n\n```javascript\n// WebSocket — connect to ws://localhost:20000/ws/customers/changes\nconst ws = new WebSocket(\"ws://localhost:20000/ws/customers/changes\");\nws.onmessage = (msg) =\u003e {\n  const event = JSON.parse(msg.data);\n  console.log(event.event, event.table, event.data);\n};\n```\n\n### Prefer Header\n\nUse the `Prefer` header for optional response behaviors:\n\n```bash\n# Include total count in pagination response\ncurl -H \"Prefer: count=exact\" \"http://localhost:20000/api/v1/users?limit=10\"\n# Response includes: \"pagination\": {\"total\": 42, ...}\n\n# Return created/updated object (default behavior)\ncurl -H \"Prefer: return=representation\" -X POST ...\n\n# Return minimal response\ncurl -H \"Prefer: return=minimal\" -X POST ...\n```\n\n## 🏗️ Database Schema Discovery\n\nExcalibase REST automatically discovers your database schema and creates REST endpoints:\n\n```bash\n# Get all available tables\ncurl \"http://localhost:20000/api/v1\"\n\n# Get table schema information\ncurl \"http://localhost:20000/api/v1/users/schema\"\n\n# Get OpenAPI specification\ncurl \"http://localhost:20000/api/v1/openapi.json\"\ncurl \"http://localhost:20000/api/v1/openapi.yaml\"\n\n# Get custom PostgreSQL type information\ncurl \"http://localhost:20000/api/v1/types/my_enum_type\"\n```\n\n## 🔧 Configuration\n\n### Application Properties\n\n```yaml\napp:\n  # Database configuration\n  allowed-schema: public        # Database schema to expose\n  database-type: postgres       # Database type\n\n  # Pagination configuration\n  max-page-size: 1000          # Maximum pagination limit\n  default-page-size: 100       # Default pagination size\n\n  # CORS configuration\n  cors:\n    enabled: true\n    allowed-origins: [\"*\"]\n    allowed-methods: [GET, POST, PUT, PATCH, DELETE, OPTIONS]\n    allowed-headers: [\"*\"]\n    allow-credentials: false\n    max-age: 3600\n\n  # Security configuration\n  security:\n    enable-sql-injection-protection: true\n    enable-table-name-validation: true\n    enable-column-name-validation: true\n    max-request-body-size: 1048576 # 1MB\n\nspring:\n  datasource:\n    url: jdbc:postgresql://localhost:5432/mydb\n    username: myuser\n    password: mypass\n    hikari:\n      maximum-pool-size: 20\n      minimum-idle: 5\n      connection-timeout: 20000\n      idle-timeout: 300000\n```\n\n### CDC / NATS Configuration\n\n```yaml\napp:\n  nats:\n    enabled: false              # Enable CDC subscriptions\n    url: nats://localhost:4222  # NATS server URL\n    stream-name: CDC            # JetStream stream name\n    subject-prefix: cdc         # Subject prefix for CDC events\n```\n\n### Environment Variables\n\n```bash\n# CDC / NATS\nexport APP_NATS_ENABLED=true\nexport APP_NATS_URL=nats://localhost:4222\n\n# Database connection\nexport SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/mydb\nexport SPRING_DATASOURCE_USERNAME=myuser\nexport SPRING_DATASOURCE_PASSWORD=mypass\n\n# Application settings\nexport APP_ALLOWED_SCHEMA=public\nexport APP_MAX_PAGE_SIZE=1000\nexport APP_DEFAULT_PAGE_SIZE=100\n# Security settings\nexport APP_SECURITY_MAX_REQUEST_BODY_SIZE=1048576\n```\n\n## 🧪 Testing\n\n### Running Tests\n\n```bash\n# Maven Tests\nmvn test                              # All tests (unit + integration)\nmvn test -Dtest=\"*Test,!*IntegrationTest\"  # Unit tests only\nmvn test -Dtest=\"*IntegrationTest\"    # Integration tests only\nmvn clean test jacoco:report          # Tests with coverage report\n\n# Make Commands (with Docker services)\nmake test               # Start services + run all tests\nmake test-maven         # Run Maven tests\nmake test-unit          # Unit tests only\nmake test-integration   # Integration tests only\nmake test-coverage      # Coverage report\nmake e2e                # Complete E2E test suite\nmake test-quick         # Quick test (skip build)\n```\n\n### Test Coverage\n\n- **Unit Tests**: Service layer business logic\n- **Integration Tests**: Database operations with Testcontainers\n- **E2E Tests**: Full API endpoint testing\n- **Performance Tests**: Load testing with realistic data\n- **Security Tests**: SQL injection and input validation\n\n## 🚀 Development\n\n### Development Commands\n\n```bash\n# Development Environment\nmake dev-setup          # Setup PostgreSQL database only\nmake quick-start         # Setup database + start application\nmake run                 # Run application locally\nmake dev-teardown        # Cleanup development environment\n\n# Testing Commands\nmake test               # Start services and run all tests\nmake test-maven         # Run all Maven tests (unit + integration)\nmake test-unit          # Run unit tests only\nmake test-integration   # Run integration tests only\nmake test-coverage      # Run tests with coverage report\nmake e2e                # Complete E2E test suite with cleanup\n\n# Build and Package\nmake build              # Build application with Maven\nmake package            # Package JAR for distribution\nmake install            # Install to local Maven repository\n\n# Docker Commands\nmake docker-build       # Build Docker image\nmake docker-run         # Run application in Docker\nmake build-image        # Build image for E2E testing\n\n# Development Utilities\nmake health             # Check API health status\nmake db-shell           # Connect to database shell\nmake db-reset           # Reset database schema\nmake logs               # Show all service logs\nmake status             # Show service status\nmake restart            # Restart all services\nmake clean              # Stop services and cleanup\n```\n\n### Building and Packaging\n\n```bash\n# Build application\nmvn clean install\n\n# Build Docker image\ndocker build -t excalibase/excalibase-rest .\n\n# Package for distribution\nmvn clean package -DskipTests\n```\n\n## 📡 Observability\n\nAn optional observability stack is available via a compose override:\n\n```bash\n# Start app + observability (Grafana, Prometheus, Tempo, Loki)\ndocker compose -f docker-compose.yml -f docker-compose.observability.yml up -d\n```\n\n| Service    | URL                          | Purpose         |\n|------------|------------------------------|-----------------|\n| Grafana    | http://localhost:3030         | Dashboards      |\n| Prometheus | http://localhost:9090         | Metrics         |\n| Tempo      | http://localhost:3200         | Traces          |\n| Loki       | http://localhost:3100         | Logs            |\n| NATS       | http://localhost:8222         | NATS monitoring |\n\nSignal flow: `App --OTLP--\u003e OTel Collector --\u003e Tempo (traces) / Prometheus (metrics) / Loki (logs) --\u003e Grafana`\n\n## 📖 Documentation\n\n- **[API Reference](docs/api-reference.md)** - Complete REST API documentation\n- **[Filtering Guide](docs/filtering.md)** - Advanced filtering and querying\n- **[Configuration](docs/configuration.md)** - Setup and configuration options\n- **[Examples](docs/examples.md)** - Real-world usage examples\n- **[Contributing](CONTRIBUTING.md)** - How to contribute to the project\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Submit a pull request\n\n## 📄 License\n\nThis project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Spring Boot team for the excellent framework\n- PostgreSQL community for the robust database\n- GraphQL community for pagination and filtering patterns\n\n## 🔗 Related Projects\n\n- **[Excalibase GraphQL](https://github.com/excalibase/excalibase-graphql)** - GraphQL version of this project\n- **[Excalibase Watcher](https://github.com/excalibase/excalibase-watcher)** - CDC streaming service\n\n---\n\n\u003cdiv align=\"center\"\u003e\n  \u003cstrong\u003eTransform your PostgreSQL database into a powerful REST API in minutes\u003c/strong\u003e\n\u003c/div\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcalibase%2Fexcalibase-rest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexcalibase%2Fexcalibase-rest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexcalibase%2Fexcalibase-rest/lists"}