Best Practices for Library Design: Managing State and Authentication Flow

Hello,

I’m new to the Elixir world, and I’m creating an implementation of the Apache Iceberg library. The expectation is to interact with the Data Catalog responsible for the metadata and, in the future, I will create bindings with the Iceberg Rust implementation to deal with data manipulation.

My question is about how to build a good public API to interact with. My current problem is about the authentication flow and how to manage passing the current state into the next iteration.

For example, I have the credentials, and I’m using Req to create the HTTP client. I will have a step that uses the credentials and retrieves the token that may expire, and I will use this token in future requests.

The easiest way is to pass and return the catalog in every action, but I have mixed feelings about the developer experience. Is this an okay solution, or would it be better to use something else to handle the state that needs to be shared between interactions?

catalog = ExIceberg.Catalog.new(%{
  uri: "http://localhost:8081",
  warehouse: "raw",
  credential: "admin:admin"
})

# Will return ok or error, the latest state of the catalog, and the information about the namespace creation
{:ok, catalog, _namespace_info} = ExIceberg.Catalog.create_namespace(catalog, "test", %{"key" => "value"})

# Will return ok or error, the latest state of the catalog, and the list of namespaces
{:ok, catalog, _namespace_list} = ExIceberg.Catalog.list_namespace(catalog)
2 Likes