Cookies management by TermsFeed Cookie Consent

Domain object and repository

7/21

The next step is to define the domain object and the repository. In the website package, create two new files: website.go and repository.go, and copy their contents that you can see on this page into them.

A Website is a struct that contains simple data about the website - its name, URL, position in the ranking, and numeric identifier. Objects of this type will be stored and retrieved from the database.

The Repository is our interface for reading and writing Website data from and to the database. Note that the methods of this interface do not depend on PostgreSQL at all. This is one of the main goals of the Repository pattern - hiding database implementation details and providing a simple API to interact with any database.

After the changes, the project structure should look like this:

postgresql-intro
├── app
├── cmd
├── go.mod
└── website
    ├── repository.go
    └── website.go

We will go through what each method does in the next step, but by now, you may be wondering why every method signature has ctx context.Context in the parameter list.

In short, the context.Context is an object that is a common Go concept used by web applications to send request-scoped values, cancellation, and deadline signals to deeper layers of services. Let’s assume that in your application you want to wait a maximum of 5 seconds for a response from the database to prevent the application to wait idly if there are any connection problems. To ensure this, you can create a new Context with a defined timeout of 5 seconds. The functions of a client or driver operating directly on the database, while receiving such a Context, respect it, which means that after the timeout of 5 seconds is exceeded, the connection is interrupted, and the application can continue to run.

In our demo application, we will also use this feature and set a timeout for all operations using the context.Context.

website/website.go

package website

type Website struct {
    ID   int64
    Name string
    URL  string
    Rank int64
}

website/repository.go

package website

import "context"

type Repository interface {
    Migrate(ctx context.Context) error
    Create(ctx context.Context, website Website) (*Website, error)
    All(ctx context.Context) ([]Website, error)
    GetByName(ctx context.Context, name string) (*Website, error)
    Update(ctx context.Context, id int64, updated Website) (*Website, error)
    Delete(ctx context.Context, id int64) error
}
7/21