repository

package
v1.7.0 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2025 License: MIT Imports: 1 Imported by: 0

README

Repository

Overview

The Repository component provides a robust implementation of the Repository pattern for data access. It abstracts the details of data storage and retrieval, making it easier to switch between different data sources and to test your code.

Features

  • Generic Implementation: Works with any data type
  • CRUD Operations: Standard Create, Read, Update, Delete operations
  • Transaction Support: Support for transactions across multiple operations
  • Query Building: Fluent API for building queries
  • Pagination: Support for paginated results

Installation

go get github.com/abitofhelp/servicelib/repository

Quick Start

See the Basic Repository example for a complete, runnable example of how to use the repository component.

Configuration

See the Repository Factory example for a complete, runnable example of how to configure the repository component.

API Documentation

Core Types

The repository component provides several core types for implementing the Repository pattern.

Repository

The main interface that defines the Repository pattern.

type Repository[T any, ID any] interface {
    // Methods
}
BaseRepository

A base implementation of the Repository interface.

type BaseRepository[T any, ID any] struct {
    // Fields
}
Key Methods

The repository component provides several key methods for implementing the Repository pattern.

Create

Creates a new entity.

func (r *BaseRepository[T, ID]) Create(ctx context.Context, entity T) (T, error)
FindByID

Finds an entity by its ID.

func (r *BaseRepository[T, ID]) FindByID(ctx context.Context, id ID) (T, error)
Update

Updates an existing entity.

func (r *BaseRepository[T, ID]) Update(ctx context.Context, entity T) (T, error)
Delete

Deletes an entity.

func (r *BaseRepository[T, ID]) Delete(ctx context.Context, entity T) error

Examples

For complete, runnable examples, see the following directories in the EXAMPLES directory:

Best Practices

  1. Use Interfaces: Define repository interfaces for better testability
  2. Use Transactions: Use transactions for operations that need to be atomic
  3. Handle Errors: Properly handle repository errors
  4. Use Context: Pass context to repository methods for cancellation and timeouts
  5. Use Pagination: Use pagination for large result sets

Troubleshooting

Common Issues
Entity Not Found

If an entity is not found, check that you're using the correct ID and that the entity exists in the data source.

Transaction Failures

If transactions are failing, check that your data source supports transactions and that you're using them correctly.

  • DB - Database access for repositories
  • Errors - Error handling for repositories
  • DI - Dependency injection for repositories

Contributing

Contributions to this component are welcome! Please see the Contributing Guide for more information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Overview

Package repository provides generic repository interfaces for data persistence operations.

This package implements the Repository pattern, which abstracts the data access layer and provides a consistent interface for working with different data sources. It aligns with the Hexagonal Architecture (Ports and Adapters) pattern by defining ports (interfaces) that can be implemented by various adapters.

The package is designed to be used with any entity type through Go generics, allowing for type-safe repository operations without code duplication.

Key components:

  • Repository: A generic interface for CRUD operations on entities
  • RepositoryFactory: An interface for creating repositories

The Repository pattern provides several benefits:

  • Decouples business logic from data access implementation
  • Simplifies testing through mocking
  • Enables switching between different data sources with minimal code changes
  • Centralizes data access logic

Example usage:

// Define an entity
type User struct {
    ID   string
    Name string
    Age  int
}

// Use the repository interface
func ProcessUser(ctx context.Context, repo repository.Repository[User], userID string) error {
    // Get user from repository
    user, err := repo.GetByID(ctx, userID)
    if err != nil {
        return err
    }

    // Process user...
    user.Age++

    // Save changes
    return repo.Save(ctx, user)
}

// Implementation would be provided by an adapter in the infrastructure layer
type MongoUserRepository struct {
    // MongoDB client and collection
}

func (r *MongoUserRepository) GetByID(ctx context.Context, id string) (User, error) {
    // Implementation using MongoDB
}

func (r *MongoUserRepository) GetAll(ctx context.Context) ([]User, error) {
    // Implementation using MongoDB
}

func (r *MongoUserRepository) Save(ctx context.Context, user User) error {
    // Implementation using MongoDB
}

Package repository provides generic repository interfaces that can be used across different applications.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Repository

type Repository[T any] interface {
	// GetByID retrieves an entity by its ID.
	// It returns the entity if found, or an error if the entity doesn't exist
	// or if there was a problem accessing the data store.
	//
	// The context parameter can be used to control cancellation and timeouts.
	GetByID(ctx context.Context, id string) (T, error)

	// GetAll retrieves all entities of type T.
	// It returns a slice of entities, which may be empty if no entities exist,
	// or an error if there was a problem accessing the data store.
	//
	// The context parameter can be used to control cancellation and timeouts.
	GetAll(ctx context.Context) ([]T, error)

	// Save persists an entity to the data store.
	// For new entities, this typically creates a new record.
	// For existing entities, this updates the existing record.
	//
	// It returns an error if there was a problem saving the entity.
	// The context parameter can be used to control cancellation and timeouts.
	Save(ctx context.Context, entity T) error
}

Repository is a generic repository interface for entity persistence operations. This interface represents a port in the Hexagonal Architecture pattern. It's defined in the domain layer but implemented in the infrastructure layer.

The generic type parameter T represents the entity type that the repository manages. This allows for type-safe repository operations without code duplication.

type RepositoryFactory

type RepositoryFactory interface {
	// GetRepository returns a repository instance.
	// The returned repository should be cast to the appropriate type
	// by the caller, typically Repository[T] for some entity type T.
	//
	// Example:
	//   factory := NewMyRepositoryFactory()
	//   repo, ok := factory.GetRepository().(Repository[User])
	//   if !ok {
	//       return errors.New("invalid repository type")
	//   }
	GetRepository() any
}

RepositoryFactory is an interface for creating repositories. This interface follows the Factory pattern and is used to abstract the creation of repository instances, allowing for dependency injection and easier testing.

Directories

Path Synopsis
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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