Go Pass Database to Service Layer Using Interface

Created At: 2023-05-10 07:40:57 Updated At: 2023-05-10 19:18:27

Here will see how to pass a database to a service layer. Service layer will have interface. Look at our main function

func Run() error {
	fmt.Println("Application start up")
	database, err := db.NewDatabase()
	if err != nil {
		fmt.Println("Error creating database")
	}

	if err := database.MigrateDB(); err != nil {
		fmt.Println("failed to migrate database")
	}
	cmtService := comment.NewService(database)

	...................................................................................
        ...................................................................................
	fmt.Println("successfully connected to database")
	return nil
}
func main() {
	fmt.Println("Go rest api")
	if err := Run(); err != nil {
		fmt.Println("returned error")
	}
}

In the main function, we create a database object by calling the NewDatabase() function. This function returns a pointer to a Database struct which contains a pointer to a sqlx.DB object. This sqlx.DB object is the connection pool to the database.

Look at our Database struct

type Database struct {
	//here DB is abstract of database and maintain a connection pool
	Client *sqlx.DB
}

Then we pass this Database object as an argument to the NewService() function which returns a pointer to a Service struct. In this way, we inject the database object into the service layer, making it available for use by the service layer.

Look at our NewService() constructor 

type Store interface {
	//repository layer should implement this
	GetComment(context.Context, string) (Comment, error)
	PostComment(context.Context, Comment) (Comment, error)
	DeleteComment(context.Context, string) error
	UpdateComment(context.Context, string, Comment) (Comment, error)
}

type Service struct {
	Store Store
}


func NewService(store Store) *Service {
	return &Service{
		Store: store,
	}
}

When we call a function in the service layer, it can then use the Store interface to communicate with the database. The Store interface defines the methods that the repository layer should implement to interact with the database. The Service struct then uses these methods to perform various CRUD operations on the database.

So in summary, the database object is created in the main function and passed to the service layer through the NewService() function. The service layer then uses the Store interface to interact with the database through the repository layer.

Another summary

In our example, the Store interface is defined to be implemented by the Database struct. The Database struct has a field named db of type *sql.DB.

When we call NewService, we pass a Database object which implements the Store interface. Since Database has a db field of type *sql.DB, which satisfies the Store interface, we can pass the Database object to NewService.

So when NewService is called with a Database object, it can access the db field of the Database object using the Store interface. This is possible because the Database struct implements the Store interface, and the db field of the Database struct is of type *sql.DB, which is what the Service methods expect to receive.

Comment

Add Reviews