Overlapping Resource URI Templates

It is possible for the URI Templates of Application Express Listener RESTful Services to overlap, meaning that more than one URI Template can match a single URI. For example consider these two URI Templates: [code language=“text”] employees/{id} employees/{id}/manager [/code] For the following URI path: employees/7469, which URI Template (and therefore which Resource Template and Resource Handler) should Application Express Listener choose? Let’s look at an actual example, I’ve created a RESTful Service Module (with a URI prefix of: overlaps/) on apex.oracle.com: [code language=“bash”] curl -i https://apex.oracle.com/pls/apex/resteasy/overlaps/employees/7499 HTTP/1.0 200 Connection established HTTP/1.1 200 OK Date: Thu, 22 Aug 2013 09:20:16 GMT Transfer-Encoding: chunked Content-Type: application/json {“empno”:7499,“ename”:“ALLEN”,“job”:“SALESMAN”,“mgr”:7698,“hiredate”:“1981-02-20T00:00:00Z”,“sal”:1600,“comm”:300,“deptno”:30} [/code] That looks OK, we expect that the employees/{id} URI Template would be chosen and we expect that the result would be data about employee 7499, which this seems to be. Now which URI Template will Listener choose for the following path: employees/7499/manager? Let’s find out: [code lanaguage=“bash”] curl -i https://apex.oracle.com/pls/apex/resteasy/overlaps/employees/7499/manager HTTP/1.0 200 Connection established HTTP/1.1 500 Internal Server Error Date: Thu, 22 Aug 2013 09:23:49 GMT Error-Reason: error=“resource.template.evaluation”; error_description*=UTF-8’‘Error%20during%20evaluation%20of%20resource%20template%3a%20GET%20overlaps%2femployees%2f%7bid%7d%2c%20SQL%20Error%20Code%3a%201%2c722%2c%20SQL%20Error%20Message%3a%20ORA-01722%3a%20invalid%20number%0a Connection: close Content-Type: text/html; charset=UTF-8 …HTML error page omitted for clarity… [/code] Hmm, that’s not what we expected, it looks like there’s a problem. Here’s the actual error message displayed on screen: overlap It says:

Error during evaluation of resource template: GET overlaps/employees/{id}, SQL Error Code: 1,722, SQL Error Message: ORA-01722: invalid number

Notice the error message says the employees/{id} URI Template is being chosen, not employees/{id}/manager, which leads to the SQL error because the string: 7499/manager cannot be converted to a number. Why is Listener choosing employees/{id} over employees/{id}/manager? Well the simple fact is that both URI Templates do match the employees/7499/manager path. Listener has to choose one and in the absence of any other criteria Listener will choose the shortest URI Template.

Fixing the problem

To resolve this problem we must set the ‘priority’ value associated with the employees/{id}/manager URI Template to be higher than the priority associated with the employees/{id} URI Template. You can see the ‘priority’ setting here: priority. Listener will always choose the URI Template with the highest priority, thus giving employees/{id}/manager a priority of 1 and employees/{id} a priority of 0 means that Listener will choose employees/{id}/manager when processing a request for: employees/7499/manager. To demonstrate this I created two more Resource Templates in the overlaps/ RESTful Service Module, with the priorities fixed. Let’s try them out: [code language=“bash”] curl -i https://apex.oracle.com/pls/apex/resteasy/overlaps/fixed/employees/7499 HTTP/1.0 200 Connection established HTTP/1.1 200 OK Date: Thu, 22 Aug 2013 09:54:08 GMT ETag: “A7rDBCEuC8pkiZrA7ifn7kkAgPUxn2ZjMTV03VhNSJ9Pl9QvCDF09UKXBa8DGE6128D5rJxjYOE2cXHp+npe0Q==” Content-Type: application/json {“empno”:7499,“ename”:“ALLEN”,“job”:“SALESMAN”,“mgr”:7698,“hiredate”:“1981-02-20T00:00:00Z”,“sal”:1600,“comm”:300,“deptno”:30} [/code] As before the employee details for 7499 are returned as expected, now let’s try the employees/7499/manager URI: [code language=“bash”] curl -i https://apex.oracle.com/pls/apex/resteasy/overlaps/fixed/employees/7499/manager HTTP/1.0 200 Connection established HTTP/1.1 200 OK Date: Thu, 22 Aug 2013 09:54:57 GMT ETag: “Luk37RW0IusktYysyhni7hfCLAa+e2/NvuVkwjSwIe9Dc0Oa3tLeKOdC/Z9MPA7LEZhYn/CHNlLYnZ6flZmT2A==” Content-Type: application/json {“uri”:{"$ref":“https://apex.oracle.com/pls/apex/resteasy/overlaps/fixed/employees/7698"},"ename":"BLAKE"} [/code] Great! it’s working now.

Conclusion

The rule of thumb for assigning URI Template priorities is:

Give the most specific URI Template the highest priority, give the least specific URI Template the lowest priority.

Ⓗ Home   Ⓑ Blog   Ⓐ About