Component Key for REST API Methods

I am looking for best practices in RESTful API design for the following use:

Domain object object:

class Vehicle { private String vehicleType; private String colour; private String transmission; private String yearOfIssue; } 

Example object:

 Vehicle = {vehicleType : 'Car', colour : 'Red', transmission : 'Automatic', yearOfIssue : '2008'}; 

In this domain model, there is no single unique field identifier (for example, vehicleId), but all the fields of the object together form the primary key (this restriction is present in the database layer).

We do not have the flexibility to change this domain model to add a unique unique field identifier.

So my question is this: if I want to add a simple REST API on top of this domain object that provides simple functionality for CREATE, UPDATE, DELETE and GET Vehicles, then what is best for PATH endpoints for these methods?

Following the example above, if the domain model must have a unique vehicle identifier with a field identifier, then I can imagine the following endpoints:

 GET /vehicles/:vehicleId PUT /vehicles/:vehicleId DELETE /vehicles/:vehicleId 

I am not aware of a pattern that is similar to this for compound keys:

 GET /vehicles/:vehicleTypecolourtransmissionyearOfIssue GET /vehicles/CarRedAutomatic2008 

seems wrong.

Any advice on a good template for this use case is welcome.

thanks

+13
design rest api
source share
3 answers

In accordance with the general REST standards, each endpoint provides a resource, and the client can work with them using http verbs. In this example, your resource is a vehicle, and the client retrieves data from the server using GET. Ideally, each resource should be uniquely identified with a unique (single) key.

But your resource (car) does not have a unique unique key and cannot be changed in the system! In this case, you can still make a GET call with all the necessary parameters to identify the resource, like any other standard HTTP calls, for example

 GET /vehicles?type=Car&color=Red&transmission=Automatic&manufactureYear=2008 

The technology / platform used, if this allows you to create your own routes for your method, you can create your own route, similar to

 new route("/vehicles/{type}/{color}/{transmission}/{manufactureYear}") 

And call support

 GET /vehicles/Car/Red/Automatic/2008 

Good thing your uri is getting shorter. But on the other hand [1] For all methods / resources of this type you will have to create your own routes, and [2] this uri does not make much sense if you do not know about a specific method and route.

+7
source share

To be RESTful, you need to create a single unique identifier to grow your class.

 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; } } 

Then you can access it using HTTP: Get http: // mysite / vehicles / 3842 . However, you may not have access to an internal unique identifier, especially when sowing or updating the database. I encountered similar problems, and to use the REST verbs I will include an external identifier to facilitate people's access to people and external systems:

 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; } } 

Then the verb looks like this: HTTP: Get http: // mysite / vehicles / externalId / sedanbluemanual2015 . You do not need to parse the URI, since all this data should be in the body of the message, you just need to make sure that the line uniquely identifies the car.

 [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> } 
+1
source share

In the ASP.NET core, I usually represent the composite key as follows:

POST/vehicles/(car:red:automatic:2008)

or

POST/vehicles/(car|red|automatic|2008)

There are no problems in the structure, comparing them with the action parameters in the specified order.

 [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(); } 

Request example: PUT/vehicles/(Ford:Ranger:100% genuine:2000)

enter image description here

0
source share

All Articles