Sto facendo un'API HTTP per l'identità di base ASP.NET.
Fondamentalmente quello che voglio è una versione remota di questo: link
Ha metodi come ChangePasswordAsync
, ChangePhoneNumberAsync
ecc.
Il modo più semplice per farlo sarebbe avere un modello di richiesta separato per ciascuno di questi metodi come ChangeUserPasswordRequest
, ChangeUserPhoneNumberRequest
e endpoint separato per ogni modifica come POST /users/changePassword
, POST /users/changePhoneNumber
.
Questo è molto più semplice da implementare rispetto a PUT /users/:id
, ma è leggermente più complicato sul lato client con 1 modulo per tutto (dove ho solo un pulsante di salvataggio). E sarebbe molto più semplice avere 1 modello come UserDto
e 1 endpoint per modificare tutto come PUT /users/:id
.
Confronta te stesso:
public class UserDto
{
public int Id { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
// ... other properties of the user
// ...
}
[HttpPut("{id}")]
public async Task<IActionResult> Put(int id, UserDto userDto)
{
var user = await _userManager.FindByIdAsync(id.ToString());
if (user == null) return NotFound();
if (userDto.PhoneNumber != user.PhoneNumber) // phone number has changed
{
var identityResult = await _userManager.ChangePhoneNumberAsync(user, userDto.PhoneNumber, userDto.Token);
//... error handling
}
// compare each property like that and call adequate method
//...
}
Questo è molto più semplice per il client, poiché colleghi semplicemente UserDto al modulo e lo rimandi sul server con un metodo come UpdateUser(userDto)
.
Ora confrontalo con un'azione che ha una singola responsabilità:
public class ChangeUserPhoneNumberRequest
{
public ChangeUserPhoneNumberRequest(string userId, string phoneNumber, string token)
{
UserId = userId;
PhoneNumber = phoneNumber;
Token = token;
}
public string UserId { get; }
public string PhoneNumber { get; }
public string Token { get; }
}
[HttpPost("changePhoneNumber")]
public async Task<IActionResult> ChangePhoneNumber(ChangeUserPhoneNumberRequest request)
{
var user = await _userManager.FindByIdAsync(request.UserId.ToString());
if (user == null) return NotFound();
var identityResult = await _userManager.ChangePhoneNumberAsync(user, request.PhoneNumber, request.Token);
//... error handling
}
Questo aspetto è leggermente migliore sul server e l'azione è più esplicita, tuttavia, sembra più difficile sul client, poiché non hai il comfort come con 1 modello che puoi semplicemente inviare con 1 metodo come UpdateUser(userDto)
questo ha anche il vantaggio di non inviare proprietà non necessarie. Invece, devi inviare molte richieste per ogni proprietà che desideri modificare come SendChangeUserPasswordRequest
, SendChangeUserEmailRequest
e così via. La mia interfaccia utente non è basata su attività ma è basata su CRUD, quindi è più difficile.
La mia interfaccia utente assomiglia a questa:
(da:
In questo tipo di interfaccia utente, sembra più naturale avere qualcosa come PUT, ma è meno naturale da implementare sul server.
Non voglio cambiare la mia interfaccia utente.
Quale approccio dovrei adottare?
Grazie in anticipo.