try-lacinia
Clojure
7
lacinia
1
graphql
3
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 1 năm trước
1 0
Bài viết liên quan
White
0 0
Each technology have different philosophies, therefore different best practices when serving over HTTP: | | REST | GraphQL | | |::|::| | Endpoints...
Quan viết hơn 1 năm trước
0 0
White
0 0
Clojure là ngôn ngữ functional có hỗ trợ OOP. Về mặt khoa học máy tính, có nhiều cách để thực hiện đa hình. Ở phiên bản trước 1.2, đa hình trong Cl...
Ngoc Dao viết hơn 2 năm 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á!