0

I want to have a custom GeoPoint type in my schema and I can't find any example how to do this in a schema types file. The only way I found was using the input_object in the schema file. Is it possible to do it this way using Absinthe.Blueprint.Input.Object ??

this is my custom type:

defmodule MyAppWeb.Schema.Types.GeoPoint do

  scalar :geo_point, name: "GeoPoint" do
    serialize(&encode/1)
    parse(&decode/1)
  end

  defp encode(value) do
    MyApp.JasonEncoders.encode_model(value)
  end

  defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
    with {:ok, decoded} <- Jason.decode(value),
         {:ok, point} <- Geo.JSON.decode(decoded) do
      {:ok, point}
    else
      _ -> :error
    end
  end

  defp decode(%Input.Null{}) do
    {:ok, nil}
  end
end

now I can create a new entry with this mutation

mutation (
  $title: String!,
  $geom: GeoPoint!
) {
  offer: createOffer(
    title: $title,
    geom: $geom
  ) 

and these variables

{
  "title": "Point",
  "geom": "{\"coordinates\":[1,2],\"type\":\"Point\"}"
}

I would prefer to create using something like

{
  "title": "Point",
  "geom": {
    "lat": 1,
    "long": 2
  }
}

or

{
  "title": "Point",
  "lat": 1,
  "long": 2
}
Daniel Kukula
  • 333
  • 3
  • 7

2 Answers2

2

What you want to do cannot be done with a scalar type, but you can use an input_object:

E.g.

input_object :geom do
  field :lat, non_null(:float)
  field :lon, non_null(:float)
end

mutation do
  field :create_offer, :offer do
    arg :title, non_null(:string)
    arg :geom, non_null(:geom)

    resolve &create_offer/2
  end
end
1

There was new flag added to absinthe scalars called open_ended: true that you can use now to get a Absinthe.Blueprint.Input.Object on a scalar. Sample of that in use

  scalar :any, name: "_Any", open_ended: true do
    parse fn value -> {:ok, value} end
    serialize fn value -> value end
  end
Kdawgwilk
  • 369
  • 3
  • 11