public void serveDescription(RestServiceRequest rsr) {
    rsr.startDoc();

    if (rsr.getResponseContentType() == ResponseType.HTML)
      rsr.write("<h1>Operation: ").write(getRelativeUrl()).write("</h1>");

    rsr.datawriter
        .object()
        .key("name")
        .value(getRelativeUrl())
        .key("description")
        .value(description)
        .key("url")
        .value(RestServices.getAbsoluteUrl(getRelativeUrl()))
        .key("arguments")
        .value(
            hasArgument ? JSONSchemaBuilder.build(Utils.getFirstArgumentType(microflowname)) : null)
        .key("accepts_binary_data")
        .value(isFileSource)
        .key("result")
        .value(
            isFileTarget
                ? RestServices.CONTENTTYPE_OCTET + " stream"
                : JSONSchemaBuilder.build(Core.getReturnType(microflowname)))
        .endObject();

    rsr.endDoc();
  }
  private void consistencyCheck() throws CoreException {
    String secError = ConsistencyChecker.checkAccessRole(this.roleOrMicroflow);
    if (secError != null)
      throw new IllegalArgumentException(
          "Cannot publish microflow " + microflowname + ": " + secError);

    int argCount = Utils.getArgumentTypes(microflowname).size();

    if (argCount > 1)
      throw new IllegalArgumentException(
          "Cannot publish microflow "
              + microflowname
              + ", it should exist and have exactly zero or one argument");

    hasArgument = argCount == 1;

    List<String> pathParams = new UriTemplate(relativeUrl).getTemplateVariables();
    if (pathParams.size() > 0 && !hasArgument) {
      throw new IllegalArgumentException(
          "Cannot publish microflow "
              + microflowname
              + " with path '"
              + relativeUrl
              + ", the microflow should have a single input argument object with at least attributes "
              + pathParams);
    }

    if (hasArgument) {
      IDataType argtype = Utils.getFirstArgumentType(microflowname);
      if (!argtype.isMendixObject())
        throw new IllegalArgumentException(
            "Cannot publish microflow "
                + microflowname
                + ", it should have a single object as input argument");
      this.argType = argtype.getObjectType();
      this.argName = Utils.getArgumentTypes(microflowname).keySet().iterator().next();
      isFileSource = Core.isSubClassOf(FileDocument.entityName, argType);

      IMetaObject metaObject = Core.getMetaObject(argType);
      if (metaObject.isPersistable() && !isFileSource)
        throw new IllegalArgumentException(
            "Cannot publish microflow "
                + microflowname
                + ", it should have a transient object of filedocument as input argument");

      Set<String> metaPrimitiveNames = Sets.newHashSet();
      for (IMetaPrimitive prim : metaObject.getMetaPrimitives()) {
        metaPrimitiveNames.add(prim.getName().toLowerCase());
      }
      for (String pathParam : pathParams) {
        if (!metaPrimitiveNames.contains(pathParam.toLowerCase()))
          throw new IllegalArgumentException(
              "Cannot publish microflow "
                  + microflowname
                  + ", its input argument should have an attribute with name '"
                  + pathParam
                  + "', as required by the template path");
      }
    }

    if (httpMethod == null) {
      throw new IllegalArgumentException(
          "Cannot publish microflow " + microflowname + ", it has no HTTP method defined.");
    }

    IDataType returnTypeFromMF = Core.getReturnType(microflowname);

    if (returnTypeFromMF.isMendixObject() || returnTypeFromMF.isList()) {
      this.returnType = returnTypeFromMF.getObjectType();
      isFileTarget = Core.isSubClassOf(FileDocument.entityName, this.returnType);

      if (Core.getMetaObject(this.returnType).isPersistable() && !isFileTarget)
        throw new IllegalArgumentException(
            "Cannot publish microflow "
                + microflowname
                + ", its return type should be a non-persistable object or a file document");
    } else isReturnTypePrimitive = true;
  }