controller_api
controller_api exposes MQTT topics over HTTP at /api/:topic, including model calls.
Requests use the normal MQTT and model access checks for the current user.
Model calls
The topic can refer to a model. In this case the topic pattern is one of:
/api/model/mymodel/get/foo/barmaps tom_mymodel:m_get([ <<"foo">>, <<"bar">> ], Msg, Context)/api/model/mymodel/post/foo/barmaps tom_mymodel:m_post([ <<"foo">>, <<"bar">> ], Msg, Context)/api/model/mymodel/delete/foo/barmaps tom_mymodel:m_delete([ <<"foo">>, <<"bar">> ], Msg, Context)
In all cases, Msg is an MQTT message map, with the payload set to the body of the received request. In case of a
GET, HEAD or DELETE the payload is set to a map of the query arguments.
Note that for a POST the payload might not be the complete message as additional query arguments are passed via
z_context:get_q(<<"argument_name">>, Context). If the model function is called using MQTT, then all arguments
are contained in the payload.
HTTP methods
| HTTP method | Supported topics |
|---|---|
| GET | Model get topics and non-model topics. |
| HEAD | Model get topics only. |
| POST | Any topic, including model get, post and delete topics. |
| DELETE | Model delete topics only. |
| OPTIONS | Any topic; does not call the model or publish a message. |
A method/topic mismatch returns 400 Bad Request. Known HTTP methods outside this list return
405 Method Not Allowed; unrecognized methods return 501 Not Implemented.
The Allow header lists the controller's methods, rather than
filtering them for the requested topic.
HEAD executes the model call and returns the same status and headers as GET, without a response body. It still performs authorization and model validation; it does not return success without checking the result. For example, to check whether all sites are running:
curl --head https://example.com/api/model/zotonic_status/get/check
On a site exposing the zotonic_status model, this returns 200 OK when all sites are running,
or 500 Internal Server Error when the check fails.
Replies
By default, the controller publishes a message to the topic and waits up to 60 seconds for
its response. The response is encoded in the negotiated content type, with JSON as the default.
Model errors determine the HTTP status, for example 403 for eacces and 404 for enoent
or unknown_path.
With the response_topic query argument, the controller publishes the message and returns
without waiting for the model's result. A non-empty value supplies the MQTT response topic;
an empty value publishes without a response topic. The HTTP reply then reports the outcome
of publishing, not the outcome of the model call.
HEAD rejects any response_topic query argument with 400 Bad Request, including an empty
value or a bare ?response_topic. This ensures that HEAD waits for the model's result.