Why does EK9 reject a qualifier name on a REQUEST or CONTENT service parameter?

← Web Services · Ref: Q1325

EK9 service parameters bind to one HTTP source via :=:. Only PATH, QUERY and HEADER bindings take an extra qualifier name (the URI segment, query key or header name) so the runtime knows which value to extract. REQUEST and CONTENT bind to the whole request object or the whole request body respectively, so there is nothing to name. Adding a quoted qualifier to REQUEST or CONTENT triggers E07720 (SERVICE_HTTP_PARAM_QUALIFIER_NOT_ALLOWED) at the EXPLICIT_TYPE_SYMBOL_DEFINITION phase.

CORRECT

  -> request as HTTPRequest :=: REQUEST
  -> body as String :=: CONTENT

INCORRECT

  -> request as HTTPRequest :=: REQUEST "x"   // E07720
  -> body as String :=: CONTENT "payload"      // E07720

The fix is simply to delete the qualifier name. Contrast with E07710 (missing qualifier), which fires when PATH, QUERY or HEADER lacks the name they DO require.

See Q658 for path parameter binding. See Q868 for service parameter types.

Example

defines module qa.webdeep.service.param.qualifier

  defines constant

    JSON_RESPONSE <- "application/json"

  defines service

    <?-
      Service showing the bindings that do NOT take a qualifier name.
      REQUEST binds the whole request, CONTENT binds the whole body.
    -?>
    EchoService :/echo open

      // REQUEST binds the full HTTPRequest - no qualifier name allowed.
      describe() as GET for :/details
        -> request as HTTPRequest :=: REQUEST
        <- response as HTTPResponse: (incoming: request.content()) with trait HTTPResponse
          override content()
            <- rtn as String: `{"request": "${incoming}"}`
          override status() as pure
            <- rtn as Integer: 200
          override contentType() as pure
            <- rtn as String: JSON_RESPONSE
          override cacheControl() as pure
            <- rtn as String: "no-cache"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

      // CONTENT binds the whole request body - no qualifier name allowed.
      operator += :/
        -> body as String :=: CONTENT
        <- response as HTTPResponse: (received: body) with trait HTTPResponse
          override content()
            <- rtn as String: `{"received": "${received}"}`
          override status() as pure
            <- rtn as Integer: 201
          override contentType() as pure
            <- rtn as String: JSON_RESPONSE
          override cacheControl() as pure
            <- rtn as String: "no-store"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

  defines application

    EchoApp
      register EchoService()

  defines program

    QualifierDemo()
      stdout <- Stdout()
      stdout.println("No qualifier name: :=: REQUEST and :=: CONTENT")
      stdout.println("Qualifier name required: :=: PATH, :=: QUERY, :=: HEADER")

Common mistakes

E07720 — REQUEST binds the whole HTTP request and CONTENT binds the whole request body, so neither accepts a qualifier name. The quoted qualifier (only valid for PATH, QUERY and HEADER, which need to name the segment/key/header) is rejected as E07720. Remove the qualifier so the binding reads ':=: REQUEST'. See ek9 -h E07720 for details.

Incorrect:

        -> request as HTTPRequest :=: REQUEST "not-required"

Correct:

        -> request as HTTPRequest :=: REQUEST
Other ways to ask this
  • What triggers E07720 SERVICE_HTTP_PARAM_QUALIFIER_NOT_ALLOWED?
  • Why can't I add a name after :=: REQUEST or :=: CONTENT?
  • Which HTTP service bindings take a qualifier name and which do not?

Coming from another language?

Java Spring: @RequestBody and the HttpServletRequest argument take no name, while @RequestParam/@PathVariable/@RequestHeader take a key string; mixing them up is silently accepted or fails at runtime. ASP.NET / Flask / Go behave similarly with no compile-time guard. EK9 enforces the distinction at compile time: REQUEST and CONTENT must have no qualifier, PATH/QUERY/HEADER must have one.

Keywords: service, http, binding, parameter, E07720, qualifier, QUERY, CONTENT, REQUEST, HEADER