View Source OpenApiTypesense

Restful client for Typesense with adherence to Open API spec 3 (formerly Swagger)

Dependabot Hex.pm Hexdocs.pm Hex.pm Typesense badge Coverage Status CI Status

Installation

If available in Hex, the package can be installed by adding open_api_typesense to your list of dependencies in mix.exs:

def deps do
  [
    {:open_api_typesense, "~> 0.5"}

    # Or from GitHub repository, if you want the latest greatest from main branch
    {:open_api_typesense, git: "https://github.com/jaeyson/open_api_typesense.git"}
  ]
end

Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/open_api_typesense.

Getting started

Adding credentials

Spin up local Typesense instance

docker compose up -d

# check if "peer refreshed" in logs
docker container logs --follow --tail 50 typesense
# e.g. config/runtime.exs
if config_env() == :prod do # if you'll use this in prod environment
  config :open_api_typesense,
    api_key: "xyz",
    host: "localhost",
    port: 8108,
    scheme: "http"
  ...

Note: The options key can be used to pass additional configuration options such as custom Finch instance or receive timeout settings. You can add any options supported by Req here. For more details check Req documentation.

Note: If you use this for adding tests in your app, you might want to add this in config/test.exs:

For Cloud hosted, you can generate and obtain the credentials from cluster instance admin interface:

config :open_api_typesense,
  api_key: "credential", # Admin API key
  host: "111222333aaabbbcc-9.x9.typesense.net", # Nodes
  port: 443,
  scheme: "https"

Using a another HTTP client

In order to use another HTTP client, OpenApiTypesense has a callback function (Behaviours) called request that contains 2 args:

  1. conn: your connection map
  2. params: payload, header, and client-related stuffs.

conn and params

you can change the name conn and/or params however you want, since it's just a variable.

Here's a custom client example (HTTPoison) in order to match the usage:

defmodule MyApp.CustomClient do
  def request(conn, params) do
    url = %URI{
      scheme: conn.scheme,
      host: conn.host,
      port: conn.port,
      path: params.url,
      query: URI.encode_query(params[:query] || %{})
    }
    |> URI.to_string()

    request = %HTTPoison.Request{method: params.method, url: url}

    request =
      if params[:request] do
        [{content_type, _schema}] = params.request
        
        headers = [
          {"X-TYPESENSE-API-KEY", conn.api_key}
          {"Content-Type", content_type}
        ]

        %{request | headers: headers}
      else
        request
      end

    request =
      if params[:body] do
        %{request | body: Jason.encode!(params.body)}
      else
        request
      end

    HTTPoison.request!(request)
  end
end

Then add your client in your config file:

config :open_api_typesense,
  api_key: "credential", # Admin API key
  host: "111222333aaabbbcc-9.x9.typesense.net", # Nodes
  port: 443,
  scheme: "https",
  client: MyApp.CustomClient # <- add this

And here's a reference taken from one of functions from Collections, as you may want to match the params:

def create_collection(%Connection{} = conn, body, opts) when is_struct(conn) do
  client = opts[:client] || @default_client
  query = Keyword.take(opts, [:src_name])

  client.request(conn, %{
    args: [body: body],
    call: {OpenApiTypesense.Collections, :create_collection},
    url: "/collections",
    body: body,
    method: :post,
    query: query,
    request: [{"application/json", {OpenApiTypesense.CollectionSchema, :t}}],
    response: [
      {201, {OpenApiTypesense.CollectionResponse, :t}},
      {400, {OpenApiTypesense.ApiResponse, :t}},
      {409, {OpenApiTypesense.ApiResponse, :t}}
    ],
    opts: opts
  })
end

Check the examples on some HTTP client implementations.