Last active
October 3, 2021 01:44
-
-
Save paulfioravanti/76483826b2e58bb8f1e3f5ab33692882 to your computer and use it in GitHub Desktop.
Example of doing a GraphQL inline fragment in Elm (contactListSpec) against a Union type for paginated objects in Phoenix. Ref: https://github.com/paulfioravanti/phoenix-and-elm/tree/graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ContactList.Request exposing (fetchContactList) | |
import Contact.Request | |
import ContactList.Model exposing (ContactList) | |
import GraphQL.Request.Builder as Builder | |
exposing | |
( Document | |
, NonNull | |
, ObjectType | |
, Request | |
, Query | |
, ValueSpec | |
, field | |
, int | |
, list | |
, object | |
, onType | |
, string | |
, with | |
) | |
import GraphQL.Request.Builder.Arg as Arg | |
import GraphQL.Request.Builder.Variable as Var | |
{-| | |
query($searchQuery: String, $pageNumber: Int) { | |
contacts(search: $searchQuery, page: $pageNumber) { | |
entries { | |
... on Contact { | |
id | |
firstName | |
lastName | |
gender | |
birthDate | |
location | |
phoneNumber | |
headline | |
picture | |
} | |
}, | |
pageNumber, | |
pageSize, | |
totalPages, | |
totalEntries | |
} | |
} | |
-} | |
fetchContactList : Int -> String -> Request Query ContactList | |
fetchContactList page search = | |
let | |
pageNumber = | |
Arg.variable (Var.required "pageNumber" .pageNumber Var.int) | |
searchQuery = | |
Arg.variable (Var.required "searchQuery" .searchQuery Var.string) | |
contactsField = | |
field | |
"contacts" | |
[ ( "page", pageNumber ), ( "search", searchQuery ) ] | |
contactListSpec | |
params = | |
{ pageNumber = page | |
, searchQuery = search | |
} | |
in | |
contactsField | |
|> Builder.extract | |
|> Builder.queryDocument | |
|> Builder.request params | |
contactListSpec : ValueSpec NonNull ObjectType ContactList vars | |
contactListSpec = | |
let | |
contact = | |
(Builder.extract | |
(Builder.assume | |
(Builder.inlineFragment | |
(Just (onType "Contact")) | |
Contact.Request.contactSpec | |
) | |
) | |
) | |
in | |
ContactList | |
|> object | |
|> with (field "entries" [] (list contact)) | |
|> with (field "pageNumber" [] int) | |
|> with (field "totalEntries" [] int) | |
|> with (field "totalPages" [] int) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule PhoenixAndElmWeb.Schema.Types do | |
@moduledoc false | |
use Absinthe.Schema.Notation | |
alias PhoenixAndElm.AddressBook.Contact | |
import_types(Absinthe.Type.Custom) | |
@desc "A paginated set of entries from a database" | |
union :entries do | |
@desc "Union object for all paginated things." | |
types([:contact]) | |
resolve_type(fn %Contact{}, _ -> :contact end) | |
end | |
@desc "A set of paginated items, including pagination metadata" | |
object :paginated do | |
@desc "The total number of entries" | |
field(:total_entries, :integer) | |
@desc "The total number of paginated pages" | |
field(:total_pages, :integer) | |
@desc "The current page number" | |
field(:page_number, :integer) | |
@desc "The number of paginated items per page" | |
field(:page_size, :integer) | |
@desc "The list of paginated items" | |
field(:entries, list_of(:entries)) | |
end | |
@desc "An address book contact" | |
object :contact do | |
@desc "Contact identifier" | |
field(:id, :integer) | |
@desc "Contact first name" | |
field(:first_name, :string) | |
@desc "Contact last name" | |
field(:last_name, :string) | |
@desc "Contact gender" | |
field(:gender, :integer) | |
@desc "Contact birth date" | |
field(:birth_date, :date) | |
@desc "Contact current location" | |
field(:location, :string) | |
@desc "Contact phone number" | |
field(:phone_number, :string) | |
@desc "Contact email" | |
field(:email, :string) | |
@desc "Contact headline" | |
field(:headline, :string) | |
@desc "Contact picture" | |
field(:picture, :string) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment