# Server

## New

This method creates a new [Server](/api/server.md) instance. You can pass [ServerOpt](/api/serveropt.md) functions to provide optional settings when creating a new instance.

{% tabs %}
{% tab title="Signature" %}

```go
func New(...ServerOpt) Server
```

{% endtab %}

{% tab title="Example" %}

```go
s := pps.New()
```

{% endtab %}
{% endtabs %}

## Changing Server settings

When you already have a [Server](/api/server.md) instance which settings weren't changed using [ServerOpt](/api/serveropt.md) functions, you can use the following methods on the [Server ](/api/server.md)instance to subsequently override them.

### SetAddr

The `SetAddr()` method overrides the listening address on the provided [Server](/api/server.md) instance.

{% tabs %}
{% tab title="Signature" %}

```go
func (*Server) SetAddr(string)
```

{% endtab %}

{% tab title="Example" %}

```go
// Create a Server with defaults
s := pps.New()

// Override the listening address
s.SetAddr("127.0.0.1")
```

{% endtab %}
{% endtabs %}

### SetPort

The `SetPort()` method will override the listening port on the provided [Server ](/api/server.md)instance.

{% tabs %}
{% tab title="Siganture" %}

```go
func (*Server) SetPort(string)
```

{% endtab %}

{% tab title="Example" %}

```go
// Create a Server with defaults
s := pps.New()

// Override the listening port
s.SetPort("1234")
```

{% endtab %}
{% endtabs %}

## Starting the Server

Starting a policy server with **pps** is as easy as just executing one method on the [Server ](/api/server.md)instance. It is important though, that you provide it with a `Context` and a custom type that satisfies the pps [Handler](/api/handler.md) interface.

### Run

Once you have a Server instance ready, all you need is to execute the Run method on it, to start a TCP policy server that is listening on the address/port combination, that you configured in it (Default: `0.0.0.0:10005`). The `Run()` method returns an error in case it wasn't able to start.

{% tabs %}
{% tab title="Signature" %}

```go
func (*Server) Run(context.Context, Handler) error
```

{% endtab %}

{% tab title="Example" %}

```go
// Create your Server instance with defaults
s := pps.New()

// Create a Context of your choice
ctx := context.Background()

// Create an instance of the type that satisfies the Handler interface
h := Hi{}

// Start the server on 0.0.0.0:10005
if err := s.Run(ctx, h); err != nil {
	panic(err)
}
```

{% endtab %}
{% endtabs %}

### RunWithListener

If you prefer to run your policy service on a different type of listener (i. e. UNIX socket), you can do so by making use of the `RunWithListener()` method. It works similar to the `Run()` method, except that you'll have to provide a `net.Listener` as additional argument.

{% tabs %}
{% tab title="Signature" %}

```go
func (*Server) RunWithListener(context.Context, Handler, net.Listener) error
```

{% endtab %}

{% tab title="Example" %}

```go
// Create your Server instance
s := pps.New()

// We'll create a Context with cancel... just because we can
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

// Let's create a UNIX socket listener on /tmp/pps_test_server
l, err := net.Listen("unix", "/tmp/pps_test_server")
if err != nil {
	t.Errorf("failed to create new UNIX socket listener: %s", err)
}

// Again, we require the Handler interface type
h := Hi{}

// ...to finally start our server on /tmp/pps_test_server
if err := s.RunWithListener(ctx, h, l); err != nil {
	t.Errorf("could not run server: %s", err)
}
```

{% endtab %}
{% endtabs %}

### Contexts

**pps** allows you to influence specific behaviour of your policy server using vaules in the `Context` you provide to the `Run()` or `RunWithListener()` methods. The context keys that you can set are provided via the `CtxKey` type of the pps package.

Currently **pps** supports the following keys:

| Property | Type   | Description                                                                                                                                                                                                                                                                                                                                                    | Default |
| -------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| CtxNoLog | `bool` | <p>When you run a server, pps by default uses <br>Go's <code>log</code> package to log some errors to <br><code>STDERR</code>. If you prefer to keep the execution <br>silent without any logging, you can set the </p><p><code>CtxNoLog</code> context value to <code>true</code> before you</p><p>hand your context to the <code>Run\*()</code> methods.</p> | `nil`   |

{% tabs %}
{% tab title="Example" %}

```go
// Create your Server instance
s := pps.New()

// And your context with a value
ctx := context.WithValue(context.Background(), pps.CtxNoLog, true)

// Again, we require the Handler interface type
h := Hi{}

// We can now start our server with logging disable
if err := s.Run(ctx, h); err != nil {
		t.Errorf("could not run server: %s", err)
}
```

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://pps-docs.pebcak.de/api/server.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
