id | title | sidebar_label |
---|---|---|
vanilla |
Vanilla Clojure |
Vanilla |
One of the core design goals of GraphQLize is not to tie to any web development library/framework and remain as a drop-in Clojure library. GraphQLize built on top of Lacinia, a de-facto library for implementing GraphQL APIs in Clojure.
Getting started with GraphQLize in vanilla Clojure is straight-forward and involves only three steps.
Create a new Clojure project using deps (or leiningen) and add the GraphQLize and other dependencies.
;; deps.edn
{:paths ["src" "resources"]
:deps {org.clojure/clojure {:mvn/version "1.10.1"}
org.graphqlize/graphqlize {:mvn/version "0.1.0-alpha20"}
;; db connection pool
hikari-cp {:mvn/version "2.10.0"}
;; for postgres
org.postgresql/postgresql {:mvn/version "42.2.8"}
;; for MySQL
mysql/mysql-connector-java {:mvn/version "8.0.19"}}}
The next step is configuring the DataSource. In this example, we are going to use Hikari Connection Pool to manage the database connection.
:::note
For brevity, this sample uses def
to define the states. In a real-world project, you can replace it with Component, Mount, or Integrant.
:::
import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem";
<Tabs defaultValue="postgres" values={[ { label: 'Postgres', value: 'postgres' }, { label: 'MySQL', value: 'mysql' } ] }>
;; src/core.clj
(ns core
(:require [hikari-cp.core :as hikari]))
(def db-spec (hikari/make-datasource {:adapter "postgresql"
:database-name "sakila"
:server-name "localhost"
:port-number 5432
:maximum-pool-size 1
:username "postgres"
:password "postgres"}))
;; src/core.clj
(ns core
(:require [hikari-cp.core :as hikari]))
(def db-spec (hikari/make-datasource {:server-name "localhost"
:maximum-pool-size 1
:jdbc-url "jdbc:mysql://localhost:3306/sakila"
:driver-class-name "com.mysql.cj.jdbc.MysqlDataSource"
:username "root"
:password "mysql123"}))
:::note
Make sure you are changing the above values to refer your database connection. The above example assumes that you are using the sakila database created from this JOOQ's example repository.
:::
Then create a lacinia schema from the data source using GraphQLize.
(ns core
(:require ; ...
[graphqlize.lacinia.core :as l]))
(def db-spec ...)
(def lacinia-schema (l/schema db-spec))
With the lacinia-schema
in place, we can query the underlying database using GraphQL by invoking the Lacinia's execute function.
(ns core
(:require ;...
[com.walmartlabs.lacinia :as lacinia]))
; ...
(defn execute
([query]
(lacinia/execute lacinia-schema query nil nil))
([query variables]
(lacinia/execute lacinia-schema query variables nil)))
=> (execute "query { actorByActorId(actorId: 1) { firstName, lastName } }")
;; {:data { :actorByActorId { :firstName "PENELOPE" :lastName "GUINESS" } } }
The execute
function has an overload to support GraphQL variables as well. The above example can be re-written using variables as below.
=> (execute
"query($actorId: Int!) { actorByActorId(actorId: $actorId) { firstName, lastName } }"
{:actorId 1})
{:data { :actorByActorId { :firstName "PENELOPE" :lastName "GUINESS" } } }
We can also run the introspection queries to know what types and queries the GraphQLizeResolver
supports.
To know all the types generated by the GraphQLize.
=> (execute "{__schema {types {name}}}")
{:data
{:__schema
{:types
({:name "Actor"}
{:name "ActorInfo"}
{:name "Address"} ...)}}}
To know more the fields of a given type, we can run the following introspection query.
=> (execute "{__type(name: \"Actor\") { fields { name type { name kind ofType { name kind }}}}}")
{:data
{:__type
{:fields
({:name "actorId"
:type {:name nil :kind :NON_NULL :ofType {:name "Int" :kind :SCALAR}}}
{:name "filmActors"
:type {:name nil :kind :NON_NULL :ofType {:name nil :kind :LIST}}}
{:name "films"
:type {:name nil :kind :NON_NULL :ofType {:name nil :kind :LIST}}}
{:name "firstName"
:type {:name nil :kind :NON_NULL :ofType {:name "String" :kind :SCALAR}}}
{:name "lastName"
:type {:name nil :kind :NON_NULL :ofType {:name "String" :kind :SCALAR}}}
{:name "lastUpdate"
:type {:name nil :kind :NON_NULL :ofType {:name "String" :kind :SCALAR}}})}}}
Congrats! You are on course to build impressive applications using GraphQLize in less time. To save yourself some more time, do refer this documentation to know more about how GraphQLize generates the GraphQL schema and the queries.
The sample code is available in this GitHub Repository.