# 3 ways to configure your Ruby API wrappers

DevFeed: [3 ways to configure your Ruby API wrappers](<https://devfeed.tech/articles/3-ways-to-configure-your-ruby-api-wrappers-26263.md>)

Original publisher: [Read original article](<https://www.justinweiss.com/articles/3-ways-to-configure-your-ruby-api-wrappers/>)

Author: Justin Weiss

Published: 2015-06-01T21:01:05Z

Content type: tutorial

Language: en

Sources: [Justin Weiss](<https://devfeed.tech/sources/justin-weiss.md>)

Topics: [Ruby](<https://devfeed.tech/topics/ruby.md>), [API](<https://devfeed.tech/topics/api.md>), [configuration](<https://devfeed.tech/topics/configuration.md>), [Environment Variables](<https://devfeed.tech/topics/environment-variables.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [configuration](<https://devfeed.tech/tags/configuration.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [ruby](<https://devfeed.tech/tags/ruby.md>)

## AI overview

This tutorial compares three ways to configure Ruby API wrappers: global configuration, per-instance configuration, and a default-instance pattern that combines convenient access with configurable instances. It discusses the tradeoffs of each approach, including shared mutable state and repeated setup.

## Source excerpt

When you use Ruby to wrap an API, you have to have a way to configure it. Maybe the wrapper needs a username and secret key, or maybe just a host. There are a few different ways to handle this. So which one should you choose? The easy, global way You might want your service to act like it's always around. No matter where you are in your app, you'd have it ready to use. Otherwise, you'll spend three lines of configuring it for every line of using it! You could make the configuration global, using constants or class attributes: config/initializers/product_api.rbProductApi.root = "https://staging-host.example.com/" ProductApi.user = "justin" ProductApi.secret = "mysecret123" app/controllers/products_controller.rbdef show @product = ProductApi.find(params[:id]) end Lots of gems use this pattern. It's pretty easy to write, and really easy to use. But it has some big problems: You can only have one ProductApi. If you want to use the Product API as two different users, or hit different servers from a single app, you're out of luck. ProductApi has global data that's easy to accidentally change. If a thread or a part of your app changed ProductApi.user, everything else using ProductApi would break. And those are painful bugs to track down. So, class variables have some problems. What if you configured instances of your Product API class, instead? What would it look like with #initialize? If you used instances, you'd create and configure your API wrapper when you need it: app/controllers/products_controller.rbdef show product_api = ProductApi.new( root: "https://staging-host.example.com/", user: "justin", secret: "mysecret123") @product = product_api.find(params[:id]) end Now, you can pass different details to your API whenever you use it. No other methods or threads are using your instance, so you don't have to worry about it changing without you knowing it. This seems better. But it's still not as easy as it should be. Because you have to configure your API every time you u