CodamAIDocs
Topicdone

The render request

What a render request contains: template key, format, mode, reference, language, time zone, PDF profile, payload and attachments. Embedded as a Java call, standalone through POST /crms/render, plus checking without rendering.

Variants
embedded (ReportRenderPort)REST (POST /crms/render)check only (validate)output into a stream (renderTo)

What this is about

A render request tells CRMS which document you want: from which template, in which format, with which data. CRMS answers in the same call with the finished document.

You can ask CRMS in two ways. Embedded, CRMS runs inside your application, and you call a Java interface. Standalone, CRMS runs as a separate service, and you send the request over HTTP. The content of the request is the same in both cases. How the two operating modes come about is described in Embedded or standalone.

A request, field by field

Request
POST /crms/render
Content-Type: application/json
Authorization: Bearer <token>
{
  "template": "audit-report",      ← template key, required
  "format": "PDF",                 ← format, required
  "mode": "FINAL",                 ← PREVIEW, FINAL or TRANSIENT, required
  "reference": "audit-4711",       ← your reference, required for FINAL
  "locale": "de-DE",               ← language, optional
  "timeZone": "Europe/Berlin",     ← time zone, optional
  "pdfProfile": "PDF_A_3A",        ← only for PDF, optional
  "data": {                        ← the payload
    "customer": { "name": "ACME" }
  },
  "attachments": []                ← pictures of this request, optional
}
Response
HTTP 200
Content-Type: application/pdf
Content-Disposition: inline; filename="audit-report.pdf"
Crms-Template-Key: audit-report
Crms-Template-Scope: TENANT
Crms-Template-Variant: de
Crms-Template-Revision: 3f0c…
Crms-Template-Revision-Hash: sha-256:9a1e…
Crms-Document-Revision: 7b42…      ← only for FINAL
X-Content-Type-Options: nosniff

%PDF-1.7 …
FieldMeaningRequiredIf it is missing
templatethe template key: the fixed name of a template, kebab-case, for example audit-report, at most 128 charactersyesrequired
formatthe output format: HTML, PDF, DOCX, XLSX, CSV, ODS. Case does not matteryesrequired
modePREVIEW, FINAL or TRANSIENT, see Preview, final, transient. Case does not matteryesrequired
referencethe reference: your own name for the thing the document belongs to, for example the id of an audit. CRMS does not read it, it stores final documents under it. 1 to 255 characters, no blanks at the edges and no control charactersonly for FINALrequired for FINAL
localethe language as a language tag, for example de or de-CHnoCRMS uses the caller’s language, see Language and time zone
timeZonethe time zone, for example Europe/Berlinnothe container’s time zone (TZ), otherwise UTC
pdfProfileNONE, PDF_A_3A, PDF_UA or PDF_A_3A_UA, only with format: PDFnothe installation’s default profile, see Output types and formats
datathe payload: the data the template inserts. A JSON objectnoempty payload
attachmentspictures that belong to this request only, see Pictures and SVGnono attachments

The response headers tell you exactly what the document was made from: which template, from which scope (the level on which the template applies: system, tenant or user), which language variant, which revision (an approved, unchangeable version of the template) and its hash. How CRMS finds the template is described in How CRMS finds the template.

How CRMS reads the request

Over REST, CRMS reads the JSON body field by field. Strict rules apply:

  • Unknown fields are refused (not-allowed). A misspelt name like refrence shows up at once instead of silently doing nothing.
  • The wrong JSON type is invalid. CRMS converts nothing: 42 is not a template key.
  • null counts like a missing field.
  • Decimal numbers in data are read as exact decimals, not as floating-point numbers. An amount keeps exactly its digits.
  • pdfProfile with a format other than PDF is not-allowed.
  • All broken fields come in one answer: 422 validation-failed with violations.

The body is bounded before it is read. The limit follows from the payload limit, the attachment limit and some room for the other fields. If it is larger, CRMS answers 422 payload-rejected with the violation payload-too-large. The body may come compressed with Content-Encoding: gzip. The limit then applies to the unpacked bytes. Other encodings are 415 content-encoding-unsupported.

The stations before rendering

Before CRMS renders, it checks the request in this order. Each station can end the request.

From the request to rendering
  1. CRMS
    Format
    Does the installation offer the format, and is a formatter for it installed?
    ↳ no 422 format-not-offered|<format>
  2. CRMS
    Mode
    Is FINAL or TRANSIENT switched on in this installation?
    ↳ no 409 document-revisions-disabled or transient-documents-disabled
  3. CRMS
    Attachments
    If there are attachments, is it not FINAL, and can the format draw them?
    ↳ no 422 attachments-not-for-final or attachments-not-for-format|<format>
  4. CIAS
    Caller
    Is the caller signed in?
    ↳ no 401 crms-authentication-required
  5. CRMS
    Template
    Is there a template with this key that the caller reaches?
    ↳ no 404 template-not-found
  6. CRMS
    Scope for TRANSIENT
    For TRANSIENT, does the revision come from the SYSTEM scope?
    ↳ no 422 transient-requires-system-template
  7. CRMS
    Output type
    Does the format fit the template's output type?
    ↳ no 422 format-not-for-template|<format>|<output type>
  8. CRMS
    Payload and attachments
    Does the payload keep the rules, and are the attachments fine?
    ↳ no 422 payload-rejected with all violations
  9. CRMS renders and returns the document

Only after the last station does the real work start: run the template, produce the format, and for FINAL seal and store. What can go wrong there is described in Execution and limits. All errors come back in one shape, see Errors and message keys.

The ways to send a request

Embedded, REST, check only, stream

When: CRMS runs inside your application

You get ReportRenderPort injected and call render(request). There are short forms for the three modes: RenderRequest.preview(key, format, data), RenderRequest.transientDocument(key, format, data) and RenderRequest.finalDocument(key, format, reference, data). Language, time zone and PDF profile are left to CRMS. You get a RenderedDocument with format, bytes, origin and, for FINAL, the document revision. Errors come as CrmsException with a message key, a rejected payload as PayloadRejectedException with the violations.

Result: the document as bytes in the same call

When: CRMS runs as a separate service, or a frontend calls CRMS directly

POST /crms/render with the JSON above and a token. The answer is the document's bytes with Content-Type and the Crms-Template-* headers. An application usually calls CRMS through crms-client, which offers the same interface as embedded, see crms-client.

Result: the document as HTTP response

When: you want to know whether a request would render, without producing a document

POST /crms/render/validate with the same body, embedded validate(request). CRMS goes through all stations and runs the template once as a dry run, but produces no format. The answer is {"violations": [...]}. Empty means: would render. Payload violations and errors in the template (in field template) are in the list. If another station fails, for example the format, the error comes as it does when rendering.

Result: list of violations, empty or not

When: embedded, for very large documents

renderTo(request, outputStream) writes the bytes straight into your stream and only returns format, size and origin. For FINAL, CRMS still buffers the whole document, because it is stored first and only then goes to you.

Result: bytes in the stream, description as return value

An embedded call from the hub looks like this. It renders a transient copy without a reference and without its own time zone:

RenderedDocument document = renderer.render(new RenderRequest(
    new TemplateKey("arc42"),       // template key
    Locale.forLanguageTag("de"),    // language, or null
    null,                           // time zone: TZ, then UTC
    OutputFormat.PDF,
    null,                           // PDF profile: the installation's default
    RenderMode.TRANSIENT,
    null,                           // reference: only for FINAL
    data));

What an installation offers

GET /crms/capabilities tells you what you can request: the offered formats, the default PDF profile, the admitted scopes, the installation’s languages, whether final documents are stored (documentRevisions), whether transient ones are allowed (transientDocuments) and the limits. Embedded, CapabilitiesPort returns the same. The values come from the configuration and do not change while running.

Request
GET /crms/capabilities
What the installation offers
{
  "formats": ["HTML", "PDF", "DOCX"],
  "defaultPdfProfile": "PDF_A_3A",
  "scopes": ["TENANT", "SYSTEM"],
  "locales": ["de", "en"],
  "documentRevisions": true,
  "transientDocuments": false,
  "limits": {
    "timeout": "PT30S",
    "maxOutputBytes": 52428800,
    "maxPayloadBytes": 5242880,
    "maxAttachmentCount": 200,
    "maxAttachmentBytes": 52428800
  }
}

Pitfalls

Next

Search