Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
GraphQL API in Clojure
Search
Kent OHASHI
January 31, 2019
Programming
97
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
GraphQL API in Clojure
Introduction to GraphQL API development in Clojure
Kent OHASHI
January 31, 2019
More Decks by Kent OHASHI
See All by Kent OHASHI
速習FP in Scala with Flix: Flix言語で親しむ純粋関数型のコード設計
lagenorhynque
0
41
"Simple Made Easy" Made Easier: Clojureに学ぶsimplicity
lagenorhynque
0
56
Property-Based Testing with test.check and clojure.spec
lagenorhynque
0
77
🐬の推し本紹介2025: 『コーディングを支える技術 ――成り立ちから学ぶプログラミング作法』
lagenorhynque
0
140
KotlinでミニマルなResult実装による関数型エラーハンドリング
lagenorhynque
0
86
Functional Calisthenics in Kotlin: Kotlinで「関数型エクササイズ」を実践しよう
lagenorhynque
1
500
関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ
lagenorhynque
1
320
純LISPから考える関数型言語のプリミティブ: Clojure, Elixir, Haskell, Scala
lagenorhynque
1
340
From Scala/Clojure to Kotlin
lagenorhynque
0
140
Other Decks in Programming
See All in Programming
【高い買い物LT会】初任給で話題の国産フィジカルAIを買った話
akagami
PRO
0
180
Webの地図
yosuke_furukawa
PRO
6
5k
AWSに止められる覚悟してますか?
morizo_1984
2
490
Omarchy Tokyo やると聞いて UMPC 買ってセットアップしてきた
mtsmfm
0
190
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
580
Security issues being discussed on Web Platforms
petamoriken
0
1.4k
すこし踏み込む CancellationToken
htkym
2
1.5k
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
9.2k
Intent as Code
shoppingjaws
6
1.1k
The Rails Doctrine Decade
koic
2
420
mrbgem 三角測量 開発
ogom
0
140
速く作れる。その次は、速く確かめられる開発へ 〜AIネイティブ開発を支える、Shift Down〜 / Can build fast. Next, moving to development where we can verify fast.
rkaga
8
5.2k
Featured
See All Featured
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
42k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
510
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
420
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
340
Statistics for Hackers
jakevdp
799
230k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.6k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
310
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
510
Designing Experiences People Love
moore
143
24k
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
690
Transcript
GraphQL API in Clojure GraphQL API in Clojure
lagénorhynque lagénorhynque (defprofile lagénorhynque :aliases [ ] :languages [Clojure Common-Lisp
Scheme Haskell English français] :interests [programming Love-Live! language-learning/linguistics law mathematics] :committing [github.com/lagenorhynque/duct.module.pedestal] :contributing [github.com/japan-clojurians/clojure-site-ja])
1. GraphQL GraphQL query GraphQL schema 2. API implementation project
structure API server GraphQL implementation
Clojure Lacinia GraphQL API
example example : AqoursQL, an example GraphQL API based on
Lacinia-Pedestal & Duct lagenorhynque/aqoursql
GraphQL GraphQL venia & edn
GraphQL query GraphQL query venia
query: query: member_by_id member_by_id { member_by_id(id: 1) { id name
organization_id organization_name } }
response (JSON) response (JSON) { "data": { "member_by_id": { "id":
1, "name": " ", "organization_id": 1, "organization_name": " " } } }
GraphiQL GraphiQL
Clojure REPL Clojure REPL dev> (q #:venia{:queries [[:member_by_id {:id 1}
[:id :name :organization_id :organization_name]]]}) {:data {:member_by_id {:id 1, :name " ", :organization_id 1, :organization_name " "}}}
utility function utility function q q (defn q ([query] (q
query nil)) ([query variables] (lacinia/execute (:aqoursql.graphql/schema system) (venia/graphql-query query) variables {:db (:duct.database.sql/hikaricp system)}))) venia.core/graphqlquery com.walmartlabs.lacinia/execute
query: query: songs songs { songs { name artist {
name members { name } } } }
response (JSON) response (JSON) { "data": { "songs": [ {
"name": " ", "artist": { "name": "Aqours", "members": [ { "name": " " }, ... ] } }, ... ] }
GraphiQL GraphiQL
Clojure REPL Clojure REPL dev> (q #:venia{:queries [[:songs [:name [:artist
[:name [:members [:name]]]]]]]}) {:data {:songs ({:name " ", :artist {:name "Aqours", :members ({:name " "} ...
GraphQL schema GraphQL schema edn
object de nition: object de nition: Member Member """ """
type Member { """ ID""" id: Int! """ """ name: String! """ ID""" organization_id: Int! """ """ organization_name: String! }
resources/aqoursql/graphql-schema.edn {:objects {:Member {:description " " :fields {:id {:type (non-null
Int) :description " ID"} :name {:type (non-null String) :description " "} :organization_id {:type (non-null Int) :description " ID"} :organization_name {:type (non-null String) :description " "}}}}}
object de nition: object de nition: Song Song """ """
type Song { """ ID""" id: Int! """ """ name: String! """" ID"" artist_id: Int! """ """ artist: Artist! """ (YYYY-MM-DD)""" release_date: String! }
resources/aqoursql/graphql-schema.edn {:objects {:Song {:description " " :fields {:id {:type (non-null
Int) :description " ID"} :name {:type (non-null String) :description " "} :artist_id {:type (non-null Int) :description " ID"} :artist {:type (non-null :Artist) :description " "} :release_date {:type (non-null String) :description " (YYYY-MM-DD)"}}}}}
query de nition: query de nition: member_by_id member_by_id type Query
{ """ID """ member_by_id( " ID" id: Int! ): Member }
resources/aqoursql/graphql-schema.edn {:queries {:member_by_id {:type :Member :description "ID " :args {:id
{:type (non-null Int) :description " ID"}} :resolve :query/member-by-id}}}
query de nition: query de nition: songs songs type Query
{ """ """ songs( " ( )" name: String ): [Song] }
{:queries {:songs {:type (list :Song) :description " " :args {:name
{:type String :description " ( )"}} :resolve :query/songs}}}
API implementation API implementation Duct + Pedestal + Lacinia
project structure project structure Duct
Clojure Duct
resources/aqoursql/con g.edn {:duct.profile/base {:duct.core/project-ns aqoursql :duct.server/pedestal { ... } :aqoursql.graphql/schema
{} :aqoursql.graphql/service { ... }} :duct.profile/dev #duct/include "dev" :duct.profile/test #duct/include "test" :duct.profile/local #duct/include "local" :duct.profile/prod {} :duct.module/logging {} :duct.module/sql { ... } :duct.module/pedestal {}}
API server API server Pedestal duct.module.pedestal
Clojure Pedestal
resources/aqoursql/con g.edn {:duct.profile/base {:duct.core/project-ns aqoursql :duct.server/pedestal {:base-service #ig/ref :aqoursql.graphql/service :service
#:io.pedestal.http{:join? true :host #duct/env "SERVER_HOST" :port #duct/env ["SERVER_PORT" Int :or 8888]}} ... } ... :duct.module/pedestal {}}
GraphQL implementation GraphQL implementation Lacinia Lacinia-Pedestal
resources/aqoursql/con g.edn {:duct.profile/base {:duct.core/project-ns aqoursql ... :aqoursql.graphql/schema {} :aqoursql.graphql/service {:schema
#ig/ref :aqoursql.graphql/schema :options {:graphiql true :app-context {:db #ig/ref :duct.database/sql} :env :prod}}} ... }
src/aqoursql/graphql.clj (defmethod ig/init-key ::schema [_ _] (-> (io/resource "aqoursql/graphql-schema.edn") slurp
edn/read-string (util/attach-resolvers resolver-map) schema/compile)) (defmethod ig/init-key ::service [_ {:keys [schema options]}] (lacinia/service-map schema options))
resolver (function) resolver (function) src/aqoursql/graphql.clj (def resolver-map {:query/artist-by-id artists/fetch-artist-by-id :query/artists
artists/list-artists :query/member-by-id members/fetch-member-by-id :query/members members/list-members :query/song-by-id songs/fetch-song-by-id :query/songs songs/list-songs})
resolver function spec src/aqoursql/resolver/members.clj (defn fetch-member-by-id [{:keys [db]} {:keys [id]}
_] (db.member/find-member-by-id db id)) (s/fdef resolver :args (s/cat :app-context map? :arguments (s/nilable map?) :resovled-value (s/nilable map?)))
boundary (DB) boundary (DB) src/aqoursql/boundary/db/member.clj (s/def ::id nat-int?) (s/def ::name
string?) (s/def ::organization_id ::organization/id) (s/def ::organization_name ::organization/name) (s/def ::artist_id ::artist/id) (s/def ::artist_ids (s/coll-of ::artist/id)) (s/def ::member (s/keys :req-un [::id ::name ::organization_id] :opt-un [::organization_name ::artist_id]))
(s/fdef find-member-by-id :args (s/cat :db ::db/db :id ::id) :ret (s/nilable
::member)) ... (defprotocol Member (find-member-by-id [db id]) ... )
dev> (aqoursql.boundary.db.member/find-member-by-id (:duct.database.sql/hikaricp system) 1) {:id 1, :name " ",
:organization_id 1, :organization_name " "} dev> (aqoursql.resolver.members/fetch-member-by-id {:db (:duct.database.sql/hikaricp system)} {:id 1} nil) {:id 1, :name " ", :organization_id 1, :organization_name " "} dev> (q #:venia{:queries [[:member_by_id {:id 1} [:name :organization_name]]]}) {:data {:member_by_id {:name " ", :organization_name " "}}}
Further Reading Further Reading Lacinia Lacinia : Expose Lacinia GraphQL
as Pedestal endpoints example: Lacinia Lacinia-Pedestal Clojure Lacinia GraphQL API lagenorhynque/aqoursql Clojure GraphQL Lacinia Tips
Duct Duct : Duct module for Pedestal Duct duct.module.pedestal Clojure
Duct
Pedestal Pedestal Pedestal Clojure Pedestal
GraphQL GraphQL : Clojure(Script) graphql query generation venia GraphQL |
A query language for your API How to GraphQL - The Fullstack Tutorial for GraphQL GraphQL ─ REST API Learning GraphQL