We are building application using an API-first approach, where we are building REST APIs only to start with and add the GUI later.
Now, I'm trying to add GUI to some of the modules, and that's where I'm kind of stuck with choosing the right way to move forward.
I have a RestController
method in my Spring Boot Web App to create a User
@PostMapping(value={"/rest/admin/users", "/ajax/admin/users"})
@ApiOperation(value="Create a user", produces="application/json", consumes="application/json")
public ResponseEntity<User> create(@RequestBody User user) {
User createdUser = this.userService.add(user);
URI location = CommonFunctions.buildResourceLocation("/{id}", createdUser.getId());
return ResponseEntity.created(location).body(createdUser);
}
Our REST APIs are secured with Basic Authentication, and the APIs work perfectly without any issues.
Things to note here are:
- The method can be accessed from
/rest/admin/users
as well as from/ajax/admin/users
(/rest
indicating a REST call and/ajax
indicating an AJAX call from the UI). Is this an acceptable approach? - Any calls via the
/rest
URL needs to have a Basic Auth Header, while/ajax
calls are not secured with Basic auth. They take the normal form login authentication instead. In this case, they just require theX-CSRF
headers.
Now, to reduce the code we have to write, I just want to re-use the aforementioned REST controller method to create a user via Ajax.
In my JSP, I have a form like the one below:
<form:form action="/ajax/admin/users" modelAttribute="user" id="user_create_form">
<label for="name">Full Name</label>
<input type='text' id='name' name='name' placeholder='' class='form-control focus-on-load'/>
<label for="email">E-Mail Address</label>
<input type='text' id='email' name='email' placeholder='' class='form-control'/>
<label for="role">Role</label>
<select class='form-control short' name='role.id' id='role'>
<option value='2'>User</option>
<option value='1'>Site Administrator</option>
</select>
</form:form>
On click of the save button, I'm serializing the form data, so that I can get a JSON like this:
{
"name":"User Full Name",
"email":"useremail@somedomain.com",
"role":{
"id":1
}
}
To serialize, I use the following code:
var formData = getFormData($form);
I got the logic for getFormData($form)
from here
This is my AJAX call
$.ajax({
url:$form.attr('action'),
method:'POST',
dataType:'json',
contentType:'application/json',
data:JSON.stringify(formData),
beforeSend:function(xhr) {
if (header && token) {
xhr.setRequestHeader(header, token);
}
},
success:function(result) {
//Do something to indicate success
}, error: function(xhr, textStatus, errorThrown) {
//Do something to indicate failure
}
});
Here everything works fine, except for the serialization. When I serialize my form data, this is what I get
{
"name":"SOme Name",
"email":"someemail@org.com",
"role.id":1
}
as opposed to
{
"name":"Some Name",
"email":"someemail@org.com",
"role":{"id":1}
}
This is the only thing stopping me from re-using my REST controller methods for AJAX requests. GET requests work fine without issues.
While I know I can generate a custom JSON object before I fire the AJAX call, I want a general solution as there are going to be many screens and I want to avoid mistakes as much as possible.
The larger question here is, is it advisable to re-use REST controllers for AJAx requests (provided both have different authentication realms / schemes)? If so, am I following the right approach?
Thanks, Sriram