Liking cljdoc? Tell your friends :D

Phrag

GraphQL from a RDBMS Connection

Phrag implements its approach to GraphQL on RDBMS for an instant and flexible data accesses with customization options.

main Clojars Project cljdoc badge

Overview

  • Instantly Operational: Phrag creates a GraphQL simply from a RDBMS connection, using schema data of tables, columns, and primary / foreign keys. It can be run as a Clojure project or stand-alone releases.

  • CRUD / Relationship Features: tables and/or views become queryable as root objects including nested objects of n-ary relationships with aggregation, filter, sorting and pagination supported. Mutations (create, update and delete) are also created per table.

  • Performance in Mind: Phrag's query resolver translates a nested object query into a single SQL query, leveraging correlated subqueries and JSON functions. Load tests have also been performed to verify it scales linear with resources without obvious bottlenecks.

  • Customization: Phrag comes with an interceptor capability to customize behaviors of GraphQL. Custom functions can be configured before & after database accesses per an operation type & table. It can make a GraphQL service more practical with access controls, event firing and more.

Requirements

Though there are multiple ways to run, Phrag only requires an RDBMS to create its GraphQL. Here's a quick view of database constructs that 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 query objects.

  • Indices on foreign key columns: Phrag queries a database by both origin and destination columns of foreign keys for nested objects. It should be noted that creating a foreign key does not always index those columns (especially origin column).

Notes:

  • Supported databases are SQLite and PostgreSQL.

  • If PostgreSQL is used, Phrag queries usage tables such as key_column_usage and constraint_column_usage to retrieve PK / FK info, therefore a 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.

Usage

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 in config, but there are many more configurable options. Please refer to configuration doc for details.

Stand-alone Version

There is a stand-alone version of Phrag which is runnable as a Docker container or Java process with a single command. It's suitable if Phrag's GraphQL is desired without any custom logic or if one wants to play around with it. Here is the repository of those artifacts for more details.

Try it out as a Docker container with a self-contained DB:

docker run -it -p 3000:3000 ykskb/phrag-standalone:latest
# visit http://localhost:3000/graphiql/index.html

Run as a Docker container with your SQLite:

docker run -it -p 3000:3000 \
-v /host/db/dir:/database \ # mount a directory of your database
-e JDBC_URL=jdbc:sqlite:/database/db.sqlite \ # specify DB URL
ykskb/phrag-standalone:latest
# visit http://localhost:3000/graphiql/index.html

Documentation

Example projects:

  • SNS: a situated project to verify Phrag's concept and practicality. It has authentication, access control and custom logics through Phrag's interceptors.

Contribution to Phrag

Please feel free to open Github issues to send suggestions, report bugs or discuss features. PRs are also welcomed.

Copyright © 2021 Yohei Kusakabe

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close