gen_coap
gen_coap copied to clipboard
Give An Example of Request Routing In The Server
Hello, would it be possible to add a small example that explains the request routing in the server and acceding to an appropriate handler for a given URI path.
Currently we have this: https://github.com/gotthardp/gen_coap/blob/master/examples/src/sample_server.erl, and we can figure out if the type of req was GET, POST, PUT, ..., but I see no information how we parse URL string and based on this we call an appropriate handler for this API endpoint.
In general, I would like to understand the CoAP req multiplexer (router) and I would like to see something like this: https://github.com/go-zoo/bone/blob/master/example/001/example.go#L34-L38 as a framework that would enable quick development of the API.
Have look at the tests, e.g. https://github.com/gotthardp/gen_coap/blob/master/test/simple_storage_tests.erl.
The coap_server_registry:add_handler
registers a handler for a given prefix, which is a list of binaries like [<<"A">>, <<"B">>, ...]
corresponding to URI path /A/B/...
. The multiplexer then takes the longest prefix registered and invokes a specific handler. The handler receives the prefix as the second parameters as well as the rest of the URI as the third parameter.
If there is a handler1
for /A
and handler2
for /A/B
, then a COAP GET call for /A/Z
calls handler1:coap_get(_ChId, [<<"A">>], [<<"Z">>], _Query)
, whereas a call for /A/B
calls handler2:coap_get(_ChId, [<<"A">>, <<"B">>], [], _Query)
.
Is it a bit clearer?
If there is a handler1 for /A and handler2 for /A/B... - how do you actually add handler1
and handler2
?
I came up with something like:
coap_server_registry:add_handler([<<"test">>], ?MODULE, undefined),
coap_server_registry:add_handler([<<"hello">>], ?MODULE, _Query),
coap_server_registry:add_handler([<<"hello">>, <<"world">>], ?MODULE, undefined).
but they are all calling the same handler called coap_get/4
in the same module.
Also, what does _Query
represent here - where does this variable comes from?
One additional question but very important: if I have a URL like:
/A/:B/C
where B is varaible (can change - for example /A/123/C
and /A/456/C
) and I want to extract this parameter in the handler - what is the best way to do it?
The ?MODULE
represents the module name. If you call add_handler
like this, it will invoke the same module. You should invoke add_handler
from different modules, or replace ?MODULE
by a module name.
I don't think the last parameter of add_handler
is used. It was meant as a parameter for the handler, but no one ever needed that.
To catch /A/:B/C
you coap_server_registry:add_handler([<<"A">>], ?MODULE, undefined)
and then match handler1:coap_get(_ChId, [<<"A">>], [B, <<"C">>], _Query)
which puts content of :B
into B
. The only thing what is not possible now is to have different modules for /A/:B/C
and /A/:B/X
, because the prefix (A
) is the same for both.
BTW, the _Query in coap_get
contains the URI query parameters (?a=x
) etc.
would this help ?