Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleHttp.fan
Code Block
using haystack
using web
using skyarcd
using util

**
** HTTP utilities
**
const class Http
{

  static Obj? postJson(Uri url, Str reqBody, Dict headers := Etc.emptyDict) {
    c := WebClient(url)
    if (RestExampleExt.cxLog.isDebug) {
      RestExampleExt.cxLog.debug("Posting JSON @ ${url} ${reqBody}...")
    }
    try {
      c.reqMethod = "POST"

      setHeaders(c, headers)
      c.reqHeaders[CONTENT_TYPE] = JSON_MIME_TYPE
      c.reqHeaders[CONTENT_LENGTH] = "$reqBody.size"
      c.writeReq.reqOut.print(reqBody).close
      c.readRes

      if (c.resCode != 200 && c.resCode != 202){
        if (c.resCode == 401 || c.resCode == 403) {
          throw IOErr("Not authorized")
        }
        throw IOErr("Bad HTTP response $c.resCode $c.resPhrase $c.resBuf.readAllStr")
      }

      return JsonInStream(c.resIn).readJson
    } catch (Err e) {
      RestExampleExt.cxLog.err("POST request failed", e)
      throw e
    } finally {
      c.close
    }
  }

  static Obj? getJson(Uri url, Dict headers := Etc.emptyDict) {
    c := WebClient(url)
    if (RestExampleExt.cxLog.isDebug) {
      RestExampleExt.cxLog.debug("Getting JSON from ${url}...")
    }
    
    try {
      c.reqMethod = "GET"
      setHeaders(c, headers)
      c.writeReq.readRes

      if (c.resCode != 200) {
        if (c.resCode == 401 || c.resCode == 403) {
          throw IOErr("Not authorized")
        }
        throw IOErr("Bad HTTP response $c.resCode $c.resPhrase")
      }

      return JsonInStream(c.resIn).readJson
    } catch (Err e) {
      RestExampleExt.cxLog.err("GET request failed", e)
      throw e
    } finally {
      c.close
    }
  }

  private static Void setHeaders(WebClient c, Dict headers := Etc.emptyDict) {
    headers.each |Obj? val, Str key| { 
      if (val != null) {
        c.reqHeaders.add(key, val.toStr)
      }
    }
  }

  **
  ** Zinc MIME type.
  **
  static const Str ZINC_MIME_TYPE := "text/zinc"

  **
  ** JSON MIME type.
  **
  static const Str JSON_MIME_TYPE := "application/json"

  **
  ** Hayson MIME type.
  **
  static const Str HAYSON_MIME_TYPE := "application/vnd.haystack+json"

  **
  ** Older Haystack JSON format.
  **
  static const Str V3_JSON_MIME_TYPE := "application/vnd.haystack+json;version=3"

  **
  ** Content type HTTP header
  **
  static const Str CONTENT_TYPE := "Content-Type"

  **
  ** Content length HTTP header
  **
  static const Str CONTENT_LENGTH := "Content-Length"
}
Code Block
using haystack
using web
using skyarcd
using util

**
** HTTP utilities
**
const class Http
{

  static Obj? postJson(Uri url, Str reqBody, Dict headers := Etc.emptyDict) {
    c := WebClient(url)
    if (RestExampleExt.cxLog.isDebug) {
      RestExampleExt.cxLog.debug("Posting JSON @ ${url} ${reqBody}...")
    }
    try {
      c.reqMethod = "POST"

      setHeaders(c, headers)
      c.reqHeaders[CONTENT_TYPE] = JSON_MIME_TYPE
      c.reqHeaders[CONTENT_LENGTH] = "$reqBody.size"
      c.writeReq.reqOut.print(reqBody).close
      c.readRes

      if (c.resCode != 200 && c.resCode != 202){
        if (c.resCode == 401 || c.resCode == 403) {
          throw IOErr("Not authorized")
        }
        throw IOErr("Bad HTTP response $c.resCode $c.resPhrase $c.resBuf.readAllStr")
      }

      return JsonInStream(c.resIn).readJson
    } catch (Err e) {
      RestExampleExt.cxLog.err("POST request failed", e)
      throw e
    } finally {
      c.close
    }
  }

  static Obj? getJson(Uri url, Dict headers := Etc.emptyDict) {
    c := WebClient(url)
    if (RestExampleExt.cxLog.isDebug) {
      RestExampleExt.cxLog.debug("Getting JSON from ${url}...")
    }
    
    try {
      c.reqMethod = "GET"
      setHeaders(c, headers)
      c.writeReq.readRes

      if (c.resCode != 200) {
        if (c.resCode == 401 || c.resCode == 403) {
          throw IOErr("Not authorized")
        }
        throw IOErr("Bad HTTP response $c.resCode $c.resPhrase")
      }

      return JsonInStream(c.resIn).readJson
    } catch (Err e) {
      RestExampleExt.cxLog.err("GET request failed", e)
      throw e
    } finally {
      c.close
    }
  }

  private static Void setHeaders(WebClient c, Dict headers := Etc.emptyDict) {
    headers.each |Obj? val, Str key| { 
      if (val != null) {
        c.reqHeaders.add(key, val.toStr)
      }
    }
  }

  **
  ** Zinc MIME type.
  **
  static const Str ZINC_MIME_TYPE := "text/zinc"

  **
  ** JSON MIME type.
  **
  static const Str JSON_MIME_TYPE := "application/json"

  **
  ** Hayson MIME type.
  **
  static const Str HAYSON_MIME_TYPE := "application/vnd.haystack+json"

  **
  ** Older Haystack JSON format.
  **
  static const Str V3_JSON_MIME_TYPE := "application/vnd.haystack+json;version=3"

  **
  ** Content type HTTP header
  **
  static const Str CONTENT_TYPE := "Content-Type"

  **
  ** Content length HTTP header
  **
  static const Str CONTENT_LENGTH := "Content-Length"
}

Getting JSON

Let's start from the GET function.

...