NationalMuseumAustralia / Collection-API

The public web API of the National Museum of Australia
10 stars 0 forks source link

Developer error messages #37

Closed staplegun closed 6 years ago

staplegun commented 6 years ago

Include a JSON body in API responses describing API errors. See: http://jsonapi.org/format/#errors

staplegun commented 6 years ago

Possible bad requests and their current status:

ID Bad... Example Response Status
1 Endpoint stub /bad 404 no body error message OK, but should add message
2 Endpoint with path /bad/more 404 with body error message OK
3 Flag /object?bad Server error Needs fixing
4 Parameter empty /object?bad= 404 with body results message Should return error
5 Parameter value /object?bad=99 404 with body error message OK

Requests 3 and 4 are incorrect and need fixing. Request 1 could add a message to be more helpful to developers.

Conal-Tuohy commented 6 years ago
<p:choose>
    ...
    <p:when test=" matches($relative-uri, '[^/]+/[^?]+') or contains($relative-uri, '?')">
        <!-- the "format" parameter can be used to specify a content type (overriding Accept header) -->
        <p:variable name="format" select="/c:param-set/c:param[@name='format']/@value"/>
        <!-- Translate the API request into a request to Solr -->
        <p:xslt>
            <p:with-param name="relative-uri" select="$relative-uri"/>
            <p:input port="stylesheet">
                <p:document href="../xslt/api-request-to-solr-request.xsl"/>
            </p:input>
        </p:xslt>
        <!-- Make the HTTP request to Solr, extract response data from Solr's response and reformat it as an API response -->
        <p:http-request/>
        <nma:format-result>
            <p:with-option name="accept" select="$accept"/>
            <p:with-option name="format" select="$format"/>
            <p:with-option name="relative-uri" select="$relative-uri"/>
        </nma:format-result>
    </p:when>
    <!-- unknown request URI -->
    <p:otherwise>
        <z:not-found/>
    </p:otherwise>
</p:choose>

This seems doable: move the p:when above down into the XSLT, and drop the p:otherwise. That XSLT would therefore need to handle bad requests that it can't translate into Solr requests. At the moment, it returns a c:request document always (that gets passed to the p:http-request step that follows it). Instead, in the case of syntactically invalid request URIs, it could directly produce a "Solr-response"-type document saying "error in URI", and we could wrap the p:http-request step in a p:choose/p:when so it only happens if the document is in fact an http request specification. Then the nma-format-result sub-pipeline could format the result document (which would have come either from Solr or direct from the request-parser).

Conal-Tuohy commented 6 years ago

I now have a try/catch around the parsing of URI parameters. If the parsing succeeds, then the parsed parameters are converted by an XSLT into an http request to Solr, and the request is executed, with the result (including any errors) formatted as either JSON-API or JSON-LD by the solr-xml-to-json.xsl stylesheet. If the URI parameter parsing fails (e.g. on /object?foo), an error message is produced in Solr format (i.e. as if it had been produced by Solr), and that error response is then converted to the appropriate flavour of JSON with the same solr-xml-to-json.xsl stylesheet.

Conal-Tuohy commented 6 years ago

I also changed the JSON-LD response to a request which has no search params but which Solr has returned no results for. Such a request now returns a JSON-LD graph describing it as a 404 error.

Conal-Tuohy commented 6 years ago

There is one minor caveat; a request which specifies a bad (i.e. unknown to Solr) parameter with no value will not itself produce an error (/object?title=dog&foo=). This I think is a necessary corollary of the approach of making it Solr's responsibility for validating that parameters conform to the Solr metadata schema. We have been filtering out any URI parameters which have no value (on the basis that such empty parameters are not generally regarded as significant by web developers) before they are passed to Solr. If we didn't do that, then Solr would treat them as an explicit search for a blank value. But if they are filtered out, then Solr never gets a chance to complain that they violate its schema. I think that tradeoff is OK.