0

Let's say I have a collection of cars, all identified by VIN, such that cars/xyz123 will return the car with that VIN. Furthermore, I can get subsystems (children) by using URIs similar to cars/xyz123/drivetrain and cars/xyz123/chassis.

Given a situation where I have a car without a VIN but with a distinct nickname, what would be the most appropriate way of constructing the path to that resource? I know the typical approach would be something like cars?nickname=herbie, but I'm not super happy with the implications of accessing child resources with something like cars/drivetrain?nickname=herbie. I prefer the idea of something like cars/bynickname/herbie/drivetrain.

I feel like my preferred approach is pragmatic and acceptable, but I would really appreciate some feedback. Thanks for any insight you've got!

2 Answers 2

1

You're starting from a wrong assumption. If you want to access resources by ID, every resource should have an ID. The VIN isn't necessarily the right choice for an ID attribute, you will most likely need to maintain an internal ID by which you can reference any car in your collection.

You can query your collection using VIN as a query key, but if you want to drill down your client should first get list of cars matching the query, and only proceed when it got exactly one matching result.

One possible alternative would be to use a "details" query parameter which doesn't control the selection of cars but which detail attributes are included, so a query like cars?nickname=herbie& details=drivetrain could be used to get all cars with that nickname, filling in their drivetrain attribute. REST purists will probably disagree with this option :-)

1
  • Thanks! FYI, the "car" example is used to hide proprietary stuff I'm doing. My API abstracts existing data across sources that will eventually have internal IDs, but often does not. We are in the process of consolidating this data. The result is that we want to build our API so that the path to the resource IS structured with an internal identifier that will someday exist, but still allow us to retrieve a resource in other ways in the meantime. I'll either absorb a child into the parent, or otherwise use the HATEOAS approach of linking to related resources so all resources have IDs.
    – Cork
    Commented Oct 26, 2021 at 14:18
1

This all depends on how you view the semantics of an identifier for a vehicle. If the URL /cars/:id should interpret the Id segment as a Vehicle Identification Number, then certainly "herbie" is an invalid value. If the REST service views the :id segment as a general purpose identifier, you could have /cars/herbie and /cars/xyz123 as long as the resource returned for /cars/herbie is always the same resource.

Supporting VINs and nicknames as part of the :id segment presents a challenge for the server application, since it would need to recognize the format of a VIN versus a nickname, but that isn't a concern for the client of your REST service. The client just needs to deal with the :id, without needing to care about the semantics of a VIN or nickname.

If more than one vehicle can be nicknamed "herbie" then this pattern breaks down. You will either need to know the VIN for "herbie" or the VIN becomes an attribute of the vehicle, and not an identifier. At that point Hans-Martin Mosner's answer would be best, and your service should expose a system-generated identifer that your REST clients can use, like a UUID or number.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.