I was programming against the Building Component Library from NREL, and ran into a few gotchas that I’d like to share to make the next person’s experience easier.

Required Request Headers

If you send an HTTP request with just the URL, you will be hit with a 500 status code, representing an internal server error.

After some trial and error, it seems the only required header is the Accept header. It did not seem to matter what was used, other than that it exists. The actual format sent back depends on the URL – XML and JSON are supported, with JSON being the default. So I’ve used an Accept header, with a value of application/json, since I prefer JSON to XML.

Other headers that weren’t required, but didn’t hurt to send along are the Host and Accept-Encoding.

Gzipped Response

For me, even without the Accept-Encoding header, the content is sent back in a compressed form, gzip.

So to properly read the response, you’ll need to uncompress. The response header Content-Encoding does properly indicate that the response is gzipped.

So here’s how that looks in C#. This is a sample method for looking up a BCL component or measure by UUID.

public string GetByUUID(string uuid)
{
    var client = new HttpClient();

    client.DefaultRequestHeaders.Host = "bcl.nrel.gov";
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
    HttpResponseMessage response = client.GetAsync("https://bcl.nrel.gov/api/search/?fq=uuid:" + uuid, HttpCompletionOption.ResponseContentRead).Result;

    if (response.StatusCode != HttpStatusCode.OK)
    {
        string message = $"Did not receive an OK back from bcl.nrel.gov HTTP request. Response items:\nStatus Code: {response.StatusCode}\nReason: {response.ReasonPhrase}\nHeaders: {response.Headers}";
        throw new HttpRequestException(message);
    }

    Stream responseStream;
    if (response.Content.Headers.TryGetValues("Content-Encoding", out IEnumerable<string> values) && values.Contains("gzip"))
    {
        // Uncompress gzip response
        responseStream = new GZipStream(response.Content.ReadAsStream(), CompressionMode.Decompress);
    }
    else
    {
        responseStream = response.Content.ReadAsStream();
    }

    StreamReader reader = new(responseStream, Encoding.UTF8);

    string allContents = reader.ReadToEnd();
    return allContents;
}