How to assign a list of list of things to another list of things using an endpoint

Viewed 85

I have an endpoint which assign a list of Roles to a single user.

@PutMapping(value = "/roles/{id}", consumes = MediaType.APPLICATION_JSON_VALUE)
public UserDto modifyRoles(
    @ApiParam(value = "User ID", required = true) @PathVariable("id") Long id,
    @ApiParam(value = "List of ID roles", required = true) @RequestBody List<Long> roles)
    throws someExceptions {
    return serviceClass.modifyUserRoles(id, roles);
}

I want to receive a list of Users aswell a list of Roles so I can assign every role to each user, but i'm not sure how to do it and if I should send the list of users via @PathVariable, or if I there's a better way to do it. This is what I've tried:

@PutMapping(value = "/roles/{usersId}", consumes = MediaType.APPLICATION_JSON_VALUE)
public List<UserDto> modifyMultipleRoles(
    @ApiParam(value = "List of User ID", required = true) @PathVariable("id") List<Long> ids,
    @ApiParam(value = "List of ID roles", required = true) @RequestBody List<Long> roles)
    throws someExceptions {
    return serviceClass.newMethodThatAssignEachRoleToEachUser(ids, roles);
}

Is this the best way to do it? Would this even work?

Thank you

Update response

This is what I've tried right now

List<Long> usersId=objectDto.getUsersId();
List<Long> rolesToAdd = objectDto.getRolesToAdd();
List<Long> rolesToDelete = objectDto.getRolesToRemove();
            
List<Usuario> users = usersId.stream()
                    .map(userId -> this.findById(userId))
                    .collect(Collectors.toList());
            
return users.stream().
// ????

Is that the way to proceed?

3 Answers

You need to make a request class like below as @RequestBody

{
    "users": ["user1", "user2"],
    "roles": ["role1", "role2"]
}


public class RolesRequestBoday {
    public List<String> users;
    public List<String> roles;
}

The easy way to do it is to wrap those list with the same object and use this objest as requestBody param:

public class UsersRolsRequest (){
    private List<Long> users;
    private List<Long> rols;
}

The final result shoul be like this:

@PutMapping(value = "/roles/{usersId}", consumes = MediaType.APPLICATION_JSON_VALUE)
public List<UserDto> modifyMultipleRoles(@ApiParam(value = "Object with the list of ID 
        users and the List of ID roles", required = true) @RequestBody UsersRolsRequest 
        request)throws someExceptions {
    return serviceClass.newMethodThatAssignEachRoleToEachUser(ids, roles);
}

The request json will be like:

{
    "users": [1,2,3],
    "rols": [1,1,2]
}
  • Your current solution won't won't work as you cannot have list as path parameter. So you want to have single payload that represents list of users and roles

  • And then the fist question is do you want to modify the same roles to every user or you want to modify different roles to each user?. Depending on that answer, the payload could be one of the variance

     {
       "users": ["user1", "user2"],
       "roles": ["role1", "role2"]
     }

or

    [
       { 
         "id: "user1"
         "roles": ["role1", "role2"]
       },
       { 
         "id: "user2"
         "roles": ["role2", "role3"]
       },
    ]
  • Once you have made that decision, second question is about the meaning of modifying roles. Does that mean adding some roles and removing some other roles or does it mean replacing the user's current roles with new set of roles?

    • Http Patch variance 1
    • Http Patch variance 2
    • Http Put variance 1
    • Http Put variance 2
      {
         "users": ["user1", "user2"],
         "rolesToAdd": ["role1", "role2"]",
         "rolesToRemove": ["role3"]
      }
    [
       { 
         "id: "user1"
         "rolesToAdd": ["role1"],
         "rolesToRemove": ["role2"],
       },
       { 
         "id: "user2"
         "rolesToAdd": ["role2", "role3"],
         "rolesToRemove": ["role4"],
       },
    ]
      {
         "users": ["user1", "user2"],
         "roles": ["role1", "role2"]",
      }
    [
       { 
         "id: "user1"
         "roles": ["role1", "role2"]
       },
       { 
         "id: "user2"
         "roles": ["role2", "role3"]
       },
    ]
  • Then it is just about creating java object to represent the payload and do the persistence accordingly

Update

  • You can create ModfifyUsersRoleRequest like with getters and setters for those 3 fields. Then you can use it as @RequestBody. Once you are inside the method, do a spring-data-jpa repository call to get all the users with those user ids and you get a list of users back. Then for each user, add the new roles and remove the roles which you want to remove
Related