How do CRUD operators map to URIs with path parameters?
← Web Services · Ref: Q660
EK9 maps service operators to HTTP verbs with semantic meaning. Each operator has a natural CRUD mapping.
OPERATOR MAPPING
operator += :/ POST (create resource) operator -= :/{id} DELETE (remove resource) operator :~: :/{id} PATCH (partial update) operator :^: :/{id} PUT (full replacement)
PATH PARAMETERS IN OPERATORS
Operators can include path parameters:
operator -= :/{resourceId} -> resourceId as String <- response as HTTPResponse: ...
CONTENT BINDING IN OPERATORS
POST and PUT operators accept request body:
operator += :/ -> body as String :=: CONTENT
SEMANTIC ALIGNMENT
The operator meanings align with HTTP:
+= adds to collection -> POST creates -= removes from collection -> DELETE removes :~: merges partially -> PATCH updates fields :^: replaces entirely -> PUT replaces
See Q200 for CRUD overview. See Q657 for URI mapping. See Q658 for path parameters.
Example
defines module qa.webdeep.crudoperators defines service <?- Full CRUD service using operator-to-verb mapping. Each operator handles a different HTTP method. -?> Products :/products open // GET /products — list listProducts() :/ <- response as HTTPResponse: () with trait HTTPResponse override content() <- rtn as String: `["widget", "gadget"]` 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 ? // POST /products — create operator += :/ -> productJson 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 ? // DELETE /products/{productId} — remove operator -= :/{productId} -> productId as String <- response as HTTPResponse: () with trait HTTPResponse override content() <- rtn as String: "" override status() as pure <- rtn as Integer: 204 override contentType() as pure <- rtn as String: "text/plain" override cacheControl() as pure <- rtn as String: "no-store" override contentLanguage() as pure <- rtn as String: "en" default operator ? defines application ProductApp register Products() defines program CrudOperatorDemo() stdout <- Stdout() stdout.println("CRUD operators in service:") stdout.println(" += maps to POST /products") stdout.println(" -= maps to DELETE /products/{id}")
Common mistakes
E50001 — The function getCrudInfo is not defined in this module. See ek9 -h E50001 for details.
Incorrect:
stdout.println(getCrudInfo())
Correct:
stdout.println("CRUD operators in service:")
E50001 — The function getPostInfo is not defined in this module. See ek9 -h E50001 for details.
Incorrect:
stdout.println(getPostInfo())
Correct:
stdout.println(" += maps to POST /products")
Other ways to ask this
- How do I use += for POST and -= for DELETE in services?
- What is the operator to HTTP verb mapping in EK9?
- How do service operators handle path parameters?
Coming from another language?
Java: Spring @PostMapping, @DeleteMapping, @PatchMapping, @PutMapping. Python: Flask methods=['POST']. Go: manual method switch. Rust: actix .post()/.delete(). EK9: operators += (POST), -= (DELETE), :~: (PATCH), :^: (PUT) with URI paths.
Keywords: operator, PUT, PATCH, E07860, dict, service, CRUD, http, mapping, DELETE, POST