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 calledHandler
: The suffix of the function name - it is alwaysHandler
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
1// all plugins must have their package name as `main`
2// each plugin is isolated at compile time
3package main
4
5import (
6 "encoding/json"
7)
8
9var (
10 // HTTPVars route variables for the current request
11 HTTPVars map[string]string
12 // URLQuery parses RawQuery and returns the corresponding values
13 URLQuery map[string][]string
14)
15
16// Response return structure of the get method
17type Response struct {
18 HTTPVars map[string]string `json:"http_vars"`
19 URLQuery map[string][]string `json:"url_query"`
20 MSG string `json:"msg"`
21}
22
23// GETHelloHandler plugin
24// function is invoked via [go language plugin](https://pkg.go.dev/plugin),
25// it is not possible to pass parameters, that's why there are global
26// variables to receive data from http protocol
27//
28// BUILD:
29// go build -o lib/hello.so -buildmode=plugin lib/src/hello.go
30func GETHelloHandler() (ret string) {
31 resp := Response{
32 HTTPVars: HTTPVars,
33 URLQuery: URLQuery,
34 MSG: "Hello plugin caller!",
35 }
36 respJSON, err := json.Marshal(resp)
37 if err != nil {
38 return
39 }
40 ret = string(respJSON)
41 return
42}
43
44// GETHelloHandler plugin
45// same function as GETHelloHandler, but this time we can return status code.
46func GETHelloWithStatusHandler() (ret string, code int) {
47 resp := Response{
48 HTTPVars: HTTPVars,
49 URLQuery: URLQuery,
50 MSG: "Hello plugin caller!",
51 }
52 respJSON, err := json.Marshal(resp)
53 if err != nil {
54 return
55 }
56 ret = string(respJSON)
57 code = http.StatusAccepted
58 return
59}
Request:
1GET /_PLUGIN/hello/Hello?abc=123 HTTP/1.1
Response:
1{
2 "http_vars": {
3 "file": "hello",
4 "func": "Hello"
5 },
6 "url_query": {
7 "abc": [
8 "123"
9 ]
10 },
11 "msg": "Hello plugin caller!"
12}