liveBook · Manning

Contract

As explained in Shipping Go: Develop, deliver, discuss, design, and go again

A defined interface through which software components or users interact with an application or service.

An API is the exposed definition that lets other code use a service without depending on how it works inside. Think of an electrical outlet: a lamp needs a compatible plug, not knowledge of the house wiring. In Go, an interface can provide this boundary by naming the methods a service must offer. section 3.2 section 6.1

One call, two implementations

A Greeter interface declares Greet() string. Both an English greeter and a Spanish greeter satisfy it, so printGreeting can accept either without changing its calling logic. The caller relies on the method contract rather than a particular struct. section 6.2

Keep that contract focused on what callers need. A Translator interface, for example, declares Translate(word string, language string) string. A handler can receive a service satisfying that interface as a dependency. This makes it possible to isolate tests with stubs, mocks, or fakes, and to change an implementation without rewriting the handler. Once callers depend on an exposed interface, however, changing it becomes harder. section 6.0 section 6.8 section 3.2

Listing 8.10 main.go
func main() {
 
    cfg := config.LoadConfiguration()
 
...
 
    var translationService rest.Translator                             #1
    translationService = translation.NewStaticService()                #2
    if cfg.LegacyEndpoint != "" {
        log.Printf("creating external translation 
        client: %s", cfg.LegacyEndpoint)
        client := translation.NewHelloClient(cfg.LegacyEndpoint)       #3
        translationService = translation.NewRemoteService(client)      #4
    }
 
    translateHandler := rest.NewTranslateHandler(translationService)   #5
 
}

The configuration example selects a static translation service by default or a remote one when a client URL is set, then passes the selected service to the same handler. section 8.3.2

Test the boundary through inputs and outputs rather than implementation details. That feedback helps shape an API callers can use while leaving room to replace the code behind it. section 3.2 section 6.2

How Shipping Go: Develop, deliver, discuss, design, and go again covers it

How deep it goes
Defines Go interfaces through method signatures and works through interchangeable services, testing, and configuration-based selection.
Examples
Uses a Go Greeter interface, a Translator contract, and a configured choice between static and remote translation services.
What it assumes
Assumes familiarity with Go functions and structs while explaining interfaces through method definitions and a small example.
What you can do after
Build it from scratch by declaring a Go method contract and supplying interchangeable service implementations to a caller.
How it connects
Connects APIs to dependency inversion, dependency injection, black-box testing, and test doubles.

Also explained in

Compare how 44 books explain contract →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Shipping Go: Develop, deliver, discuss, design, and go again. The section links point to the parts of the book it draws on.