adapters

module
v0.0.0-...-7268f2b Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2025 License: MIT

README ΒΆ

Adapters

A collection of reusable adapters for external services such as encryption, mail, and storage. The goal is to provide simple, consistent interfaces that allow applications to interact with external systems without tight coupling to specific implementations.

Keep in mind that this is a work in progress, it is already being used in production, but is not yet feature complete. It takes a lot to build a good adapter, and is a continuous effort to make the adapters better and easier to use.

I was done with initializing specific services like s3 in my code which didn't make it easy to swap out services. But also testing was a huge pain and my goal is to solve this by providing mocks for each adapter.

The goal is multiple adapters that can standalone or be used in an adapter pkg. The imports should be modular, however for now it's all one package.

✨ Features

  • Common interfaces for external services (mail, storage, encryption).
  • Pluggable implementations (swap SMTP for a mock, or local storage for S3).
  • Easy to test β€” use provided mocks to assert interactions in unit tests.
  • Written in idiomatic Go, with simplicity and clarity in mind. (not entirely true, it uses globals which is looked down upon in Go, but I like it. I maybe provide better interfaces to use in something like a DI container like https://github.com/samber/do)

πŸ“¦ Installation

go get github.com/gonstruct/adapters

πŸš€ Usage

Mail

For global use, you can set up a default mailer:

mail.Register(smtp.Adapter{
    ... // SMTP configuration
})

Then you can use it somewhere in your application without worrying about the implementation details:

if err := mail.Send(ctx, "to@example.com", mail.WithMailable(YourMailable{})); err != nil {
    log.Fatal(err)
}

If you prefer to not use it globally, you can just use the adapter directly:

adapter := smtp.Adapter{
    ... // SMTP configuration
}

if err := adapter.Send(context.Background(), mail.Options{}); err != nil {
    log.Fatal(err)
}
Encryption
encryption.Register(aes_256_gcm.Adapter{
    Keys: func() [][]byte {
        return [][]byte{
            []byte("your-32-byte-long-key-here12345678"), // Example key
        }
    },
})

cipher, _ := encryption.Encrypt("hello")
plain, _ := encryption.Decrypt(cipher)
Storage
storage.Register(s3.Adapter{
    ... // S3 configuration
})

object, _ := storage.Upload(context.Background(), file, 
    storage.WithFileName("example.txt"),
    storage.WithPath("uploads/"),
)

πŸ§ͺ Testing

Each adapter includes a mock implementation for unit tests:

mock := mailers.Fake()
mock.AssertSentTo(t, &mail.Mailable{}, "to@example.com")

πŸ› οΈ Roadmap / Todo

  • Add encryption example
  • Add mail example
  • Add storage example
  • Add mail tests
  • Add storage tests
  • Add storage adapter for local file system
  • Make modular (only import encryption + only import the encryption adapter you need)

🀝 Contributing

Contributions are welcome! If you’d like to add a new adapter or improve an existing one, feel free to open an issue or submit a PR.

πŸ“„ License

MIT License. See LICENSE for details.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL