Define spec type in CronJob inputs


#1

I am defining a CronJob for an API that takes a spec type as an argument. My base type with the API looks something like this:

remix type Statistic {
    refreshCount: function(spec: !StatisticSpec) js server
}

Where StatisticSpec looks something like this:

type StatisticSpec mixes Spec {
    startDays: int
    categories: [string]
    metrics: json
}

and my CronJob instance looks like this:

{
  "id" : "trigger-refreshCount",
  "action" : {
    "actionName" : "refreshCount",
    "typeName" : "Statistic"
  },
  "inputs" : {
    "spec": {
      "startDays": 4,
      "categories": ["XX","YY"],
      "metrics": {
        "metric1": "string1",
        "metric2": "string2",
        "metric3": "string3"
      }
    }
  },
  "scheduleDef" : {
    "cronExpression" : "0 0 8 * * ?",
    "skipOverdue" : false
  }
}

When the CronJob runs, I see the following error in the CronQueue errors:
Unable to coerce json value of Statistic.refreshCount#spec to StatisticSpec

I’ve tried updating my Cron definition to explicitly cast the spec.metrics field into a Json type, as the StatisticSpec is expecting:

 "inputs" : {
    "spec": {
      "startDays": 4,
      "categories": ["XX","YY"],
      "metrics": {
        "typeRef": { "typeName": "Json" },
        "metric1": "string1",
        "metric2": "string2",
        "metric3": "string3"
      }
    }
  }

but got the same error.

Any recommendations?


#2

You might try including the Type in the spec obj:

    "inputs" : {
        "spec" : {
          "type" : {
            "name" : "StatisticSpec"
          },
          "startDays": 4,
          "categories": ["XX","YY"],
          "metrics": {
            "metric1": "string1",
            "metric2": "string2",
            "metric3": "string3"
          }
        }
      }

#3

i would recommend to never have a field defined as json, instead do: metrics: [string] (or even better, metrics: [Metric])


#4

This worked on provision (but not in the static console), thanks @seth.horrigan!

For future reference, this type coercion will only work in the static console via CronJob.create, .merge, etc. by first making an instance of the desired type (StatisticSpec), otherwise the above code will be interpreted as JSON (you’ll see something like inputs: { type: 'json', spec: { ... }} in the details on CronJob.fetch).
ex for static console:

"inputs" : {
        "spec" : {
          "type" : StatisticSpec.make({
             "startDays": 4,
             "categories": ["XX","YY"],
             "metrics": {
               "metric1": "string1",
               "metric2": "string2",
               "metric3": "string3"
             }
          })
      }