# Service structs


Encore lets you define a type, called a service struct, to represent your running service. This lets you define an initialization function (similar to the `main` function in regular Go programs).

You can also define API endpoints as methods on the service struct type, enabling you to use [dependency injection](/docs/go/how-to/dependency-injection) for testing purposes.

It works by defining a struct type of your choice (typically called `Service`)
and declaring it with `//encore:service`.
Then, you can define a special function named `initService`
(or `initWhatever` if you named the type `Whatever`)
that gets called by Encore to initialize your service when it starts up.

It looks like this:
```go
//encore:service
type Service struct {
	// Add your dependencies here
}

func initService() (*Service, error) {
	// Write your service initialization code here.
}

//encore:api public
func (s *Service) MyAPI(ctx context.Context) error {
	// ...
}
```

<GitHubLink 
    href="https://github.com/encoredev/examples/tree/main/uptime" 
    desc="Event-driven example application using service structs." 
/>

## Calling APIs defined on service structs

When using a service struct like above, Encore will create a file named `encore.gen.go`
in your service directory. This file contains package-level functions for the APIs defined
as methods on the service struct. In the example above, you would see:

```go
// Code generated by encore. DO NOT EDIT.

package email

import "context"

// These functions are automatically generated and maintained by Encore
// to simplify calling them from other services, as they were implemented as methods.
// They are automatically updated by Encore whenever your API endpoints change.

func Send(ctx context.Context, p *SendParams) error {
	// The implementation is elided here, and generated at compile-time by Encore.
	return nil
}
```

These functions are generated in order to allow other services to keep calling your
APIs as package-level functions, in the same way as before: `email.Send(...)`.
This means other services do not need to care about whether you're using Dependency Injection
internally. You must always use these generated package-level functions for making API calls.

<Callout type="info">

Encore will automatically generate these files and keep them up to date
whenever your code changes. There is no need to manually invoke anything
to regenerate this code.

</Callout>

Encore adds all `encore.gen.go` files to your `.gitignore` since you typically
don't want to commit them to your repository; doing so ends up creating
a lot of unnecessary merge conflicts.

However, in some cases when running third-party linters in a CI/CD environment
it can be helpful to generate these wrappers to make the linter happy.
You can do that by invoking `encore gen wrappers`.

## Graceful Shutdown

When defining a service struct, Encore supports notifying
your service when it's time to gracefully shut down. This works
by having your service struct implement the method
`func (s *Service) Shutdown(force context.Context)`.

If that method exists, Encore will call it when it's time to begin
gracefully shutting down. Initially the shutdown is in "graceful mode",
which means that you have a few seconds to complete ongoing work.

The provided `force` context is canceled when the graceful shutdown window
is over, and it's time to forcefully shut down. How much time you have
from when `Shutdown` is called to when forceful shutdown begins depends on the
cloud provider and the underlying infrastructure. Typically it's in the range 5-30 seconds.

<Callout type="info">

Encore automatically handles graceful shutdown of all Encore-managed
functionality, such as HTTP servers, database connection pools,
Pub/Sub message receivers, distributed tracing recorders, and so on.

The graceful shutdown functionality is provided if you have additional,
non-Encore-related resources that need graceful shutdown.

</Callout>

Note that graceful shutdown in Encore is *cooperative*: Encore will wait indefinitely
for your `Shutdown` method to return. If your `Shutdown` method does not return promptly
after the `force` context is closed, the underlying infrastructure at your cloud provider
will typically force-kill your service, which can lead to lingering connections and other
such issues.

In summary, when your `Shutdown(force context.Context)` function is called:

- Immediately begin gracefully shutting down
- When the `force` context is canceled, you should forcefully shut down
  the resources that haven't yet completed their shutdown
- Wait until the shutdown is complete before returning from the `Shutdown` function
