How to include id in REST API URL path (but not in query string or body)?

I’m using the REST connector to integrate with (external) RESTful API endpoints. I know I can supply parameters as part of the query string (behind the question mark in a URL) and that a request body can be supplied for POST/PUT requests. But in a normal REST style, the URL path itself often contains (resource id-like) parameters as well. How to supply those? How to specify that in the Camunda Modeler? This isn’t (yet) described in REST Connector | Camunda Platform 8 Docs.

For example, I want to GET the resource representation for a specific customer, #123, from its URL:
https://example.com/customer/123
or its address which resource URL is
https://example.com/customer/123/address

I know that
https://example.com/customer?id=123
or
https://example.com/customer/address?id=123
are possible, but semantically those are slightly different: they search for (possibly more) resources with the id of 123 (resulting in minimally an empty list) instead of clearly referring to (at most) one resource (resulting in minimally a 404 response code).

See REST API - URL Naming Conventions for common conventions on this.

Question: how to do this in Camunda Modeler? Is something like
https://example.com/customer/{id}
or
https://example.com/customer/{id}/address
possible?

As per the documentation, I did not see any details about mentioning path parameters, may be time to submit a request for adding it in next release.

Thanks - just what I discovered: it’s not (yet) in the documentation… but it’s a very common convention in RESTful APIs.

Where can I submit a request for adding it to a release? This could be an important improvement. (Or it’s already possible, and just should be documented.)

@Camunda Team, would you please share the link.

The URL supports FEEL. You can click the = in the circle or fx in later modeler versions to switch to FEEL. Then you can enter something like: "https://example.com/customer/" + customerId + "/address". customerId would be a variable.

@cpbpm and @jschulenklopper - confirming what @cma said: the URL property supports FEEL, so you can build your URL as needed for the request.

I agree that is a gap in the documentation. Do either of you have a suggestion on how it should be included? If you do, I’d like to encourage you to submit the change yourself! There is an “Edit This Page” link at the bottom of every page that will automatically open a pull request. (I will forward this on to our documentation regardless, but we love seeing community contributions, especially to our documentation!)

1 Like

Ah, great; this is a solution.

But, being honest here, for such a common convention in RESTful requests to a resource on its API endpoint, I think there could be a nicer way to specify that URL path than expressing it as a concatenation of substrings and variables. It complicates the expression of such a common and often-used pattern for URL paths.

Any chance that something like
https://www.example.com/customer/{customerId}/address
or
https://www.example.com/customer/:customerId/address
will become available as valid (FEEL) expressions? These two examples are very common in other SDKs or API documentation.

I can make a proposal for this, but I’ll away the response to my follow-up question to @cma. In my opinion, the concatenation of string parts to build a URL path with resource identifying variables is more difficult than it should be. So, if FEEL supports (of will support) in-string-placement of variable names, that’ll make this very common RESTful URL path convention more clear (and we can document the easiest way).

Don’t get me wrong: I like that there’s a solution (and that the community answered to quick). But I think (hope) there’s a better solution possible, that’ll make expressing this common pattern more easy. Otherwise I’ll have some more challenges in educating my Business Analyst to construct the URL of a RESTful API endpoint using the current FEEL capabilities.

I’m no FEEL expert, but currently, I think this is the best solution you can get. The only way I see this working is if they add more functions. There is a replace, but it doesn’t help. We would need something like format("https://www.example.com/{}/address", customerId) similar to slf4j formatting (with dynamic number of parameters!). Automatic variable replacement in strings will be more difficult to implement I guess and I don’t know about specifications etc. but that would be another approach to make it easier.

1 Like

Thanks - I get it. I’m mainly referring to other ways of variable substitution or string interpolation that are solved differently in other expression languages so that it can be an inspiration to improve this in FEEL.

I really like Camunda (Modeler) so far, but this specific thing is currently more complex than it could be (and it’ll lower the acceptance / convenience of the Camunda Modeler by the Business Analysts in my team).

I see, Camunda has to answer about their FEEL plans, but there is always the possibility of creating a custom connector which does exactly that. Take a text field and then resolve the variables in the connector function. You can also read configuration from the connector runtime etc. Custom connectors are really flexible. So there are ways to make it easier for non-devs, but you have to bridge the gap yourself.

In my opinion if a non-dev should configure a connector he shouldn’t have to know anything about the end points etc. Just some fields where he/she can put in some values. So in this case you could create a customerConnector and then add an action drop down, one of the action is getAdress and then an id field appears and nothing more (+ field to save the result in a variable).

1 Like

Great direction for a solution: I might need to make a custom connector for my customer, based on the existing REST connector, tailored towards how it should work for my project. Thanks for the pointer - I’ll look into that.

Such a custom connector could even abstract / hide the API application server id (the hostname) and the resource (the first element of the URL path) - those values could be determined/set at deploy-time (also depending on the environment the process is deployed to: TST, STAGING, PROD).

Extending the Protocol Connectors is a great way to achieve what you’re looking for. In fact, there’s a blog post I wrote coming out in a couple weeks on exactly that topic! :wink: I built several iterations of an Airtable Connector, one of which accepts variables in the details pane then builds the URL “behind the scenes”:

    {
      "label": "URL",
      "group": "endpoint",
      "type": "Hidden",
      "binding": {
        "type": "zeebe:input",
        "name": "url"
      },
      "value": "=\"https://api.airtable.com/v0/\"+baseId+\"/\"+tableId"
    },
    {
      "id": "baseId",
      "label": "Base ID",
      "description": "The ID of the base the table is in",
      "group": "input",
      "feel": "optional",
      "type": "String",
      "binding": {
        "type": "zeebe:input",
        "name": "baseId"
      }
    },
    {
      "id": "tableId",
      "label": "Table ID",
      "description": "The ID of the table to insert records into",
      "group": "input",
      "feel": "optional",
      "type": "String",
      "binding": {
        "type": "zeebe:input",
        "name": "tableId"
      }
    },

Regarding FEEL, I don’t think that’s something that will end up being supported, because FEEL is actually a standard maintained by OMG and I don’t think that form of string interpolation is part of the spec. You could also look into using a user defined function that returns the concatenated URL.

2 Likes

Working BPMN Snippet:

<camunda:inputParameter name=“url”>
<camunda:script scriptFormat=“JavaScript”>“https://example.com/customer/”+id</camunda:script>

Hi @linforestzhang - that is a snippet for Camunda 7; that will not work with Camunda 8.

Right, it’s based on Camunda 7. Thanks for your clarification.