How do I extract path parameters in EK9 services?

← Web Services · Ref: Q658

EK9 services extract path parameters using :/{paramName} syntax. The path variable binds to a method parameter of the same name.

PATH PARAMETER

Declare a path variable in the URI:

  byId() as GET for :/{orderId}
    -> orderId as String

The server extracts orderId from the URL path.

CAPTURE PATTERN FOR DYNAMIC RESPONSE

Path parameters are NOT in scope inside the dynamic HTTPResponse class body. To use a path parameter in response content, capture it in the dynamic class expression:

  <- response as HTTPResponse: (capturedId: orderId) with trait HTTPResponse
    override content()
      <- rtn as String: `{"id": "${capturedId}"}`

The captured variable is accessible within the dynamic class methods.

CONTENT BINDING

Use :=: CONTENT for request body:

  operator += :/
    -> body as String :=: CONTENT

The request body is bound to the 'body' parameter.

HTTPRESPONSE RETURN

Every service method must return HTTPResponse:

  <- response as HTTPResponse: ...

See Q657 for URI mapping basics. See Q200 for CRUD operators. See Q201 for HTTP responses. See Q659 for HTTPResponse requirements. See Q660 for CRUD operators.

Example

defines module qa.webdeep.pathbinding

  defines service

    <?-
      Service demonstrating path parameter extraction
      and content body binding.
    -?>
    Orders :/orders open

      // GET /orders/{orderId} — extract path param
      byId() as GET for :/{orderId}
        -> orderId as String
        <- response as HTTPResponse: (capturedId: orderId) with trait HTTPResponse
          override content()
            <- rtn as String: `{"orderId": "${capturedId}"}`
          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 /orders — content body binding
      operator += :/
        -> orderJson as String :=: CONTENT
        <- response as HTTPResponse: () with trait HTTPResponse
          override content()
            <- rtn as String: `{"received": 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 application

    OrderApp
      register Orders()

  defines program

    PathParameterDemo()
      stdout <- Stdout()

      stdout.println("Path parameter binding:")
      stdout.println("  GET /orders/{orderId} -> byId(orderId)")
      stdout.println("  POST /orders with CONTENT -> operator +=")

Common mistakes

E07700 — Path parameters in the URI must have a matching method parameter with the same name. If the URI declares {orderId}, the method must have a parameter named orderId. See ek9 -h E07700 for details.

Incorrect:

-> orderNumber as String

Correct:

-> orderId as String
Other ways to ask this
  • How does PATH binding work in EK9 services?
  • How do I get URL path variables in service methods?
  • What is E07880 service parameter binding error?

Coming from another language?

Java: @PathVariable('orderId') String orderId. Python: Flask route('<orderId>'). Go: mux.Vars(r)['orderId']. Rust: web::Path<String>. EK9: ':/{orderId}' in URI, '-> orderId as String' in parameter list.

Keywords: path, REST, binding, parameter, URL, extract, variable, E07880, http, service