# OpenAPI Cheat Sheet

## Location To Tesla API

| OpenAPI `in` | Tesla API |
| --- | --- |
| `path` | `Tesla.OpenAPI.PathTemplate`, `Tesla.OpenAPI.PathParam`, `Tesla.OpenAPI.PathParams`, `{Tesla.Middleware.PathParams, mode: :modern}` |
| `query` | `Tesla.OpenAPI.QueryParam`, `Tesla.OpenAPI.QueryParams`, `{Tesla.Middleware.Query, mode: :modern}` |
| `querystring` | `Tesla.OpenAPI.QueryString` as the request `:query` |
| `header` | `Tesla.OpenAPI.HeaderParam`, `Tesla.OpenAPI.HeaderParams.to_headers/2` |
| `cookie` | `Tesla.OpenAPI.CookieParam`, `Tesla.OpenAPI.CookieParams.to_headers/2` |

## Client Stack

```elixir
client =
  Tesla.client([
    {Tesla.Middleware.BaseUrl, "https://api.example.com"},
    {Tesla.Middleware.PathParams, mode: :modern},
    {Tesla.Middleware.Query, mode: :modern},
    Tesla.Middleware.JSON
  ])
```

## Response Wrapper

```elixir
defmodule MyApi.Response do
  use Tesla.OpenAPI.Response
end
```

## Generated Operation Metadata

```elixir
defmodule MyApi.Operation.GetItem.Path do
  alias Tesla.OpenAPI.{PathParam, PathParams, PathTemplate}

  @path_template PathTemplate.new!("/items/{id}{coords}")

  @path_params PathParams.new!([
                 PathParam.new!("id"),
                 PathParam.new!("coords", style: :matrix, explode: true)
               ])

  def path_template, do: @path_template
  def path_params, do: @path_params
end

defmodule MyApi.Operation.GetItem.Query do
  alias Tesla.OpenAPI.{QueryParam, QueryParams}

  @query_params QueryParams.new!([
                  QueryParam.new!("color", style: :pipe_delimited),
                  QueryParam.new!("filter", style: :deep_object)
                ])

  def query_params, do: @query_params
end

defmodule MyApi.Operation.GetItem do
  alias MyApi.Operation.GetItem.{Path, Query}
  alias Tesla.OpenAPI
  alias Tesla.OpenAPI.{PathParams, PathTemplate, QueryParams}

  @operation_path Path.path_template().path

  @private OpenAPI.merge_private([
             PathTemplate.put_private(Path.path_template()),
             PathParams.put_private(Path.path_params()),
             QueryParams.put_private(Query.query_params())
           ])
end
```

## Request Values

```elixir
defmodule MyApi.Operation.GetItem do
  alias MyApi.Operation.GetItem.{Path, Query}
  alias Tesla.OpenAPI
  alias Tesla.OpenAPI.{PathParams, PathTemplate, QueryParams}

  @operation_path Path.path_template().path

  @private OpenAPI.merge_private([
             PathTemplate.put_private(Path.path_template()),
             PathParams.put_private(Path.path_params()),
             QueryParams.put_private(Query.query_params())
           ])

  def request(client) do
    Tesla.get(client, @operation_path,
      query: %{
        "color" => ["blue", "black"],
        "filter" => [role: "admin"],
        "debug" => true
      },
      opts: [
        path_params: %{
          "id" => 42,
          "coords" => ["blue", "black"]
        }
      ],
      private: @private
    )
  end
end
```

## Headers And Cookies

```elixir
defmodule MyApi.Operation.GetItem.Header do
  alias Tesla.OpenAPI.{HeaderParam, HeaderParams}

  @header_params HeaderParams.new!([
                   HeaderParam.new!("X-Request-ID")
                 ])

  def header_params, do: @header_params
end

defmodule MyApi.Operation.GetItem.Cookie do
  alias Tesla.OpenAPI.{CookieParam, CookieParams}

  @cookie_params CookieParams.new!([
                   CookieParam.new!("session_id")
                 ])

  def cookie_params, do: @cookie_params
end

defmodule MyApi.Operation.GetItem do
  alias MyApi.Operation.GetItem.{Cookie, Header}
  alias Tesla.OpenAPI.{CookieParams, HeaderParams}

  @header_params Header.header_params()
  @cookie_params Cookie.cookie_params()

  def headers do
    HeaderParams.to_headers(@header_params, %{"X-Request-ID" => "req-123"}) ++
      CookieParams.to_headers(@cookie_params, %{"session_id" => "abc123"})
  end
end
```

## Query String Parameter

```elixir
Tesla.get(client, "/search",
  query: Tesla.OpenAPI.QueryString.form!(q: "blue", page: 2)
)
```

## Style Names

OpenAPI JSON names become Elixir atoms:

| OpenAPI | Tesla |
| --- | --- |
| `pipeDelimited` | `:pipe_delimited` |
| `spaceDelimited` | `:space_delimited` |
| `deepObject` | `:deep_object` |
| `allowReserved` | `:allow_reserved` |
