Search code examples
restjson-api

Can attribute values be used as identifiers in REST urls


I have a resource with identifier id and attribute name - name is unique for each of the resource instances.

In order to get, patch and delete the resource, is it REST and JSON:API compliant to use the name field as the identifier in the URL?

e.g. to get resource by name, is the following URL compliant:

GET /resource/{name}

or is the following to be used / preferable:

GET /resource?name={name}

to patch or delete by name, can one use:

PATCH /resource/{name}

DELETE /resource/{name}


Solution

  • In order to get, patch and delete the resource, is it REST and JSON:API compliant to use the name field as the identifier in the URL?

    Yes. REST doesn't care what spellings you use for your resource identifiers, as long as those identifiers are consistent with the production rules defined in RFC 3986.

    That might mean that you need to encode the attribute name - for instance, replacing some reserved characters with the equivalent hex representation.

    GET /resource/{name}
    PATCH /resource/{name}
    DELETE /resource/{name}
    

    That's fine

    GET /resource?name={name}
    PATCH /resource?name={name}
    DELETE /resource?name={name}
    

    Also fine. It's a trade off; encoding information into path segments mean that you can take advantage of relative references and dot segments. Using key value pairs in the query part means that you can use HTML forms to allow the client to specify a name.

    GET /resource?name={name}
    DELETE /resource/{name}
    

    Technically, you can play mix-and-match, but general purpose caches aren't going to know that you are being clever, and will not invalidate cached entries when the URI are different.

    This answer fully ignores that it should be also compliant with JSON API specification.

    That's fair comment.

    The JSON:API specification does not introduce any significant constraints on the spelling conventions used in URI.

    It does, however, expect that identifiers can be extended with application/x-www-form-urlencoded key value pairs to support sorting, pagination, filtering and so on.

    (Warning: please be careful when reading the JSON:API specification, as the use of "resource" there does not align particularly well with the meaning of resource in the context of REST.)

    The JSON:API recommendations for URI design encourage the use of path segments for referencing "resources" as though they were individually addressable hierarchically organized elements of a single "reference document".

    Furthermore, the recommendations call for using a specific hierarchical spelling, using the type and identifier of a resource to compute its URI

    /{type}/{id}
    

    In other words, GET /resource/{name} should return a application/vnd.api+json representation with a type member resource and an id member name. The specification applies the additional constraint that this (type, id) combination must be unique.

    If name is just a property, and not actually the identifier, then JSON:API recommends that you treat it as a filter

    /resource?filter%5Bname%5D=abcde
    

    And the representation returned would include a self link relation that tracks with the identifier in the usual way.

    (Note: [] are RFC 3986 gen-delims, and therefore require hex encoding in the query part. At least one of the JSON:API examples includes a note explain this, but filtering example in recommendations does not emphasize this. In practice? you might get away with using them unencoded -- the use of square brackets in the query part was a common non-compliant convention).