walmartlabs / lacinia

GraphQL implementation in pure Clojure
http://lacinia.readthedocs.io/en/latest/
Other
1.82k stars 160 forks source link

Make com.walmartlabs.lacinia/execute support read-only mode #461

Closed namenu closed 3 months ago

namenu commented 3 months ago

According to the graphql-http specification, queries passed in GET requests should not allow mutation.

We can do this by adding :read-only? (default false) to :options, and determining the operation-type from the result of parse-query.

For example:

(defn execute [schema query variables context options]
  ...
  (when (and (:read-only? options) (= :mutation (:operation-type parsed)))
    ;; It should also throw an exception so that the web server will respond with `400 Bad Request` to the client
    (throw (ex-info ...)))

  (execute-parsed-query ...))
hlship commented 3 months ago

Typically, a GraphQL endpoint (say, via lacinia-pedestal) is exposed as using the POST method (not GET, which lacinia-pedestal only supports as a legacy option, as it involves a gigantic query variable). If you want to expose queries using GET and mutations using POST, that can be done in a number of ways; I would suggest having multiple compiled schemas ... this is an area where being able to treat the schema as data is valuable, as you can have a full schema and a stripped-down schema and compile each of them, and build two endpoints around them separately.

However, at its core, lacinia doesn't know about the transport layer, where concerns such as HTTP method come from; so at the very least, a discussion of this belongs in lacinia-pedestal.

namenu commented 3 months ago

Fair enough. Thanks!