# Endpoint Plugin

With prestd's http plugin system it is possible to create new endpoints in the "private" URI,

The plugin endpoint has the following default: `/_PLUGIN/{file}/{func}`

### Naming patterns

The plugin endpoint (`/_PLUGIN/{file}/{func}`) receives two parameters:

* **File name:** The name of the file without the extension (`{file}`)
* **Function name:** The name of the function (`{func}`)

#### File name

The file name will be used on the endpoint to identify which library will be loaded when it **receives the first access**.

> After the **first access the library will not be loaded again**, it will only be executed, i.e., if the file (`.so`) is changed after the first execution it will have no effect because it has already been loaded.

#### Function name

When talking about a compiled *library* we have no way of identifying its functions. Given this characteristic we have defined some name and behavior patterns to develop *libraries* for ***prestd***.

**function name:** `{HTTP Method}{Function Name}Handler`

* `{HTTP Method}`: The HTTP method that the function will be called for (in upper case letters)
* `{Function Name}`: The name of the function that will be called
* `Handler`: The suffix of the function name - it is always `Handler`

> `fmt.Sprintf("%s%sHandler", r.Method, funcName)`

### Example

* **Source code name:** `./lib/src/hello.go`
* **Library file name:** `./lib/hello.so`
* **Function name:** `GETHelloHandler`
* **Endpoint:** `/_PLUGIN/hello/Hello`
* **Verb HTTP:** `GET`

```go
// all plugins must have their package name as `main`
// each plugin is isolated at compile time
package main

import (
 "encoding/json"
)

var (
 // HTTPVars route variables for the current request
 HTTPVars map[string]string
 // URLQuery parses RawQuery and returns the corresponding values
 URLQuery map[string][]string
)

// Response return structure of the get method
type Response struct {
 HTTPVars map[string]string   `json:"http_vars"`
 URLQuery map[string][]string `json:"url_query"`
 MSG      string              `json:"msg"`
}

// GETHelloHandler plugin
// function is invoked via [go language plugin](https://pkg.go.dev/plugin),
// it is not possible to pass parameters, that's why there are global
// variables to receive data from http protocol
//
// BUILD:
// go build -o lib/hello.so -buildmode=plugin lib/src/hello.go
func GETHelloHandler() (ret string) {
 resp := Response{
  HTTPVars: HTTPVars,
  URLQuery: URLQuery,
  MSG:      "Hello plugin caller!",
 }
 respJSON, err := json.Marshal(resp)
 if err != nil {
  return
 }
 ret = string(respJSON)
 return
}

// GETHelloHandler plugin
// same function as GETHelloHandler, but this time we can return status code.
func GETHelloWithStatusHandler() (ret string, code int) {
	resp := Response{
		HTTPVars: HTTPVars,
		URLQuery: URLQuery,
		MSG:      "Hello plugin caller!",
	}
	respJSON, err := json.Marshal(resp)
	if err != nil {
		return
	}
	ret = string(respJSON)
	code = http.StatusAccepted
	return
}
```

**Request:**

```http
GET /_PLUGIN/hello/Hello?abc=123 HTTP/1.1
```

**Response:**

```json
{
  "http_vars": {
    "file": "hello",
    "func": "Hello"
  },
  "url_query": {
    "abc": [
      "123"
    ]
  },
  "msg": "Hello plugin caller!"
}
```


---

# 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://docs.prestd.com/plugins/endpoint-plugin.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.
