在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):walmartlabs/lacinia开源软件地址(OpenSource Url):https://github.com/walmartlabs/lacinia开源编程语言(OpenSource Language):Clojure 98.7%开源软件介绍(OpenSource Introduction):LaciniaLacinia Manual | Lacinia Tutorial | API Documentation This library is a full implementation of Facebook's GraphQL specification. Lacinia should be viewed as roughly analogous to the official reference JavaScript implementation. In other words, it is a backend-agnostic GraphQL query execution engine. Lacinia is not an Object Relational Mapper ... it's simply the implementation of a contract sitting between the GraphQL client and your data. Lacinia features:
Lacinia has been developed with a set of core philosophies:
This library can be plugged into any Clojure HTTP pipeline. The companion library lacinia-pedestal provides full HTTP support, including GraphQL subscriptions, for Pedestal. An externally developed library, duct-lacinia, provides similar capability for Duct. Getting StartedFor more detailed documentation, read the manual. GraphQL starts with a schema definition of exposed types. A schema starts as an EDN file; the example below demonstrates a small subset of the available options: {:enums
{:episode
{:description "The episodes of the original Star Wars trilogy."
:values [:NEWHOPE :EMPIRE :JEDI]}}
:objects
{:droid
{:fields {:primary_functions {:type (list String)}
:id {:type Int}
:name {:type String}
:appears_in {:type (list :episode)}}}
: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}}} A schema alone describes what data is available to clients, but doesn't identify where the data comes from; that's the job of a field resolver, provided by the :resolve key inside fields such as the :hero and :droid query. The values here, :get-hero and :get-droid, are placeholders; the startup code
of the application will use
A field resolver is just a function which is passed the application context, a map of arguments values, and a resolved value from a parent field. The field resolver returns a value. If it's a scalar type, it should return a value that conforms to the defined type in the schema. If not, it's a type error. The field resolver is totally responsible for obtaining the data from whatever external store you use: whether it is a database, a web service, or something else. It's important to understand that every field has a field resolver, even if you don't define it explicitly. If you don't supply a field resolver, Lacinia provides a default field resolver, customized to the field. Here's what the (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"]}))) In this greatly simplified example, the field resolver can simply return the resolved value. Field resolvers that return multiple values return a list, vector, or set of values. In real applications, a field resolver might execute a query against a database, or send a request to another web service. After attaching resolvers, it is necessary to compile the schema; this step performs validations, provide defaults, and organizes the schema for efficient execution of queries. This needs only be done once, in application startup code: (require '[clojure.edn :as edn]
'[com.walmartlabs.lacinia.util :refer [attach-resolvers]]
'[com.walmartlabs.lacinia.schema :as schema])
(def star-wars-schema
(-> "schema.edn"
slurp
edn/read-string
(attach-resolvers {:get-hero get-hero
:get-droid (constantly {})})
schema/compile)) With the compiled application available, it can be used to execute requests; this typically occurs inside a Ring handler function: (require '[com.walmartlabs.lacinia :refer [execute]]
'[clojure.data.json :as json])
(defn handler [request]
{:status 200
:headers {"Content-Type" "application/json"}
:body (let [query (get-in request [:query-params :query])
result (execute star-wars-schema query nil nil)]
(json/write-str result))}) Lacinia doesn't know about the web tier at all, it just knows about parsing and executing queries against a compiled schema. A companion library, lacinia-pedestal, is one way to expose your schema on the web. Clients will typically send a JSON POST request, with a
The {:data
{:hero {:id 2000
:name "Lando Calrissian"}}} This example request has no errors, and contained only a single query. GraphQL supports multiple queries in a single request. There may be errors executing the query, Lacinia will process as much as it can, and will report errors in the :errors key. One of the benefits of GraphQL is that the client has the power to rename fields in the response:
{:data {:hero {:movies [:NEWHOPE :EMPIRE :JEDI]}}} This is just an overview, far more detail is available in the manual. StatusThis library has been used in production at Walmart since 2017, going through a very long beta period as it evolved; we transitioned to a 1.0 release on 9 Oct 2021. To use this library with Clojure 1.8, you must include a dependency on clojure-future-spec. More details are in the manual. LicenseCopyright © 2017-2021 WalmartLabs Distributed under the Apache License, Version 2.0. |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论