A spec-driven GraphQL Backend-for-Frontend engine in Clojure.
Write a YAML spec → get a fully functional GraphQL API. No boilerplate per endpoint.
Define your endpoints in a YAML spec. The engine generates a Lacinia GraphQL schema, fans out HTTP calls to your backend services in parallel, maps the responses to your output types with jq, and returns a well-formed GraphQL response — including partial data and structured errors when things go wrong.
bff-spec.yaml
│
├── spec_loader load YAML, resolve env vars, pre-compile jq
│
├── schema_builder generate Lacinia schema (objects, queries, mutations)
│
└── executor
├── validator optional — short-circuit before any backend call
├── graph dep graph → execution waves (topological sort)
├── [Wave 0] missionary m/join → parallel HTTP calls
├── [Wave 1] missionary m/join → parallel HTTP calls
├── jq_engine apply compiled jq to map step results → output fields
├── transformer optional — post-process mapped output
└── resolver optional — replace backend chain entirely
Add to deps.edn:
io.github.rthadani/bff {:mvn/version "0.2.0"}
Create a spec file and start the handler:
(require '[bff.core :as bff])
;; Simplest — no extensions
(def handler (bff/create-handler "bff-spec.yaml"))
;; With extensions
(def handler
(bff/create-handler
"bff-spec.yaml"
{:validators {"check-order" my-validator-fn}
:transformers {"attach-warnings" my-transformer-fn}
:resolvers {"user-profile" my-resolver-fn}
:cache my-cache-store}))
;; handler is a standard Ring handler — mount it however you like
Or run it standalone:
clj -M -m bff.main bff-spec.yaml
# GraphQL server on http://localhost:8080 (set PORT to change)
Send a query:
curl -X POST http://localhost:8080 \
-H "Content-Type: application/json" \
-d '{"query": "{ userDashboard(userId: \"u123\") { fullName email } }"}'
Tag a release to deploy to Clojars:
git tag v0.1.0 && git push origin v0.1.0
The publish workflow runs tests then deploys using CLOJARS_USERNAME and
CLOJARS_PASSWORD secrets.
Can you improve this documentation? These fine people already did:
rthadani & Rohit ThadaniEdit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |