Part of the IRI requests and requests is up to you. The path is for hierarchical data, such as api/version/module/collection/item/property , the query is for non-hierarchical data, such as ?display-fields="id,name,etc..." or ?search="brown teddy bear"&offset=125&count=25 etc.
What you should keep in mind is that you work with resources, not operations. Thus, IRIs are resource identifiers, such as DELETE /something , and not operation identifiers, such as POST /something/delete . You do not have to follow any IRI structure, so for example, you can just use POST /dashuif328rgfiwa . The server would understand, but it would be more difficult to write a router for such an IRI, so we use good IRI.
It is important that one IRI always belongs to only one resource. Thus, you cannot read cat properties using GET /cats/123 and write dog properties using PUT /cats/123 . As a rule, ppl does not understand that one resource can have several IRIs, therefore, for example, /cats/123 , /cats/name:kitty , /users/123/cats/kitty , cats/123?fields="id,name" etc ... may belong to the same resource. Or, if you want to give IRI something (a live cat, not a document that describes it), you can use /cats/123#thing or /users/123#kitty , etc ... Usually you do this is in RDF docs.
What should be the structure of a URI if I want to get a contact using an identifier or alias?
It can be /api/contacts/name:{name} for example /api/contacts/name:John , since it is clearly hierarchical. Or you can check if the parameter contains numeric or string in /api/contacts/{param} .
You can also use the query, but I do not recommend doing this. For example, the following IRI can have two separate values: /api/contacts?name="John" . Do you want to list each contact with the name John or want to get an exact contact. Therefore, you need to make some conventions about these types of requests in the router of your server-side application.