Je recherche les meilleures pratiques de conception d'API RESTful pour le cas d'utilisation suivant:
Véhicule d'objet de domaine:
class Vehicle {
private String vehicleType;
private String colour;
private String transmission;
private String yearOfIssue;
}
Un exemple d'objet:
Vehicle = {vehicleType : 'Car', colour : 'Red', transmission : 'Automatic', yearOfIssue : '2008'};
Dans ce modèle de domaine, il n'y a pas d'identifiant unique à champ unique (par exemple, vehicleId), mais tous les champs de l'objet forment ensemble la clé primaire (cette contrainte est présente dans la couche base de données).
Nous n'avons pas la possibilité de modifier ce modèle de domaine pour ajouter un identificateur unique de champ unique.
Ma question est donc la suivante: si je souhaite ajouter une API REST simple au-dessus de cet objet de domaine, qui fournit une fonctionnalité simple permettant de créer, mettre à jour, supprimer et obtenir des véhicules, quelle est la meilleure pratique pour PATH points finaux pour ces méthodes?
Suivant l'exemple ci-dessus, si le modèle de domaine devait avoir un identifiant unique VehicleId de champ unique, je peux imaginer les points de terminaison suivants:
GET /vehicles/:vehicleId
PUT /vehicles/:vehicleId
DELETE /vehicles/:vehicleId
Je ne connais pas de modèle similaire à celui-ci pour les clés composites:
GET /vehicles/:vehicleTypecolourtransmissionyearOfIssue
GET /vehicles/CarRedAutomatic2008
semble incorrect.
Tout conseil sur un bon modèle à suivre pour ce cas d'utilisation serait grandement apprécié.
Merci
Conformément aux normes générales REST, chaque noeud final expose une ressource et le client peut y travailler avec des verbes http. Dans cet exemple, votre ressource est véhicule et le client extrait les données du serveur à l'aide de GET. Idéalement, chaque ressource devrait être identifiée de manière unique avec une clé unique.
Mais votre ressource (véhicule) ne possède pas de clé unique à valeur unique et ne peut pas être modifiée dans le système! Dans ce cas, vous pouvez toujours effectuer l'appel GET avec tous les paramètres requis pour identifier la ressource, comme pour tout autre appel http standard, tel que
GET /vehicles?type=Car&color=Red&transmission=Automatic&manufactureYear=2008
La technologie/plate-forme que vous utilisez, si cela vous permet de créer des itinéraires personnalisés pour votre méthode, vous pouvez créer un itinéraire personnalisé comme
new route("/vehicles/{type}/{color}/{transmission}/{manufactureYear}")
Et appelez votre service en tant que
GET /vehicles/Car/Red/Automatic/2008
La bonne chose à ce sujet est que votre uri devient plus court. Mais d’autre part [1] Pour toutes les méthodes/ressources de ce type, vous devrez créer des itinéraires personnalisés, et [2] cet uri n’a pas beaucoup de sens si vous ne connaissez pas la méthode et l’itinéraire spécifiques.
Dans ASP.NET Core, je représente généralement une clé composite comme ceci:
POST /vehicles/(car:red:automatic:2008)
ou
POST /vehicles/(car|red|automatic|2008)
La structure n'a aucun problème pour les mapper à des paramètres d'action dans l'ordre spécifié.
[HttpPut("vehicles/({car}:{color}:{trans}:{year})")]
public async Task<IActionResult> Add(
string car, string color, string trans, int year, [FromBody] Vehicle request)
{
await Task.CompletedTask;
return Ok();
}
Exemple de demande: PUT /vehicles/(Ford:Ranger:100% genuine:2000)
Pour être RESTful, vous devez créer un identifiant unique et unique pour augmenter votre classe.
class Vehicle {
public int vechicleId { get; set; }
public string vehicleType { get; set; }
public string colour { get; set; }
public string transmission { get; set; }
public string yearOfIssue { get; set; }
}
Vous pourrez ensuite y accéder via HTTP: Get http: // mysite/véhicules/3842 . Cependant, il est possible que vous n'ayez pas accès à l'identificateur interne unique, en particulier lorsque vous créez ou mettez à jour la base de données. J'ai rencontré des problèmes similaires et pour utiliser les verbes REST, je vais inclure un identifiant externe afin de faciliter l'accès des utilisateurs aux systèmes externes:
class Vehicle {
public int vechicleId { get; set; }
public string externalId { get; set; }
public string vehicleType { get; set; }
public string colour { get; set; }
public string transmission { get; set; }
public string yearOfIssue { get; set; }
}
Le verbe se présente alors comme suit: HTTP: Récupérez http: // mysite/véhicules/externalId/sedanbluemanual2015 . Vous n'avez pas à analyser l'URI car toutes les données doivent figurer dans le corps du message. Il vous suffit de vous assurer que la chaîne identifie le véhicule de manière unique.
[HttpPut("externalId/{externalId}")]
public IActionResult PutVehicle([FromRoute] string externalId, [FromBody] JObject jObject)
{
// See if the record exists already.
var oldVehicle = (from v in vehicles
where vehicle.ExternalId == externalId
select v).FirstOrDefault();
if (oldVehicle != null)
{
<insert new vehicle>
}
else
{
<update old vehicle>
}