# HTTP Server

## Overview

The HTTP server serves as the entry point for Diarkis. The application server connects to the HTTP server to obtain real-time connection endpoints and encryption keys.

Additionally, you can define custom endpoints.

## Setting Up the HTTP Server

To expose built-in commands to the client, you can set it up using the `diarkisexec` package.

* You can expose built-in commands by specifying modules with `diarkisexec.SetupDiarkis()`. By setting `ConfigPath` for each module, you can customize the configuration.
* You can expose custom commands using `diarkisexec.SetServerCommandHandler()`.
* You can set up a UDP server with `diarkisexec.SetupDiarkisHTTPServer()`. You can customize the server settings using a JSON file as an argument.

> :warning: The above functions must be executed before calling `diarkisexec.StartDiarkis()`.

For more details, please refer to the [API reference of diarkisexec](https://docs.diarkis.io/docs/server/current/diarkis/diarkisexec/index.html).

```go
package main

import (
	"github.com/Diarkis/diarkis/diarkisexec"

	"github.com/Diarkis/diarkis-server-template/cmds"
)

func main() {
	logConfigPath := "/configs/shared/log.json"
	meshConfigPath := "/configs/shared/mesh.json"

	diarkisexec.SetupDiarkis(logConfigPath, meshConfigPath, &diarkisexec.Modules{
		Dive:       &diarkisexec.Options{ConfigPath: "/configs/shared/dive.json", ExposeCommands: true},
		Field:      &diarkisexec.Options{ConfigPath: "/configs/shared/field.json", ExposeCommands: true},
		DM:         &diarkisexec.Options{ConfigPath: "/configs/shared/dm.json", ExposeCommands: true},
		MatchMaker: &diarkisexec.Options{ConfigPath: "/configs/shared/matching.json", ExposeCommands: true},
	})

	httpcmds.SetupHTTP()

	diarkisexec.SetupDiarkisHTTPServer("/configs/http/main.json")

	diarkisexec.StartDiarkis()
}
```

## Mesh Configuration

Specify the path to the JSON file in `meshConfigPath`. For more details, refer to [#mesh-setup](#mesh-setup "mention").

## HTTP Server Configuration

Configuration is done in JSON format.

<table><thead><tr><th width="230">Key</th><th width="119">Default</th><th></th></tr></thead><tbody><tr><td>address</td><td>"127.0.0.1"</td><td>The address for binding the UDP server</td></tr><tr><td>port</td><td>"7000"</td><td>The port for the UDP server to bind to. The UDP server will automatically search for an available port starting from the specified port.</td></tr><tr><td>useFixedPort</td><td>false</td><td>If set to true, the HTTP server will bind only to the specified port.</td></tr><tr><td>timeout</td><td>5</td><td>HTTP response timeout (seconds)</td></tr><tr><td>enableEncryption</td><td>true</td><td>If set to false, packet encryption and decryption will be disabled. Other servers need to be configured similarly.</td></tr></tbody></table>

For more details, please refer to the [API reference for http](https://docs.diarkis.io/docs/server/current/diarkis/server/http/index.html).

## **Creating Custom HTTP Endpoints**

Diarkis's HTTP server allows you to write custom endpoints.

```go
package httpcmds

import (
      "github.com/Diarkis/diarkis/server/http"
)

func Expose(rootpath string) {
      // :message is treated as a parameter and the value can be accessed from *http.Params

      http.Get("/hello/:message", handleHello)
}

func handleHello(res *http.Response, req *http.Request, params *http.Params, next func(error)) {
      message := params.GetAsString("message")
      res.Respond(message, http.Ok)
      // move on to other handlers
      next(nil)
}

```

### Using JSON in HTTP Endpoints

Diarkis's HTTP server automatically decodes the request body into `req.JSONBody` when the ContentType of the request is `application/json`. Note that an object must be described to store in the JSON Body.

```go
package httpcmds

import (
	"github.com/Diarkis/diarkis/server/http"
)

func Expose(rootpath string) {
	http.Post("/echo", handleEcho)
}

func handleEcho(res *http.Response, req *http.Request, params *http.Params, next func(error)) {
	if req.JSONBody == nil {
		err := errors.New("expect JSON body")
		res.Respond(err.Error(), http.Bad)
		next(err)
		return
	}

	message, ok := req.JSONBody["message"].(string)
	if !ok {
		err := errors.New("missing parameter message")
		res.Respond(err.Error(), http.Bad)
		next(err)
		return
	}

	enc, err := json.Marshal(map[string]any{"echo": message})
	if err != nil {
		res.Respond(err.Error(), http.Bad)
		next(err)
		return
	}

	res.SetHeader("Content-Type", "application/json")
	res.SendBytes(enc, http.Ok)
	// move on to other handlers
	next(nil)
}
```


---

# 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://help.diarkis.io/en/diarkis-server/http.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.
