Elixir client from OpenAPI(Swagger) definition

author

niku

date

2017/04/01

allotted-time

5m

About Me

twitter: niku_name github: niku

Live in Sapporo City, Hokkaido

About Me

A member of Sapporo.beam

About Me

An elixir-lang contributer

/Users/niku/src/elixir-head% git log --author=niku
commit a4028e73604807b9e13a5404a98e9f51d2a1eb0d
Author: niku <niku@niku.name>
Date:   Mon Dec 12 17:27:28 2016 +0900

    Make the example a valid mix project (#5555)

commit 5b9b186d4b6f78f83211821bb4453897be14c13b
Author: niku <niku@niku.name>
Date:   Sun Aug 3 22:58:55 2014 +0900

    Improve IEx docs about .iex.exs

commit e68f617e2add9772082b09c4e35cc03c2cc5bd04
Author: niku <niku@niku.name>
Date:   Tue Jul 29 23:46:52 2014 +0900

    Remove duplicate test

Elixir

I ♡ Elixir and ErlangVM.

A hard thing

In many cases, Official SDK for ErlangVM haven't been provided (yet).

Should I make a elixir client to each service?

(╯ಠ~ಠ)╯︵ ┻━┻

OpenAPI(Swagger)

github.com/OAI/OpenAPI-Specification

language-agnostic interface to REST APIs which allows both humans and computers to discover and understand the capabilities of the service

OpenAPI definition example

write in yaml or json

swagger: '2.0'
info:
  version: 0.1.0
  title: Simple API
paths:
  /:
    get:
      responses:
        200:
          description: OK

OpenAPI definition example

Generate from OpenAPI definition

github.com/swagger-api/swagger-codegen#template-creator

OpenAPI online editor

editor.swagger.io/

OpenAPI online editor

You can download an elixir client generated from OpenAPI definition

An elixir client generated from OpenAPI definition

/Users/niku/Downloads/elixir-client% tree
.
├── README.md
├── config
│   └── config.exs
├── lib
│   └── swagger_petstore
│       ├── api
│       │   ├── pet.ex
│       │   ├── store.ex
│       │   └── user.ex
│       └── model
│           ├── apiResponse.ex
│           ├── category.ex
│           ├── order.ex
│           ├── pet.ex
│           ├── tag.ex
│           └── user.ex
├── mix.exs
└── test
    └── test_helper.exs

6 directories, 13 files

Use an elixir client

Add new pet (definition)

Use an elixir client

Add new pet (code)

named ElixirConfJa2017

SwaggerPetstore.Api.Pet.add_pet(%{"name" => "ElixirConfJa2017"})

Use an elixir client

/Users/niku/Downloads/elixir-client% mix deps.get
(...snip...)
/Users/niku/Downloads/elixir-client%  mix run -e \
% 'IO.inspect SwaggerPetstore.Api.Pet.add_pet(%{"name" => "ElixirConfJa2017"})'
%Tesla.Env{body: %{"id" => 9072482292156441678, "name" => "ElixirConfJa2017",
   "photoUrls" => [], "tags" => []},
 headers: %{"access-control-allow-headers" => "Content-Type, api_key, Authorization",
   "access-control-allow-methods" => "GET, POST, DELETE, PUT",
   "access-control-allow-origin" => "*", "connection" => "close",
   "content-type" => "application/json",
   "date" => "Fri, 31 Mar 2017 14:47:18 GMT",
   "server" => "Jetty(9.2.9.v20150224)"}, method: :post, opts: [], query: [],
 status: 200, url: "http://petstore.swagger.io/v2/pet"}

Get an pet ID 9072482292156441678

Use elixir client

Get the pet by ID (definition)

Use elixir client

Get the pet by ID (code)

ID 9072482292156441678

SwaggerPetstore.Api.Pet.get_pet_by_id(9072482292156441678)

Use elixir client

/Users/niku/Downloads/elixir-client% mix run -e \
'IO.inspect SwaggerPetstore.Api.Pet.get_pet_by_id(9072482292156441678)'
%Tesla.Env{body: %{"id" => 9072482292156441678, "name" => "ElixirConfJa2017",
   "photoUrls" => [], "tags" => []},
 headers: %{"access-control-allow-headers" => "Content-Type, api_key, Authorization",
   "access-control-allow-methods" => "GET, POST, DELETE, PUT",
   "access-control-allow-origin" => "*", "connection" => "close",
   "content-type" => "application/json",
   "date" => "Fri, 31 Mar 2017 14:53:28 GMT",
   "server" => "Jetty(9.2.9.v20150224)"}, method: :get, opts: [], query: [],
 status: 200, url: "http://petstore.swagger.io/v2/pet/9072482292156441678"}

It seems work well.

Brand-new feature (not yet released)

View API Document with using h/1

iex(1)> h SwaggerPetstore.Api.Store.get_inventory

                              def get_inventory()

Returns pet inventories by status

Returns a map of status codes to quantities

Conclusion