{"id":27603211,"url":"https://github.com/opendgraph/otter","last_synced_at":"2026-02-24T02:01:53.367Z","repository":{"id":286040135,"uuid":"960002620","full_name":"OpenDgraph/Otter","owner":"OpenDgraph","description":"Otter is a smart proxy and query transpiler for Dgraph. It balances traffic across clusters and adds experimental support for Cypher and other graph query languages.","archived":false,"fork":false,"pushed_at":"2025-04-18T00:10:27.000Z","size":12511,"stargazers_count":2,"open_issues_count":8,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-22T19:14:00.150Z","etag":null,"topics":["balancer","cypher-query-language","dql","graph","graphql","transpiler"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/OpenDgraph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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}},"created_at":"2025-04-03T17:44:23.000Z","updated_at":"2025-04-18T00:10:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"8d26b973-d728-4695-a985-e85da0fac16a","html_url":"https://github.com/OpenDgraph/Otter","commit_stats":null,"previous_names":["opendgraph/otter"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/OpenDgraph/Otter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDgraph%2FOtter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDgraph%2FOtter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDgraph%2FOtter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDgraph%2FOtter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/OpenDgraph","download_url":"https://codeload.github.com/OpenDgraph/Otter/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/OpenDgraph%2FOtter/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29768329,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T01:40:24.820Z","status":"online","status_checked_at":"2026-02-24T02:00:07.497Z","response_time":75,"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":["balancer","cypher-query-language","dql","graph","graphql","transpiler"],"created_at":"2025-04-22T19:13:56.480Z","updated_at":"2026-02-24T02:01:53.350Z","avatar_url":"https://github.com/OpenDgraph.png","language":"Go","readme":"# Otter 🦦\n\n\u003e Under construction 🚧\n\n\u003e Built for performance. Designed for graphs.\n\nOtter is a lightweight, purpose-driven proxy and query transpiler for [Dgraph](https://dgraph.io).  \nIt intelligently balances traffic between Dgraph clusters and adds support for advanced query workflows — including Cypher-to-DQL translation (in progress).\n\n\nOtter aims to serve as the foundation for future support of multiple graph languages, offering modular extensions, semantic enrichment, and introspection tools.\n\n# Why this Software?\n\nRead [Why](why.md) this software was created.\n\n---\n\n\n# Otter Design\n\nCurrent design.\n\n![Otter Design](assets/design.png)\n\n### Features\n\n-  Round-robin and purpose-based balancing\n-  HTTP proxy for Dgraph `/query` and `/mutate`\n-  WebSocket server with support for `query`, `mutation`, and `upsert`\n-  Simple token-based authentication\n-  Configurable via environment variables or YAML\n-  Otter now supports GraphQL queries via Ratel. Just enable the experimental feature `ratel-graphql: true`\n\n---\n\n## Run Otter with Docker\n\nRequirements\n\n* Clone the repository\n\n* Docker\n\n* Docker Compose\n\n* (optional) make installed\n\n#### Run with make\n\n```bash\nmake rund\n```\n\n Manual Docker Compose\nIf you don't have make:\n\n```bash\ncd examples/cluster\ndocker compose up --build\n```\n\n#### Configuration\nBy default, Otter will load config from:\n\n```ini\nCONFIG_FILE=/app/manifest/config_docker.yaml\n```\n\nIf you want to change the config:\n\n```\nmanifest/config_docker.yaml\n```\n\nOr override with environment variables (see internal/config/config.go for supported vars)\n\n---\n\n### Example WebSocket Payload\n\n```json\n{\n  \"type\": \"upsert\",\n  \"query\": \"query { u as var(func: eq(email, \\\"test@example.com\\\")) }\",\n  \"mutation\": \"uid(u) \u003cname\u003e \\\"Test\\\" .\",\n  \"cond\": \"@if(eq(len(u), 1))\",\n  \"commitNow\": true\n}\n```\n\n---\n\n### Run Locally\n\n```bash\ngit clone https://github.com/OpenDgraph/Otter.git\ncd Otter\n```\n\n```bash\nexport CONFIG_FILE=./manifest/config.yaml\ngo run cmd/proxy/main.go\n```\n\nSet your balancer strategy inside `config.yaml`:\n\n```yaml\nbalancer_type: purposeful # or round-robin\n```\n\n---\n\n###  HTTP Proxy Endpoints\n\n| Endpoint   | Method | Description         |\n|------------|--------|---------------------|\n| `/query`   | POST   | Executes a DQL query |\n| `/mutate`  | POST   | Executes a mutation  |\n\nSupported Content-Types:\n\n- `application/json`\n- `application/dql`\n\nExample request:\n```bash\ncurl -X POST http://localhost:8080/query \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\": \"{ data(func: has(email)) { uid name email } }\"}'\n```\n\n---\n\n---\n\n### WebSocket Usage\n\n**URL**: `ws://localhost:8089/ws`\n\n#### Supported message types:\n\n- `auth` -\u003e authenticate\n- `ping` -\u003e keep connection alive\n- `query` / `mutation` / `upsert` → require authentication\n\n#### Example (after auth):\n\n```json\n{\n  \"type\": \"query\",\n  \"query\": \"{ data(func: has(email)) { uid name email } }\",\n  \"token\": \"banana\",\n  \"verbose\": true\n}\n```\n\n###  Load Balancing Modes\n\nAvailable types:\n\n- `round-robin` *(default)*\n- `defined` *(per-purpose: query/mutation/upsert)*\n\nTo use `defined`, provide a YAML like this:\n\n```yaml\nbalancer_type: defined\ngroups:\n  query:\n    - localhost:9080\n  mutation:\n    - localhost:9081\n  upsert:\n    - localhost:9082\n```\n\n---\n\n###  Roadmap\n\n- [ ] Automatic health checks\n- [ ] Support for multiple Balancing strategies\n- [ ] Graph model abstraction\n- [ ] Become a framework\n\nMore purposeful Balancing strategies:\n- [x] `round-robin` basic round-robin\n- [x] `round-robin-purposeful` with purpose\n- [ ] `round-robin-healthy` support\n- [ ] `round-robin-on-RW` separate readonly and write only\n- [ ] `round-robin-avoid-leaders` avoid leaders\n- [ ] `round-robin-leaders-only` leaders only\n- [ ] `round-robin-state-based` this will check the state of the Alpha and check memory usage and coroutine count\n---","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendgraph%2Fotter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopendgraph%2Fotter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopendgraph%2Fotter/lists"}