Why does EK9 reject some operators inside a service definition?

← Web Services · Ref: Q1322

An EK9 service maps operators to HTTP verbs, so only the operators that have a clear CRUD meaning are permitted. The supported set is +, +=, -, -=, :^:, :~: and ?. Using any other operator (for example * or /) inside a service raises E07670 because there is no HTTP verb to map it to.

The semantic mapping is: += and + create (POST), -= and - remove (DELETE), :^: replaces (PUT), :~: merges (PATCH), and ? checks whether the service is set. Arithmetic operators like * have no place at the HTTP boundary.

Fix: keep the service surface limited to the supported operators, and move any computational behaviour (such as multiplication) into a plain helper class or function that the service handler calls.

See Q200 for CRUD operator mapping. See Q660 for path parameters with operators.

Example

defines module qa.web.unsupported.operator

  defines service

    //CORRECT: only the supported, HTTP-mappable operators appear here.
    //Any arithmetic (such as multiplication) lives in a helper, not the service.
    Items :/items open

      // GET /items — list all items
      listAll() :/
        <- response as HTTPResponse: () with trait HTTPResponse
          override content()
            <- rtn as String: `["item1", "item2"]`
          override status() as pure
            <- rtn as Integer: 200
          override contentType() as pure
            <- rtn as String: "application/json"
          override cacheControl() as pure
            <- rtn as String: "no-cache"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

      // POST /items — add new item (supported operator, maps to create)
      operator += :/
        -> content as String :=: CONTENT
        <- response as HTTPResponse: () with trait HTTPResponse
          override content()
            <- rtn as String: `{"created": true}`
          override status() as pure
            <- rtn as Integer: 201
          override contentType() as pure
            <- rtn as String: "application/json"
          override cacheControl() as pure
            <- rtn as String: "no-store"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

  defines class

    //Arithmetic belongs in a plain helper, never in the service surface.
    Calculator
      multiply() as pure
        ->
          a as Integer
          b as Integer
        <-
          rtn as Integer: a * b

  defines application

    ItemsApp
      register Items()

  defines program

    UnsupportedServiceOperatorDemo()
      stdout <- Stdout()
      calc <- Calculator()
      stdout.println("Service uses only supported operators: +, +=, -, -=, :^:, :~:, ?")
      stdout.println(`Arithmetic stays in a helper: 6 * 7 = ${calc.multiply(6, 7)}`)

Common mistakes

E07670 — The * operator has no HTTP-verb meaning, so it cannot appear inside a service and triggers E07670. Only +, +=, -, -=, :^:, :~: and ? are supported because each maps to a CRUD HTTP verb. Use a supported operator (for example += for POST) for the endpoint and move any arithmetic into a helper class. See ek9 -h E07670 for details.

Incorrect:

operator * :/{id}
  -> id as String
  <- response as HTTPResponse: ...

Correct:

      operator += :/
        -> content as String :=: CONTENT
        <- response as HTTPResponse: () with trait HTTPResponse
Other ways to ask this
  • What triggers E07670 unsupported service operator?
  • Which operators are allowed inside an EK9 service?
  • Why can't I use operator * in an EK9 REST service?

Coming from another language?

Java: Spring/JAX-RS use method annotations (@GetMapping, @PostMapping); an arbitrary method is allowed and only meaningful at runtime. Python Flask/FastAPI: any function can be a route, no restriction on its name or shape. Go/Rust: handlers are ordinary functions wired to verbs by the router. EK9: the service surface is restricted at compile time to the operators that map to HTTP verbs (+, +=, -, -=, :^:, :~:, ?); anything else is rejected with E07670 so business arithmetic never leaks into the transport layer.

Keywords: service, rest, unsupported, E07670, http, crud, operator, verb, webservice