GraphQL from a RDBMS Connection
Phrag implements an approach of GraphQL on RDBMS for an instant and flexible data access with customization options.
Instantly Operational: Phrag creates a GraphQL simply from a RDBMS connection, using schema data such as tables, columns, and primary / foreign keys. It can be run as a Clojure project or a stand-alone executable.
Relationship / CRUD Features: tables and/or views become queryable as root objects containing relationships as nested objects with aggregation, filter, sorting and pagination supported. Mutations (create
, update
and delete
) are also created per table.
Customization: Phrag comes with an interceptor capability to customize behaviors of GraphQL. Custom functions can be configured in Clojure before & after database accesses per table and operation type, which can make GraphQL more practical with access controls, event firing and more.
Performance in Mind: Phrag's query resolver implements a batched SQL query per nest level to avoid N+1 problem. Load tests have also been performed to verify it scales linear with resources without obvious bottlenecks.
All needed is an RDBMS. Here's a quick view of database constructs which are important for Phrag. Detailed mechanism is explained here.
Primary keys: Phrag uses primary keys as identifiers of GraphQL mutations. Composite primary key is supported.
Foreign keys: Phrag translates foreign keys to nested properties in GraphQL objects.
Indices on foreign key columns: Phrag queries a database by origin and destination columns of foreign keys for nested objects. It should be noted that creating a foreign key does not index those columns.
Notes:
Supported databases are SQLite and PostgreSQL.
If PostgreSQL is used, Phrag queries usage tables such as
key_column_usage
andconstraint_column_usage
to retrieve PK / FK info, therefore the database user provided to Phrag needs to be identical to the one that created those keys.Not all database column types are mapped to Phrag's GraphQL fields yet. Any help would be appreciated through issues and PRs.
Phrag's GraphQL can be created with phrag.core/schema
function and invoked through phrag.core/exec
function:
(let [config {:db (hikari/make-datasource my-spec)}
schema (phrag/schema config)]
(phrag/exec config schema query vars req))
There is also a support for creating Phrag's GraphQL as a route for reitit or Bidi:
;; Add a route (path & handler) into a ring router:
(ring/router (phrag.route/reitit {:db my-datasource})
;; Also callable as an Integrant config map key
{:phrag.route/reitit {:db (ig/ref :my/datasource)}}
Notes:
Database (
:db
) is the only required parameter inconfig
, but there are many more configurable options. Please refer to configuration doc for details.
There is a stand-alone version of Phrag which is runnable as a Docker container or a Java process with a single command. It's suitable if a Phrag's GraphQL is desired without any custom logic or if one wants to play around with it. The repository for these artifacts is here for more options and information.
# example: Docker container with SQLite
# visit http://localhost:3000/graphiql/index.html after running:
docker run -it -p 3000:3000 \
-e JDBC_URL=jdbc:sqlite:path/to/db.sqlite \
ykskb/phrag-standalone:latest
Copyright © 2021 Yohei Kusakabe
Can you improve this documentation?Edit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close