Skip to content

Commit f369cdd

Browse files
authored
Merge pull request #468 from juanscasado/feature/union-leading-bar-465
Support leading vertical bar in union types (issue #465)
2 parents 1d447c5 + 1cf7ccb commit f369cdd

File tree

4 files changed

+90
-0
lines changed

4 files changed

+90
-0
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ Lacinia features:
2727
- Efficient and asynchronous query execution.
2828

2929
- Full support for GraphQL types, interfaces, unions, enums, input objects, and custom scalars.
30+
- Union types in SDL now support an optional leading vertical bar (|) before the first member, following the GraphQL specification. For example:
31+
32+
```graphql
33+
union Searchable =
34+
| Business
35+
| Employee
36+
```
3037

3138
- Full support for GraphQL subscriptions.
3239

docs/json-scalar-example.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# Example: Raw JSON Scalar in Lacinia
2+
3+
## Motivation
4+
5+
It is common in GraphQL APIs to need a field that can accept or return arbitrary JSON data. Lacinia does not provide a built-in JSON scalar, but it is straightforward to define one. This example demonstrates how to implement and use a raw JSON scalar in your Lacinia schema.
6+
## Recommendations and Warnings
7+
8+
- Always validate incoming JSON data to avoid security issues and unexpected errors.
9+
- Consider restricting the structure of the JSON if possible, to make your API more predictable.
10+
- Document clearly which fields use the JSON scalar and what kind of data is expected.
11+
- Be aware that large or deeply nested JSON objects may impact performance.
12+
## Example GraphQL Query and Response
13+
14+
Suppose you have a field in your schema that returns a JSON value:
15+
16+
```edn
17+
{:objects
18+
{:Root
19+
{:fields
20+
{:config {:type :JSON}}}}}
21+
```
22+
23+
You can query this field as follows:
24+
25+
```graphql
26+
query {
27+
config
28+
}
29+
```
30+
31+
And the response might look like:
32+
33+
```json
34+
{
35+
"data": {
36+
"config": {
37+
"enabled": true,
38+
"threshold": 42,
39+
"options": ["a", "b", "c"]
40+
}
41+
}
42+
}
43+
```
44+
## Implementing the Scalar Functions in Clojure
45+
46+
You can use the [cheshire](https://github.com/dakrone/cheshire) library to parse and generate JSON in Clojure. Here is an example implementation:
47+
48+
```clojure
49+
(ns my-app.json-scalar
50+
(:require [cheshire.core :as json]))
51+
52+
(defn parse-json [value]
53+
(try
54+
(json/parse-string value true)
55+
(catch Exception _
56+
nil)))
57+
58+
(defn serialize-json [value]
59+
(json/generate-string value))
60+
```
61+
62+
Make sure to add `cheshire` to your dependencies in `deps.edn`:
63+
64+
```clojure
65+
;; deps.edn
66+
{:deps {cheshire {:mvn/version "5.11.0"}}}
67+
```
68+
type Product {
69+
id: ID!
70+
metadata: JSON
71+
}
72+
73+
type Query {
74+
getProduct(id: ID!): Product
75+
...existing code...

src/com/walmartlabs/lacinia/parser/schema.clj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,10 +428,13 @@
428428
(apply-directives directiveList))]
429429
extension-meta)))
430430

431+
431432
(defmethod xform :unionTypes
432433
[prod]
433434
(->> prod
434435
rest
436+
;; Remove leading vertical bar if present
437+
(drop-while #(= (first %) :verticalBar))
435438
(filter #(-> % first (= :anyName)))
436439
(mapv xform)))
437440

test/com/walmartlabs/lacinia/unions_test.clj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
(deftest union-supports-leading-vertical-bar
2+
(let [sdl "union Searchable =\n | Business\n | Employee"
3+
schema (ql/schema sdl)]
4+
(is (= #{:Business :Employee}
5+
(set (get-in schema [:unions :Searchable :members])))))
16
; Copyright (c) 2017-present Walmart, Inc.
27
;
38
; Licensed under the Apache License, Version 2.0 (the "License")

0 commit comments

Comments
 (0)