Avatar image in Oracle APEX
Using a REST Media Resource as an image source

Why you should read this
Displaying custom avatar images in Oracle APEX’s top navigation bar isn't as straightforward as you might think. By default, APEX lets you use Font APEX icons, but replacing those with actual image - especially ones stored as BLOBs in database - it takes some extra work.
In this post, I've put down the steps to do that using a REST Media Resource as the image source for your avatar, which is one of the simplest and most flexible approaches.
There are a few other possible methods that you can use:
Third-party services that host avatar images and provides image URLs via API (such as Gravatar, used by the APEX Ideas App)
Hosting your avatars in the APEX Static Application Files
Converting your avatar images to Base64-encoded image URLs
Each of these alternatives has its pros and cons and will try to cover them in more detail in future blog post. For now, let’s see how the REST Media Resource approach can help us in achieving our goal.
Step by step guide
REST Module with a GET method, Source type - Media Resource
DECLARE
l_roles OWA.VC_ARR;
l_modules OWA.VC_ARR;
l_patterns OWA.VC_ARR;
BEGIN
ORDS.ENABLE_SCHEMA(
p_enabled => TRUE,
p_url_mapping_type => 'BASE_PATH',
p_url_mapping_pattern => 'gamma_dev',
p_auto_rest_auth => FALSE);
ORDS.DEFINE_MODULE(
p_module_name => 'profile',
p_base_path => '/profile/',
p_items_per_page => 25,
p_status => 'PUBLISHED',
p_comments => NULL);
ORDS.DEFINE_TEMPLATE(
p_module_name => 'profile',
p_pattern => 'profile_picture/:user_id',
p_priority => 0,
p_etag_type => 'HASH',
p_etag_query => NULL,
p_comments => NULL);
ORDS.DEFINE_HANDLER(
p_module_name => 'profile',
p_pattern => 'profile_picture/:user_id',
p_method => 'GET',
p_source_type => 'resource/lob',
p_mimes_allowed => NULL,
p_comments => NULL,
p_source =>
'select mime_type as content_type, blob_content from MY_USERS_TABLE where id = :user_id');
ORDS.DEFINE_PARAMETER(
p_module_name => 'profile',
p_pattern => 'profile_picture/:user_id',
p_method => 'GET',
p_name => 'user_id',
p_bind_variable_name => 'user_id',
p_source_type => 'URI',
p_param_type => 'STRING',
p_access_method => 'IN',
p_comments => NULL);
COMMIT;
END;


Desktop Navigation Bar entry
<img id="user_avatar_img" class="ea-topnav-avatar" src="https://oracleapex.com/ords/gamma_dev/profile/profile_picture/&G_USER_ID."></img>


Application Item with the User_ID, used in the REST module


Add CSS to style the navigation
/* Navigation Bar avatar fixes */
.t-NavigationBar {
align-items: center;
}
.ea-topnav-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
border: 3px #6b3010 solid;
}
@media (max-width:768px) {
.ea-topnav-avatar {
width: 32px;
height: 32px;
}
}
@media (max-width:479px) {
.ea-topnav-avatar {
margin-right: 20px;
}
.t-NavigationBar {
column-gap: 25px;
}
}
.t-Button--navBar .t-Button-badge {
display: flex;
border-radius: 50%;
padding: 0;
background: none;
}
See your avatar in action


Security
Instead of just USER_ID, use a hashed version on the User_id + User_Email or any other columns in your user table
Create new Application Item, called
G_USER_HASHCompute
G_USER_HASHafter Authentication (using Application Process or Application Computation). Here is a sample code for a hashing that you could use:select mime_type content_type, profile_image blob_content from my_users_table where apex_util.get_hash(apex_t_varchar2 (id, user_email)) = :user_hash
Modify the REST module to use the
G_USER_HASH, instead of just user_id
- Change the Resource Template, replacing :user_id with :user_hash parameter (similar to the below):

Change the
GETmethod Source and Parameter name:select mime_type content_type, profile_image blob_content from my_users_table where apex_util.get_hash(apex_t_varchar2 (id, user_email)) = :user_hash




