'Match table rows by REST query-like patterns?
I am implementing ReSTful SICF services for a customer. The SICF service has a single handler (implementing IF_HTTP_EXTENSION~HANDLE_REQUEST) and this calls further API handling classes. The API handling class is stored against the incoming path like this
DDIC Table: ZAPI_HNLDRS
/animals/:id | ZCL_HANDLE_ANIMALS
/animals/:id/tiger/:id | ZCL_HANDLE_TIGER
When the API is called /animals/:id/tiger/:id looks like /animals/4545152/tiger/1423331.
How do I make a call to ZAPI_HNDLRS to get ZCL_HANDLE_TIGER?
Of course, this won't help,
select single HANDLING_CLASS from ZAPI_HNDLRS
into <wa> where uri = '/animals/4545152/tiger/1423331'
I believe I have to use REGEX in some form - I amn't sure how though. How do I match patterns in an ABAP select query?
update
The reason I have a table to store API handlers is because I want the whole process to be dynamic.
We could have newer urls that could be added over a period of time that could look like this.
Thanks for the answers that use SPLIT But that's still not fully dynamic. There could be multiple new urls that could come up in the future. E.g.
/animals/:id/tiger/:id/claws
/animals/:id/tiger/:id/claws/:id
:id - is an unique id
When such cases arise, there will be new handler entries in table ZAPI_HNDLRS.
Hence, I would need a generic logic to convert any incoming resource path. let's say: /animals/1234243242423/tiger/32423443344/claws to it's pattern that's stored /animals/:id/tiger/:id/claws
So that I know the right handler to pick up from the table.
Solution 1:[1]
If you really want to use REGEX you are probably looking for this
REPLACE ALL OCCURRENCES OF REGEX '/\d+/' IN lv_input WITH '/:id/'
For Regex see SAP Help:
https://help.sap.com/http.svc/rc/abapdocu_740_index_htm/7.40/en-US/abenregex_syntax_specials.htm
Solution 2:[2]
You could use regular expressions to split the URI but in this case it seems to be over the top, because a simple SPLIT would suffice. Once you have the URI split into its different parts you can put it back together again with the ':id' strings replacing the actual ID's. If needed you could also add some checks on the ID parts.
Solution 3:[3]
I'd first recommend writing your HTTP handler in a separate class inheriting from CL_REST_RESOURCE rather than trying squeeze everything into handle_request. In that class say ZCL_API_ANIMALS_TIGER you'd reimplement the methods corresponding to HTTP verbs. Your SICF node should inherit from cl_rest_http_handler.
In the method if_rest_application~get_root_handler of your SICF node, you'd attach the handler in this kind of way
lo_router->attach( iv_template = '/animals/{ID}/tiger/{tigerID} ' iv_handler_class = 'ZCL_API_ANIMALS_TIGER' ).
From there, you could pick off the ID or tiger ID from the table coming from mo_request->get_uri_attributes( ) when executing your request.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Gert Beukema |
| Solution 3 | Ryan M |
