Skip to content

WhatsApp/erlang-argo

Repository files navigation

argo

Build Status Hex.pm

argo is a compact binary serialization format for GraphQL.

This library provides support for Erlang and Elixir following the Argo 1.2.0 specifications.

See the CONTRIBUTING file for how to help out.

Installation

Add argo_graphql to your project's dependencies in mix.exs

defp deps() do
  [
    {:argo, "~> 1.0", hex: :argo_graphql}
  ]
end

Add argo_graphql to your project's dependencies in your Makefile for erlang.mk or the following to your rebar.config

{deps, [
    {argo, "~> 1.0", {pkg, argo_graphql}}
]}.

Usage

Using the "Introduction to GraphQL" example:

% Load the GraphQL Service Document.
SD = argo_graphql_service_document:from_string("
  type Query {
    me: User
  }

  type User {
    id: ID
    name: String
  }
"),
% Load the GraphQL Executable Document.
ED = argo_graphql_executable_document:from_string("
  query MyQuery {
    me {
      name
    }
  }
"),
% Derive the Argo Wire Type based on the GraphQL Service Document
% and the GraphQL Executable Document.
{{some, <<"MyQuery">>}, ArgoWireType} = argo_typer:derive_wire_type(SD, ED, none).

% Convert a JSON response to an Argo Value.
JsonValue = #{<<"data">> => #{<<"me">> => #{<<"name">> => <<"Luke Skywalker">>}}},
ArgoValue = argo_value:from_json(ArgoWireType, JsonValue),
% Encode Argo Value using default settings.
ArgoEncoded = argo_value:to_writer(ArgoValue),
% Compare output size to the JSON encoding.
JsonEncoded = jsone:encode(JsonValue),
41 = byte_size(JsonEncoded),
22 = byte_size(ArgoEncoded),
% Argo encoding is roughly 46% smaller than JSON encoding in this case.
46 = trunc((1 - (byte_size(ArgoEncoded) / byte_size(JsonEncoded))) * 100).

% For decoding, use the Argo Wire Type and the Argo encoding bytes.
{<<>>, ArgoValue} = argo_value:from_reader(ArgoWireType, ArgoEncoded).

% Optionally convert back to JSON representation.
JsonResponse = argo_value:to_json(ArgoValue).

Use argo:display/1 or argo:display_with_lines/1 to inspect Argo Wire Types, Argo Values, and GraphQL related data structures:

argo:display(ArgoWireType).
% {
%   data: {
%     me: {
%       name: STRING<String>?
%     }?
%   }?
%   errors?: ERROR[]
%   extensions?: EXTENSIONS
% }

argo:display(ArgoValue).
% {
%   data: NON_NULL({
%     me: NON_NULL({
%       name: NON_NULL(STRING(<<"Luke Skywalker">>)<String>)
%     })
%   })
%   errors?: ABSENT
%   extensions?: ABSENT
% }

License

argo is MIT licensed, as found in the LICENSE file.