Versions Compared

Key

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

...

In fan/http  you can find the Http.fan  utility class that contains two functions that allow getting and posting JSON to a REST endpoint.

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"
}

Getting JSON

Let's start from the GET function.

...

A schedule point is a record with specific tags. You can find some documentation here: http://20.49.58.255:8085/ui/#fc292f34e24e, see scheduleExt.

The most important tag of a schedule record is the scheduleGrid , because it contains the schedule events and rules. An example of schedule grid is:

Expand
Code Block
date,dis,end,start,val
"2025-01-01","New Year's Day",00:00:00,00:00:00,"off"
"2025-01-11","Municipal holiday",00:00:00,00:00:00,"off"
"2025-03-04","Carnival",00:00:00,00:00:00,"off"
"2025-04-18","Good Friday",00:00:00,00:00:00,"off"
"2025-04-20","Easter Sunday",00:00:00,00:00:00,"off"
"2025-04-25","Liberty Day",00:00:00,00:00:00,"off"
"2025-05-01","Labor Day",00:00:00,00:00:00,"off"
"2025-06-08","Corpus Christi",00:00:00,00:00:00,"off"
"2025-06-10","Portugal Day",00:00:00,00:00:00,"off"
"2025-08-15","Assumption Day",00:00:00,00:00:00,"off"
"2025-10-05","Republic Day",00:00:00,00:00:00,"off"
"2025-11-01","All Saints' Day",00:00:00,00:00:00,"off"
"2025-12-01","Independence Day",00:00:00,00:00:00,"off"
"2025-12-08","Immaculate Conception Day",00:00:00,00:00:00,"off"
"2025-12-25","Christmas",00:00:00,00:00:00,"off"

So each event has a date and timerange, a description, and a value. val  is the value that will be written to the points bound to this scheduler, and can be of any type (string, number, boolean).

...