zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

adapter.ex (4084B)


      1 defmodule Absinthe.Adapter do
      2   @moduledoc """
      3   Absinthe supports an adapter mechanism that allows developers to define their
      4   schema using one code convention (eg, `snake_cased` fields and arguments), but
      5   accept query documents and return results (including names in errors) in
      6   another (eg, `camelCase`).
      7 
      8   Adapters aren't a part of GraphQL, but a utility that Absinthe adds so that
      9   both client and server can use use conventions most natural to them.
     10 
     11   Absinthe ships with four adapters:
     12 
     13   * `Absinthe.Adapter.LanguageConventions`, which expects schemas to be defined
     14     in `snake_case` (the standard Elixir convention), translating to/from `camelCase`
     15     for incoming query documents and outgoing results. (This is the default as of v0.3.)
     16   * `Absinthe.Adapter.Underscore`, which is similar to the `Absinthe.Adapter.LanguageConventions`
     17     adapter but converts all incoming identifiers to underscores and does not
     18     modify outgoing identifiers (since those are already expected to be
     19     underscores). Unlike `Absinthe.Adapter.Passthrough` this does not break
     20     introspection.
     21   * `Absinthe.Adapter.Passthrough`, which is a no-op adapter and makes no
     22     modifications. (Note at the current time this does not support introspection
     23     if you're using camelized conventions).
     24   * `Absinthe.Adapter.StrictLanguageConventions`, which expects schemas to be
     25     defined in `snake_case`, translating to `camelCase` for outgoing results.
     26     This adapter requires incoming query documents to use `camelCase`.
     27 
     28   To set an adapter, you pass a configuration option at runtime:
     29 
     30   For `Absinthe.run/3`:
     31 
     32   ```
     33   Absinthe.run(
     34     query,
     35     MyApp.Schema,
     36     adapter: YourApp.Adapter.TheAdapterName
     37   )
     38   ```
     39 
     40   For `Absinthe.Plug`:
     41 
     42   ```
     43   forward "/api",
     44     to: Absinthe.Plug,
     45     init_opts: [schema: MyAppWeb.Schema, adapter: YourApp.Adapter.TheAdapterName]
     46   ```
     47 
     48   For GraphiQL:
     49 
     50   ```
     51   forward "/graphiql",
     52     to: Absinthe.Plug.GraphiQL,
     53     init_opts: [schema: MyAppWeb.Schema, adapter: YourApp.Adapter.TheAdapterName]
     54   ```
     55 
     56   Check `Absinthe.Plug` for full documentation on using the Plugs
     57 
     58   Notably, this means you're able to switch adapters on case-by-case basis.
     59   In a Phoenix application, this means you could even support using different
     60   adapters for different clients.
     61 
     62   A custom adapter module must merely implement the `Absinthe.Adapter` protocol,
     63   in many cases with `use Absinthe.Adapter` and only overriding the desired
     64   functions.
     65 
     66   ## Writing Your Own
     67 
     68   All you may need to implement in your adapter is `to_internal_name/2` and
     69   `to_external_name/2`.
     70 
     71   Check out `Absinthe.Adapter.LanguageConventions` for a good example.
     72 
     73   Note that types that are defined external to your application (including
     74   the introspection types) may not be compatible if you're using a different
     75   adapter.
     76   """
     77 
     78   @type t :: module
     79 
     80   defmacro __using__(_) do
     81     quote do
     82       @behaviour unquote(__MODULE__)
     83 
     84       def to_internal_name(external_name, _role) do
     85         external_name
     86       end
     87 
     88       def to_external_name(internal_name, _role) do
     89         internal_name
     90       end
     91 
     92       defoverridable to_internal_name: 2,
     93                      to_external_name: 2
     94     end
     95   end
     96 
     97   @typedoc "The lexical role of a name within the document/schema."
     98   @type role_t :: :operation | :field | :argument | :result | :type | :directive
     99 
    100   @doc """
    101   Convert a name from an external name to an internal name.
    102 
    103   ## Examples
    104 
    105   Prefix all names with their role, just for fun!
    106 
    107   ```
    108   def to_internal_name(external_name, role) do
    109     role_name = role |> to_string
    110     role_name <> "_" <> external_name
    111   end
    112   ```
    113   """
    114   @callback to_internal_name(binary | nil, role_t) :: binary | nil
    115 
    116   @doc """
    117   Convert a name from an internal name to an external name.
    118 
    119   ## Examples
    120 
    121   Remove the role-prefix (the inverse of what we did in `to_internal_name/2` above):
    122 
    123   ```
    124   def to_external_name(internal_name, role) do
    125     internal_name
    126     |> String.replace(~r/^\#{role}_/, "")
    127   end
    128   ```
    129   """
    130   @callback to_external_name(binary | nil, role_t) :: binary | nil
    131 end