Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give An Example of Request Routing In The Server #13

Open
drasko opened this issue Mar 29, 2017 · 4 comments
Open

Give An Example of Request Routing In The Server #13

drasko opened this issue Mar 29, 2017 · 4 comments
Labels

Comments

@drasko
Copy link
Contributor

drasko commented Mar 29, 2017

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.

@gotthardp
Copy link
Owner

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?

@drasko
Copy link
Contributor Author

drasko commented Mar 29, 2017

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?

@gotthardp
Copy link
Owner

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.

@kanishkablack
Copy link

image

image

would this help ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants