Friendly URL structure
Oracle has updated apex.oracle.com to APEX 20.1 which includes among other features the new “Friendly URL” option. The legacy URL structure concatenated a string of parameters into a single “p” parameter, which works fine; but it can make it difficult to configure web server rules to match and rewrite URLs. Apart from the application ID or alias (the first part), all the parameters are optional; if all were specified the URL will be something like this (line breaks added for clarity):
f?p=SAMPLE_DB_APP:HOME:16801234560918:myrequest:mydebug :myclearcache:myitems:myvalues:myprinterfriendly &p_trace=mytrace &cs=19A56DBFDXXXE4DF293C96D786 &c=jk64
In this example, the application alias is used (SAMPLE_DB_APP
) and page alias (HOME
) followed by the session ID etc. I’ve also specified the workspace (jk64
) using the “c
” query parameter.
In APEX 20.1 if you edit your Application Properties, you will see the new “Friendly URLs” setting.
With this setting turned on, URLs generated throughout the application will take this form (this is not exhaustive, there are other query parameters supported as well):
/pls/apex/jk64/r/sample_db_app/home ?myitems=myvalues &request=myrequest &clear=myclearcache &debug=mydebug &printerFriendly=myprinterfriendly &session=16801234560918 &p_trace=mytrace &cs=19A56DBFDXXXE4DF293C96D786
When the documentation says the URLs should be “easier to read” I’m pretty sure they mean “by developers”, not end users. I suppose this means the URLs make more sense to developers of other web-based applications, because they conform better to REST URL conventions.
In its simplest form, the URL generated by APEX will include just the workspace path prefix, application, page, and session ID:
/pls/apex/jk64/r/sample_db_app/home?session=16801234560918
Calling APEX_PAGE.GET_URL
generates the URLs correctly for the application according to whether the Friendly URL setting is on or not.
I noticed the following features of this new format:
- The URL generated by
APEX_PAGE.GET_URL
now includes a full path (excluding the domain). - Instead of the “
c
” workspace query parameter, the application’s Path Prefix (which could be set to something other than the workspace name) is used (jk64
in my example). This is not the workspace name, although in most cases it usually will happen to be the same because it’s defaulted that way. This attribute is set at the workspace level, under Administration / Manage Service / Set Workspace Preferences / SQL Workshop. - If not specified, the application and page alias will be used rather than the application or page ID, which is nice.
- Even if you specify the application or page alias in uppercase,
APEX_PAGE.GET_URL
returns them in all lowercase. - The more important attributes relevant to a user navigating the application are now further towards the start of the URL, such as page and item values, so they will be more likely to be noticed by the end user.
- The “
/r/
” bit in the URL is just that. It’s just “r” and can’t be anything else, don’t ask me what it means. EDIT: apparently it stands for “router”…
If your users have bookmarked your application using the legacy URL format, you can still safely upgrade your application to use Friendly URLs because both are still supported. This also means that if you have some old code that generates links programmatically they should still work the same (although it is best practice to call APEX_PAGE.GET_URL
for this purpose).
In case you’re wondering, it is not possible to change the URL format when calling APEX_PAGE.GET_URL
, it will follow your application’s Friendly URL setting. If you call APEX_PAGE.GET_URL
for another application, it will return the correct format of URL for the target application. If you call APEX_PAGE.GET_URL
for an application that does not exist, it will return the URL in the legacy format.
Existing applications after upgrading, or ones you import from an older version of APEX, will still use the legacy URL syntax. New applications will use the new Friendly URLs by default – but you can revert them to the legacy URLs if you wish.
On a side note, in earlier versions when you create a new application the application alias was set to the application ID by default. In APEX 20.1, a new application will have an application alias generated from the initial application name; when I tried it, it added a number as well for some reason.
For obvious reasons, existing code that parses the URL (e.g. in javascript on the client) will probably break. This is a fairly rare thing but does happen (such as in a plugin of mine which I’ll need to fix).
At this very early stage, the legacy URL format is still fully supported – I imagine it will eventually be deprecated, but not yet.
Finally, I’d like to point out some entries on the APEX Feature Requests site:
Our patience has been rewarded 🙂
Morten
22 April 2020 - 1:30 pm
The constant “r” in the URL stands for “router”.
The new trace parameter name is just “trace”, not “p_trace”.
Jeffrey Kemp
22 April 2020 - 1:39 pm
Hi Morten,
Thanks for that, very enlightening.
With regards to the trace parameter, in my testing on apex.oracle.com the url generated produces “&p_trace=”, not “&trace=”. Perhaps this is a bug, as the documentation does indeed say we should expect it to be called “trace”.
Jeff
Inzy
14 May 2020 - 12:57 am
How we can use new format for PREPARE_URL with triggering element
some cases like
apex_util.prepare_url('f?p='||:APP_ID||':24:'||:APP_SESSION||'::NO::P24_CASE_ID:'|| :P21_ID , p_triggering_element => 'apex.jQuery(''#SAVEBUTTON'')' );
Jeffrey Kemp
15 May 2020 - 2:46 pm
Hi Inzy,
I recommend switching to use
APEX_PAGE.GET_URL
instead, which should work with both legacy and friendly URLs depending on what your application uses, e.g.:Jeff
Anonymous
5 June 2020 - 4:51 pm
I’m one of the ugly guys who embed APEX applications in Confluence pages for end user convenience via iframes. For this to work I have to allow this in the security configuration of my APEX application of course. Worked fine, but …
I found out that the use of the “userfriendly urls” in the iframe results in a denied access while the use of the “old” url format still works.
Functional regression?
And no .. I don’t need any iframe discussion at all ….
Jeffrey Kemp
5 June 2020 - 4:53 pm
Could be regression – I recommend you raise this on Oracle Community – https://community.oracle.com/community/groundbreakers/database/developer-tools/application_express
Issam
12 June 2020 - 5:33 pm
Hi,
I call a pdf report from apex page using url. It was working fine but after enabling the friendly url option, the url is converted from:
f?p=&APP_ID.:0:&SESSION.:PRINT_REPORT=check_list_maintenance
to:
f?p=&APP_ID.:0:&SESSION.:PRINT_REPORT%253Dcheck_list_maintenance
so the pdf cannot be generated anymore.
Any idea about that?
Thank you
Jeffrey Kemp
12 June 2020 - 5:36 pm
Hi Issam,
The new URL is not in “Friendly URL” form so I suspect you have some custom code in your application that is generating the URL directly (i.e. bypassing the APEX URL API). It is then getting encoded for some reason.
I would examine the code that is generating this URL; you should be able to replace it to use the documented APEX_PAGE.GET_URL function which should generate the correct URL.
Jeff
bifin
1 July 2020 - 4:07 pm
Hi Jeffrey
I have a small problem when switching to Apex 20.1
Can you suggest a solution?
https://community.oracle.com/thread/4336950
Jeffrey Kemp
1 July 2020 - 5:01 pm
Sorry, that link seems to be to an issue with uploading files; how is that related to the new URL structure?
Sunil Bhatia
13 July 2020 - 7:40 pm
Hi Jefferey,
l_url :=
APEX_UTIL.prepare_url (
p_url =>
‘f?p=’
|| :app_id
|| ‘:’
|| :app_page_id
|| ‘:’
|| :app_session);
OWA_UTIL.redirect_url (l_url);
Using normal URL, it works fine and redirects, but using friendly URL, it does nothing. Do you suspect any issue with OWA_UTIL?
Thanks,
Sunil Bhatia
Arijit Kanrar
28 July 2020 - 12:33 am
Hi Jeffrey,
Can we generate the URLs using JS code. I have an application that determines which page to open based on the selections the user has made. Now I have to make an AJAX call to get the URL from the back-end as the pages are modal and the checksum has to be supplied by the back-end.
Is there any front-end JS API to generate URLs for modal pages?
Thanks!
Arijit
Jeffrey Kemp
28 July 2020 - 12:17 pm
Hi Arijit,
If the page you are linking to requires a checksum, it MUST be generated on your server. If it were possible to generate the checksum on the user’s client machine, that would defeat the purpose of using checksums for security.
Therefore, if you need to generate a URL on the client, you will need to switch off the checksum requirement on the target page. You will, however, need to consider the security implications of this in the context of your application.
I hope this helps.
Jeff
alix
18 December 2021 - 2:01 pm
Hi Jeff , how can I make my URL like those in Universal Theme sample app. I mean without sesison state and session id in the URL.
Ejemple:
https://apps.<redacted>.com/ords/r/reflexdevelopment/ut/content-modifiers
Jeffrey Kemp
18 December 2021 - 7:26 pm
Hi Alix,
Any page with authentication set to Page is Public will not add a session ID to the URL.
Jeff
Boris
12 February 2022 - 12:47 am
Hi,
When workspace is isolated with domain entered in Allow Hostnames, there is no Path Prefix value in the friendly url, when running the app, and application is not available because of this.
BR
Ethan
23 February 2022 - 9:56 pm
Not sure if this is a bug or expected yet strange behavior. 21.2.1
Calling apex_mail.send changes the behavior of get url radically.
SQL>
SQL> set echo on
SQL>
SQL> select apex_page.get_url (
2 p_application=>100,
3 p_page=>6,
4 p_items=>’foo,bar’,
5 p_values=>’123,test’) from dual;
APEX_PAGE.GET_URL(P_APPLICATION=>100,P_PAGE=>6,P_ITEMS=>’FOO,BAR’,P_VALUES=>’123,TEST’)
————————————————————————————————————————————————————————
f?p=100:6:::::foo,bar:123,test
SQL>
SQL>
SQL> begin
2 apex_mail.send(
3 p_to=>’post.ethan@gmail.com’,
4 p_from=>’ethan@arclogicsoftware.com’,
5 p_subj=>’test’,
6 p_body=>’test’
7 );
8 — apex_mail.push_queue;
9 end;
10 /
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> select apex_page.get_url (
2 p_application=>100,
3 p_page=>6,
4 p_items=>’foo,bar’,
5 p_values=>’123,test’) from dual;
APEX_PAGE.GET_URL(P_APPLICATION=>100,P_PAGE=>6,P_ITEMS=>’FOO,BAR’,P_VALUES=>’123,TEST’)
————————————————————————————————————————————————————————
https://k2.maxapex.net/apex/app/r/sldev/submit_weight?foo=123&bar=test
Jeffrey Kemp
23 February 2022 - 10:22 pm
Hi Ethan,
Interesting – I’ve reproduced it as well in 21.2.3. It’s due to the way that apex_page.get_url works in a database session that has not yet been set up as an APEX session. After calling the apex mail API, the session has now been set up as an APEX session so it can now see the application definition and it knows it accepts friendly URLs.
Before an APEX session is set up, the API has no way of knowing whether the application will accept friendly URLs or not (it cannot see the application definition), so it errs on the side of caution and creates a legacy-style URL which will work either way.
If you call apex_session.create_session before calling apex_page.get_url, you will get a friendly url as well (although note that in this case, the session query parameter will also be added).
Jeff
Scott Oloo
27 June 2024 - 3:37 am
Jeff,
Great but how do you determine the checksum value for your friendly URL?
regards
Jeffrey Kemp
27 June 2024 - 8:22 am
Hi Scott, the checksum is calculated by APEX itself, so if your page requires a checksum you must call APEX_PAGE.GET_URL or APEX_UTIL.PREPARE_URL.