{"id":1822,"date":"2026-05-22T13:40:52","date_gmt":"2026-05-22T11:40:52","guid":{"rendered":"https:\/\/kindsonthegenius.com\/blog\/?p=1822"},"modified":"2026-05-22T13:40:52","modified_gmt":"2026-05-22T11:40:52","slug":"inventoryms-springboot-roles-and-privileges-2-the-data-model-and-api","status":"publish","type":"post","link":"https:\/\/kindsonthegenius.com\/blog\/inventoryms-springboot-roles-and-privileges-2-the-data-model-and-api\/","title":{"rendered":"InventoryMS \u2013 SpringBoot Roles and Privileges 2 ( The Data Model and API)"},"content":{"rendered":"<p>This is Part 3 SpringBoot Roles and Privileges implementation for our Inventory Management System (InventoryMS).<\/p>\n<p>In this tutorial, we would actually implement the Roles and Privileges in our Inventory Management System.<\/p>\n<p><strong>Content<\/strong><\/p>\n<ol>\n<li><a href=\"#t1\">The Basic\u00a0 Approach<\/a><\/li>\n<li><a href=\"#t2\">The Fine-Grained Approach<\/a><\/li>\n<li><a href=\"#t3\">The Roles Management Classes<\/a><\/li>\n<li><a href=\"#t4\">The Controller Endpoints<\/a><\/li>\n<li><a href=\"#t5\">How the savePrivileges Work<\/a><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>Now, let&#8217;s take some time to understand how management of roles and privileges work in Spring Boot. There are two approaches to handling Roles and Privileges in SpringBoot.<\/p>\n<ul>\n<li>The Basic Approach<\/li>\n<li>The Fine-grained Approach<\/li>\n<\/ul>\n<h4><strong id=\"t1\">1. The Basic Approach: User-&gt; Roles -&gt; Privilege Relationship<\/strong><\/h4>\n<p>The User -&gt; Role relationship could either be one-to-many or many-to-many.<\/p>\n<p>This means a User could have more that one role<\/p>\n<p>The Role -&gt; Privilege relationship could also either be one-to-many or many-to-many<\/p>\n<p>Generally, a Role would have multiple privileges<\/p>\n<p>Also, a user assigned a given role, would inherit all the privileges under that role ( we would not use this approach, we would use a more fine-grained approach)<\/p>\n<p><strong>To assign a User additional permissions, you could either:<\/strong><\/p>\n<ul>\n<li>assign the User additional Role that includes the desired permission<\/li>\n<li>add the desired permission to the Role the User currently holds<\/li>\n<\/ul>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t2\">2. A Fine-Grained Approach: User -&gt; Privilege, Role -&gt; Privilege<\/strong><\/h4>\n<p>In this application, we would use the Fine-Grained Approach. The Basic Approach was used in <a href=\"https:\/\/youtu.be\/FzNqL3dxEwc?si=flIJrPzaIsS8fWcI\" target=\"_blank\" rel=\"noopener\">FleetMS version 2<\/a>.<\/p>\n<p>As mentioned above, if a user is assigned a role, he would automatically inherit all the privileges under that role. However, we would use this approach.<\/p>\n<p>In the fine-grained approach, a users could be assigned privileges\u00a0 from any role. This means that a user could be assigned some privileges from the ADMIN role and some privileges from the FINANCE MANAGER role.<\/p>\n<p>This also allows us to assign a user all the privileges under a given role if needed.<\/p>\n<p><strong>AssignAll and UnassignAll<\/strong><\/p>\n<p>Since a user has privileges and each privilege belongs to a role, we could implement &#8216;Role Assignment&#8217; by assigning the user all the privileges belonging to specific role. Same for unassign as we. The screen appears as shown below:<\/p>\n<figure id=\"attachment_15098\" aria-describedby=\"caption-attachment-15098\" style=\"width: 1024px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2024\/10\/Screenshot-2024-10-13-at-10.09.17-scaled.jpg\"><img decoding=\"async\" loading=\"lazy\" class=\"wp-image-15098 size-large\" src=\"https:\/\/www.kindsonthegenius.com\/wp-content\/uploads\/2024\/10\/Screenshot-2024-10-13-at-10.09.17-1024x640.jpg\" alt=\"User Role\/Privilege assignment screen\" width=\"1024\" height=\"640\" \/><\/a><figcaption id=\"caption-attachment-15098\" class=\"wp-caption-text\">User Role\/Privilege assignment screen<\/figcaption><\/figure>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t3\">3. Implementing the Roles Management Classes<\/strong><\/h4>\n<p>The following classes would participate in the Roles Management implementation:<\/p>\n<ul>\n<li><strong>User<\/strong> &#8211; create a OneToMany relationship between User and Privilege<\/li>\n<li><strong>Role<\/strong> &#8211; create a OneToMany relationship between Role and Privilege<\/li>\n<li><strong>Privilege<\/strong> &#8211; create a ManyToOner relation from Privilege to Role<\/li>\n<li><strong>UserPrivilegeAssignment<\/strong>\u00a0 &#8211; relates both User and Role (we use this so that we don&#8217;t have to do a ManyToMany as this is a bit tricky to manage ????)<\/li>\n<\/ul>\n<p>We have chosen these models in such a way to avoid a many-to-many relationship since this is a bit tricky while working with Roles and Privileges in SpringBoot.<\/p>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t4\">4. Implementing the Controller Endpoints<\/strong><\/h4>\n<p>We would need the following controller endpoints in addition to the 5 standard methods (getAll, getOne, add, edit, delete):<\/p>\n<table>\n<tbody>\n<tr>\n<td width=\"186\"><strong>Description<\/strong><\/td>\n<td width=\"137\"><strong>Route<\/strong><\/td>\n<td width=\"157\"><strong>Implemented In Controller<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"186\">1. Save privileges<\/td>\n<td width=\"137\">POST: \/user\/{id}\/privileges<\/td>\n<td width=\"157\">UserPrivilegeAssignment<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">2. Get User Privileges<\/td>\n<td width=\"137\">GET: \/user\/{id}\/privileges<\/td>\n<td width=\"157\">UserPrivilegeAssignment<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">3. Get Users in Privilege<\/td>\n<td width=\"137\">GET: \/privilege\/{id}\/users<\/td>\n<td width=\"157\">UserPrivilegeAssignment<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">4. Clear assigned privileges<\/td>\n<td width=\"137\">PUT:\/user\/{id}\/privileges\/clear<\/td>\n<td width=\"157\">UserPrivilegeAssignment<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">5. Assign Role (assign all privileges in role)<\/td>\n<td width=\"137\">PUT:\/role\/{roleid}\/assign\/user\/{userid}<\/td>\n<td width=\"157\">Role<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">6. UnAssign Role (unassign all privileges in role)<\/td>\n<td width=\"137\">DELETE:\/role\/{roleid}\/unassign\/user\/{userid}<\/td>\n<td width=\"157\">Role<\/td>\n<\/tr>\n<tr>\n<td width=\"186\">7. Get Privileges in Role<\/td>\n<td width=\"137\">GET:\/role\/{roleid}\/privileges<\/td>\n<td width=\"157\">Role<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<h4><strong id=\"t5\">5. How savePrivileges Work<\/strong><\/h4>\n<p>This controller method takes a list of Privileges retrieved from the request body as well as the user id retrieved from the path variable.<\/p>\n<p>It updates the user privileges by performing two steps:<\/p>\n<ul>\n<li>Step 1- clear existing user privileges<\/li>\n<li>Step 2 &#8211; assign the new privileges provided<\/li>\n<\/ul>\n<p>Note that this two steps has to be performed within a transaction. The function is given below:<\/p>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888888;\">\/\/1. Save privileges<\/span>\r\n<span style=\"color: #555555; font-weight: bold;\">@Transactional<\/span>\r\n<span style=\"color: #555555; font-weight: bold;\">@PostMapping<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"\/user\/{userid}\/privileges\"<\/span><span style=\"color: #333333;\">)<\/span>\r\n<span style=\"color: #008800; font-weight: bold;\">public<\/span> ResponseEntity<span style=\"color: #333333;\">&lt;<\/span>String<span style=\"color: #333333;\">&gt;<\/span> <span style=\"color: #0066bb; font-weight: bold;\">saveUserPrivilegeAssignments<\/span><span style=\"color: #333333;\">(<\/span>\r\n        <span style=\"color: #555555; font-weight: bold;\">@RequestBody<\/span> List<span style=\"color: #333333;\">&lt;<\/span>Privilege<span style=\"color: #333333;\">&gt;<\/span> privileges<span style=\"color: #333333;\">,<\/span>\r\n        <span style=\"color: #555555; font-weight: bold;\">@PathVariable<\/span> Long userid<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n    <span style=\"color: #008800; font-weight: bold;\">try<\/span> <span style=\"color: #333333;\">{<\/span>\r\n        userPrivilegeAssignmentService<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">deletePrivileges<\/span><span style=\"color: #333333;\">(<\/span>userid<span style=\"color: #333333;\">);<\/span>\r\n        List<span style=\"color: #333333;\">&lt;<\/span>Privilege<span style=\"color: #333333;\">&gt;<\/span> savedPrivileges <span style=\"color: #333333;\">=<\/span> userPrivilegeAssignmentService<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">savePrivileges<\/span><span style=\"color: #333333;\">(<\/span>privileges<span style=\"color: #333333;\">,<\/span> userid<span style=\"color: #333333;\">);<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">return<\/span> ResponseEntity<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">status<\/span><span style=\"color: #333333;\">(<\/span>HttpStatus<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">CREATED<\/span><span style=\"color: #333333;\">).<\/span><span style=\"color: #0000cc;\">body<\/span><span style=\"color: #333333;\">(<\/span>savedPrivileges<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">toString<\/span><span style=\"color: #333333;\">());<\/span>\r\n    <span style=\"color: #333333;\">}<\/span> <span style=\"color: #008800; font-weight: bold;\">catch<\/span> <span style=\"color: #333333;\">(<\/span>Exception e<span style=\"color: #333333;\">)<\/span> <span style=\"color: #333333;\">{<\/span>\r\n        <span style=\"color: #008800; font-weight: bold;\">return<\/span> ResponseEntity<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">status<\/span><span style=\"color: #333333;\">(<\/span>HttpStatus<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">INTERNAL_SERVER_ERROR<\/span><span style=\"color: #333333;\">)<\/span>\r\n                <span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">body<\/span><span style=\"color: #333333;\">(<\/span><span style=\"background-color: #fff0f0;\">\"Failed to delete user privileges: \"<\/span> <span style=\"color: #333333;\">+<\/span> e<span style=\"color: #333333;\">.<\/span><span style=\"color: #0000cc;\">getMessage<\/span><span style=\"color: #333333;\">());<\/span>\r\n    <span style=\"color: #333333;\">}<\/span>\r\n<span style=\"color: #333333;\">}<\/span>\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>In the next part, we would understand the concept of <a href=\"https:\/\/www.kindsonthegenius.com\/inventoryms-springboot-roles-and-privileges-3-implementing-granted-authorities\/\" target=\"_blank\" rel=\"noopener\">Granted Authorities in Spring Boot<\/a>. Then we would use our API to set up access restriction to our API endpoints.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is Part 3 SpringBoot Roles and Privileges implementation for our Inventory Management System (InventoryMS). In this tutorial, we would actually implement the Roles and &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[414],"tags":[],"_links":{"self":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1822"}],"collection":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/comments?post=1822"}],"version-history":[{"count":1,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1822\/revisions"}],"predecessor-version":[{"id":1823,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/posts\/1822\/revisions\/1823"}],"wp:attachment":[{"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/media?parent=1822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/categories?post=1822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kindsonthegenius.com\/blog\/wp-json\/wp\/v2\/tags?post=1822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}