How does service URI mapping work with :/path syntax?

← Web Services · Ref: Q657

EK9 services use ':/path' syntax for URI mapping. The service declaration includes a base path, and each method or operator adds a relative path.

BASE PATH

Declare a service with a root URI:

  Items :/items

This binds the service to the '/items' path prefix.

METHOD PATHS

Named methods declare additional path segments:

  welcome() as GET for :/welcome

This creates a GET endpoint at '/items/welcome'.

OPERATOR PATHS WITH PARAMETERS

Operators use path parameters:

  operator -= :/{itemId}

This creates a DELETE endpoint at '/items/{itemId}'.

PATH PARAMETER BINDING

Path parameters bind to method parameters:

  -> itemId as String

The server extracts the value from the URL and passes it.

See Q199 for GET endpoints. See Q200 for CRUD operators. See Q658 for path parameter binding. See Q202 for parameter binding.
See Q684 for service URI paths. See Q685 for service method bodies.

Example

defines module qa.webdeep.urimapping

  defines service

    <?-
      Service with base URI and multiple endpoint paths.
      Each method and operator adds a relative path.
    -?>
    Catalogue :/catalogue open

      // GET /catalogue/all — list items
      listAll() as GET for :/all
        <- response as HTTPResponse: () with trait HTTPResponse
          override content()
            <- rtn as String: `["itemA", "itemB"]`
          override status() as pure
            <- rtn as Integer: 200
          override contentType() as pure
            <- rtn as String: "application/json"
          override cacheControl() as pure
            <- rtn as String: "max-age=60"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

      // GET /catalogue/{itemCode} — get single item
      byCode() as GET for :/{itemCode}
        -> itemCode as String
        <- response as HTTPResponse: (capturedCode: itemCode) with trait HTTPResponse
          override content()
            <- rtn as String: `{"code": "${capturedCode}"}`
          override status() as pure
            <- rtn as Integer: 200
          override contentType() as pure
            <- rtn as String: "application/json"
          override cacheControl() as pure
            <- rtn as String: "max-age=30"
          override contentLanguage() as pure
            <- rtn as String: "en"
          default operator ?

  defines application

    CatalogueApp
      register Catalogue()

  defines program

    ServiceUriMappingDemo()
      stdout <- Stdout()

      stdout.println("Service URI mapping:")
      stdout.println("  Base: /catalogue")
      stdout.println("  GET /catalogue/all -> listAll()")
      stdout.println("  GET /catalogue/{itemCode} -> byCode()")

Common mistakes

E50001 — The function getMapping is not defined in this module. Use string literals or defined functions. See ek9 -h E50001 for details.

Incorrect:

stdout.println(getMapping())

Correct:

stdout.println("Service URI mapping:")
Other ways to ask this
  • How do I define URI paths for EK9 services?
  • What is the :/path syntax in service definitions?
  • How do service URIs bind to methods and operators?

Coming from another language?

Java: @RequestMapping('/items') on class, @GetMapping('/welcome') on method. Python: @app.route('/items/welcome'). Go: http.HandleFunc('/items/welcome', handler). Rust: web::resource('/items').route(web::get().to(handler)). EK9: 'Items :/items' on service, 'method() as GET for :/welcome' on method.

Keywords: uri, HTTP, dict, endpoint, REST, service, http, route, mapping, path, E07790