I have two entities that have a many-to-many relationship with each other. Namely a Machine and a Tool. A Tool can be inside the inventory of zero or multiple machines, therefore the many-to-many relations.
Now I need to query the Machines where a particular tool is inside them. At the moment I have a resource /machines/ where I can get a list of machines or /machines/{id} to get a particular machine. The first method already has an implementation to search for machines. Through the name, type and other attributes. But for this query I need to query in one way, namely: "Which Machines have this Tool inside of their inventory?"
How do you apply this in a meaningful Restful way making it clear for the client that they have two options to query Machines: (1) through attributes, and (2) through the tool inside the inventory? This implementation will not be shared, thus a client cannot expect to find machines that have a particular tool inside its inventory AND filter by name or type. It's one or the other.
Thus, when I offer an API that has the following resource(s)
- /machines?toolid=GUID
- /machines?name=SOME-NAME
- /machines?name=SOME=NAME&type=SOME-TYPE
It's logical to expect that query parameters can be combined, thus the combination of toolid and name is also a possibility. But that isn't the case.
How can I design the API in such a way that it is clear to the client that they have two options to search for machines and what the use cases are of the two query options?
@Update 22-09-22: I have let it sunk in further and came to the conclusion that on repository level I'm going to introduce two methods, thus there I'm already introducing a seperation:
interface IRepository {
function findBy(string $name = null, string $type = null): array;
function findByToolInInventory(string $toolId): array;
}
Is it then good practice to introduce a operation beside /machines that delivers the result from another query. For example: /machines/wheretoolininventory/{toolId} ?