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: under 'defines service' the service name is followed by its base path, as in 'Items for :/items'. This binds the service to the '/items' path prefix. The 'for' before every URI is required, as is the 'as' before an HTTP verb ('welcome() as GET for :/welcome'): leaving either out is E07671, and the editing tools insert it for you.
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 -= for :/{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
#!ek9 defines module qa.webdeep.urimapping defines service <?- Service with base URI and multiple endpoint paths. Each method and operator adds a relative path. -?> Catalogue for :/catalogue open // GET /catalogue/all — list items listAll() as GET for :/all <- response as HTTPResponse: () with trait HTTPResponse override content() <- rtn as Bytes: Bytes().withUtf8(`["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 Bytes: Bytes().withUtf8(`{"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
E07671 — A service URI is written after 'for' - the service's own and each method's. Without it the compiler reports E07671 at the URI. See ek9 -h E07671 for details.
Incorrect:
Catalogue :/catalogue open
Correct:
Catalogue for :/catalogue open
E07671 — An HTTP verb is written after 'as'. 'listAll() GET' is E07671 at the verb; 'listAll() as GET for :/all' is the one form. See ek9 -h E07671 for details.
Incorrect:
listAll() GET for :/all
Correct:
listAll() as GET for :/all
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 for :/items' on service, 'method() as GET for :/welcome' on method.
Keywords: E07671, E07790, HTTP, REST, dict, endpoint, http, mapping, path, route, service, uri