Why does a QUERY/HEADER/PATH service parameter need a name qualifier in EK9?
← Web Services · Ref: Q1324
An EK9 service parameter bound with QUERY, HEADER, or PATH must declare the wire name it binds to as a String qualifier. The method-parameter identifier is your local variable name; the qualifier string is the actual HTTP query key, header name, or path segment name. Without the qualifier the compiler cannot know which request value to extract, so it raises E07710.
Fix: add the qualifier string. For a query string ?q=...:
-> term as String :=: QUERY "q"
For an HTTP header:
-> token as String :=: HEADER "Authorization"
For a named path segment, the qualifier follows the :/{seg} variable in the URI.
The REQUEST qualifier is the exception - it binds the whole HTTPRequest and must NOT carry a name (a name there triggers E07720).
See Q945 for HTTP verbs and URI params. See Q658 for path parameter binding. See Q846 for valid service parameter types.
Example
defines module qa.webdeep.service.param.qualifier defines constant JSON_TYPE <- "application/json" defines service <?- Service demonstrating named QUERY and HEADER parameter binding. Each parameter declares the wire name it reads from, so the compiler can extract the right request value (no E07710). -?> SearchService :/search open // GET /search/results?q=... with an Authorization header find() as GET for :/results -> term as String :=: QUERY "q" token as String :=: HEADER "Authorization" <- response as HTTPResponse: (capturedTerm: term, capturedToken: token) with trait of HTTPResponse override content() <- rtn as String: `{"query": "${capturedTerm}", "authorized": ${capturedToken?}}` override status() as pure <- rtn as Integer: 200 override contentType() as pure <- rtn as String: JSON_TYPE override cacheControl() as pure <- rtn as String: "no-cache" override contentLanguage() as pure <- rtn as String: "en" default operator ? defines application SearchApp register SearchService() defines program ServiceParamQualifierDemo() stdout <- Stdout() stdout.println("Named service parameter binding:") stdout.println(" GET /search/results?q=... -> QUERY \"q\" binds to term") stdout.println(" Header Authorization -> HEADER \"Authorization\" binds to token")
Common mistakes
E07710 — A QUERY (or HEADER or PATH) binding must state the wire name it reads from. Without it, the compiler cannot tell which query key, header, or path segment to extract, so it raises E07710. Add the name qualifier - 'QUERY "q"' binds the ?q= query string to the 'term' parameter. (Only REQUEST takes no name.) See ek9 -h E07710 for details.
Incorrect:
-> term as String :=: QUERY
Correct:
-> term as String :=: QUERY "q"
Other ways to ask this
- What triggers E07710 SERVICE_HTTP_PARAM_NEEDS_QUALIFIER?
- Why must I name the QUERY string for a service parameter?
- How do I bind a query string parameter to a method argument in EK9?
Coming from another language?
Java Spring: @RequestParam("q"), @RequestHeader("Authorization"), @PathVariable("id") - the wire name is an annotation argument, omittable so it defaults to the Java parameter name (silent at compile time, surprises at runtime). Python Flask, Go gorilla/mux: the wire key is a plain string in code, never checked. EK9: the wire name is a mandatory part of the binding syntax, enforced at compile time (E07710), so a parameter can never silently bind to the wrong request value.
Keywords: HEADER, E07710, name, parameter, QUERY, qualifier, http, PATH, service, REST, binding