try-lacinia
Clojure
7
lacinia
1
graphql
4
White

Quan viết ngày 01/04/2017

Overview

Walmart recently open source Lacinia , a library for implementing Facebook’s GraphQL specification at server-side, in idiomatic Clojure.

This is a getting started guide to have an overview about this library.

Define the Schema

The schema is described as an EDN data structure:

{:enums
 {:episode
  {:description "The episodes of the original Star Wars trilogy."
   :values      ["NEWHOPE" "EMPIRE" "JEDI"]}}

 :objects
 {:droid
  {:fields {:id                {:type Int}
            :name              {:type String}
            :appears_in        {:type (list :episode)}
            :primary_functions {:type (list String)}}}

  :human
  {:fields {:id          {:type Int}
            :name        {:type String}
            :home_planet {:type String}
            :appears_in  {:type (list :episode)}}}}

 :queries
 {:hero  {:type    (non-null :human)
          :args    {:episode {:type :episode}}
          :resolve :get-hero}
  :droid {:type    :droid
          :args    {:id {:type String :default-value "2001"}}
          :resolve :get-droid}}}

Compile the Schema

The schema starts as a data structure, we need to add in the field resolver fn and then compile the result.

(require '[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
         '[com.walmartlabs.lacinia.schema :as schema])

(defn get-hero [context arguments value]
  (let [{:keys [episode]} arguments]
    (if (= episode "NEWHOPE")
      {:id          1000
       :name        "Luke"
       :home-planet "Tatooine"
       :appears-in  ["NEWHOPE" "EMPIRE" "JEDI"]}
      {:id          2000
       :name        "Lando Calrissian"
       :home-planet "Socorro"
       :appears-in  ["EMPIRE" "JEDI"]})))

(def star-wars-schema
  (-> (io/resource "star-wars-schema.edn")
      slurp
      edn/read-string
      (attach-resolvers {:get-hero  get-hero
                         :get-droid (constantly {})})
      schema/compile))

Using the API

We can now execute queries:

(require
  '[com.walmartlabs.lacinia :as ql])

(ql/execute star-wars-schema
            "query { hero { id name }}"
            nil nil)
;;=> {:data {:hero #ordered/map([:id 2000] [:name "Lando Calrissian"])}}

(ql/execute star-wars-schema
            "query { hero(episode: NEWHOPE){ id name appears_in}}"
            nil nil)
;;=> {:data {:hero #ordered/map([:id 1000] [:name "Luke"] [:appears_in ["NEWHOPE" "EMPIRE" "JEDI"]])}}

A failed query would return a map with an :errors key

(ql/execute star-wars-schema
            "query { hero(id: 1000){ id name appears_in}}"
            nil nil)
;;=>
{:errors [{:message "Exception applying arguments to field `hero': Unknown argument `id'.",
           :query-path [],
           :locations [{:line 1, :column 6}],
           :field :hero,
           :argument :id,
           :defined-arguments (:episode)}]}

Put it into web tier

Lacinia know nothing about the web tier, it just knows about parsing and executing queries against a compiled schema.

Put it into a Ring web stacks, we'll have a web service that handles graphql request:

http POST http://localhost:3000/graphql \
     Content-Type:application/graphql \
     <<< '{
            hero(episode: NEWHOPE) {
              movies: appears_in
            }
          }'

{
    "data": {
        "hero": {
            "movies": [
                "NEWHOPE", 
                "EMPIRE", 
                "JEDI"
            ]
        }
    }
}

ref

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Quan

5 bài viết.
2 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
1 0
Clojure supports flexible concurrency models for real world complexity: (Link): builtin support. (Link): similar to Golang concurrency model, w...
Quan viết hơn 2 năm trước
1 0
Bài viết liên quan
White
0 0
Chào các bạn Mình vừa mới làm một side project để cập nhật công nghệ mới nhất về React stack. Shopping Cart của mình được build bằng TypeScript, N...
Đinh Viễn viết 2 tháng trước
0 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
5 bài viết.
2 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!