Functional endpoints support three specially named arguments to allow finer control over the marshaling to and unmarhsaling from the underlying HTTP protocol.
httpRequestBody receives the unmarshaled request body (JSON or URL encoded)httpResponseBody is marshaled as the response (JSON)httpStatusCode of type int sets the response’s status codeThese arguments are often required when implementing a RESTful API.
httpRequestBodyBy default, the body of a request to a functional endpoint is a JSON object that contains a named field for each of the function’s arguments. Consider the following RESTful functional endpoint Create:
functions:
- signature: Create(p Person) (id int)
description: Store a person in the directory and return its assigned ID.
path: /persons
method: POST
As written, it expects the following request. Notice how the payload in the request body in nested under the argument name p:
POST /persons HTTP/1.1
Content-Type: application/json
{
"p": {
"first": "Harry",
"last": "Potter",
"muggle": false
}
}
In this case it may be desirable to read the entire request directly into the object and avoid the extra nesting under the argument name p. This can be achieved by naming the input argument httpRequestBody.
functions:
- signature: Create(httpRequestBody Person) (id int)
description: Store a person in the directory and return its assigned ID.
path: /persons
method: POST
The endpoint will now expect the following payload in the request body:
POST /persons HTTP/1.1
Content-Type: application/json
{
"first": "Harry",
"last": "Potter",
"muggle": false
}
Because the argument httpRequestBody takes over the entire request body, no additional arguments may be posted in the request body. Any other input arguments are unmarshaled from either the path or the query of the request. This limits their size and is best saved for simple types.
httpResponseBodyhttpResponseBody operates the same way but for output arguments.
functions:
- signature: Load(id int) (httpResponseBody Person)
description: Load a person from the directory.
path: /person/{id}
method: GET
Produces the response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"first": "Harry",
"last": "Potter",
"muggle": false
}
Because the argument httpResponseBody takes over the entire response body, no additional arguments may be returned, except for httpStatusCode.
httpStatusCodehttpStatusCode controls the HTTP status code returned by the function. For example, we might want the Create method discussed earlier to return HTTP status 201 Created instead of the default 200 OK.
functions:
- signature: Create(httpRequestBody Person) (id int, httpStatusCode int)
description: Store a person in the directory and return its assigned ID.
path: /persons
method: POST
The implementation may look similar to the following:
func (svc *Service) Create(ctx context.Context, httpRequestBody Person) (id int, httpStatusCode int, err error) {
person := httpRequestBody
id, err := svc.database.createPerson(ctx, person)
if err != nil {
return http.StatusInternalServerError, errors.Trace(err)
}
return id, http.StatusCreated, nil
}