language_conventions.ex (2129B)
1 defmodule Absinthe.Adapter.LanguageConventions do 2 use Absinthe.Adapter 3 alias Absinthe.Utils 4 5 @moduledoc """ 6 This defines an adapter that supports GraphQL query documents in their 7 conventional (in JS) camelcase notation, while allowing the schema to be 8 defined using conventional (in Elixir) underscore (snakecase) notation, and 9 transforming the names as needed for lookups, results, and error messages. 10 11 For example, this document: 12 13 ```graphql 14 { 15 myUser: createUser(userId: 2) { 16 firstName 17 lastName 18 } 19 } 20 ``` 21 22 Would map to an internal schema that used the following names: 23 24 * `create_user` instead of `createUser` 25 * `user_id` instead of `userId` 26 * `first_name` instead of `firstName` 27 * `last_name` instead of `lastName` 28 29 Likewise, the result of executing this (camelcase) query document against our 30 (snakecase) schema would have its names transformed back into camelcase on the 31 way out: 32 33 ``` 34 %{ 35 data: %{ 36 "myUser" => %{ 37 "firstName" => "Joe", 38 "lastName" => "Black" 39 } 40 } 41 } 42 ``` 43 44 Note variables are a client-facing concern (they may be provided as 45 parameters), so variable names should match the convention of the query 46 document (eg, camelCase). 47 """ 48 49 @doc "Converts a camelCase to snake_case" 50 @impl Absinthe.Adapter 51 def to_internal_name(nil, _role) do 52 nil 53 end 54 55 def to_internal_name("__" <> camelized_name, role) do 56 "__" <> to_internal_name(camelized_name, role) 57 end 58 59 def to_internal_name(camelized_name, _role) when is_binary(camelized_name) do 60 camelized_name 61 |> Macro.underscore() 62 end 63 64 @doc "Converts a snake_case name to camelCase" 65 @impl Absinthe.Adapter 66 def to_external_name(nil, _role) do 67 nil 68 end 69 70 def to_external_name("__" <> underscored_name, role) do 71 "__" <> to_external_name(underscored_name, role) 72 end 73 74 def to_external_name(<<c::utf8, _::binary>> = name, _) when c in ?A..?Z do 75 name |> Utils.camelize() 76 end 77 78 def to_external_name(underscored_name, _role) when is_binary(underscored_name) do 79 underscored_name 80 |> Utils.camelize(lower: true) 81 end 82 end