Suppose, If I have a binding key as "a.b.*" then I can use the routing keys as a.b.1, a.b.2, a.b.3 , a.b.4 and so on.
I want the queue to accept messages from the all these routing keys except the routing key "a.b.3". How can that be implemented?
Or is there any way I can use regex for my binding key instead of just the wildcard characters "*" and "#".
No; there's no regex, just the two wildcards.
You can use multiple bindings though - you would have to explicitly bind the queue with a.b.1, a.b.3, a.b.4, but then, you might as well just use a direct exchange.
Related
I have a question about a simple REST API endpoint.
The endpoint can accept a value expressed in EURO then returns the corresponding value in DOLLAR, conversely it can accept a value in DOLLAR an return the value in EURO.
I would like to know how I should name this endpoint to respect REST API endpoint naming conventions and best practices.
So far, I have thought about:
-convert-euro-dollar (Probably bad because it uses a verb)
-euro-dollar (Good option?)
Thanks in advance!
I would like to know how I should name this endpoint to respect REST API endpoint naming conventions and best practices.
REST doesn't care what naming conventions you use for your resource identifiers. (Hint: URL shorteners work.)
See Tilkov 2014.
The motivation for choosing "good" resource identifiers is much the same as the motivation for choosing "good" variable names -- the machines don't care, therefore you have extra degrees of freedom that you can use to make things easy for some people.
Possible people you might want to make things easy for: folks looking at resource identifiers in their browser history, operators looking at identifiers in HTTP access logs, writers trying to document the API, etc.
https://www.merriam-webster.com/dictionary/put
Verbs are fine; notice that this URL works exactly the way that you and your browser expect it to, even though the identifier includes a HTTP method.
As suggested by https://stackoverflow.com/a/48692503/19060474 and https://stackoverflow.com/a/10883810/19060474, I would go with one of
GET /dollar/from-euro
GET /euro/to-dollar
GET /currency/usd/from/usd
GET /currency/eur/to/usd
as long as you stay consistent.
Keep in mind, that you should be able to easily deduce from the endpoint what it will likely do. So you should make clear in which direction the conversion will be performed.
With euro-dollar or convert-euro-dollar this is not clearly expressed because one can not determine if the endpoint expects dollar (which dollar by the way, there are quite some variants like USD, AUD, CAD, ...) and converts to EUR or vice versa.
I also suggest you consider using currency codes from the ISO 4217 standard to avoid ambiguity. You can find some of them at https://www.iban.com/currency-codes.
Be aware that answers to this are opinion based, because there is no REST constraint on URI design. All you need is following the URI standards which tells you that the path is hierarchical and the query is non-hierarchical, and that's all. Even that part is sort of flexible.
As of the URI design conventions, I like to describe the operation first and convert it into a verb and a noun. After that I choose HTTP method for the verb and try to describe the rest of it with a noun and attach that second noun to the first one and convert it to an URI template. So I like to name my resources with nouns.
The endpoint can accept a value expressed in EURO then returns the
corresponding value in DOLLAR, conversely it can accept a value in
DOLLAR an return the value in EURO.
Here the operation name would be convertEuroToDollarOrDollarToEuro. I think either we have two operations here convertEuroToDollar and convertDollarToEuro or we need a more general operation name something like convertCurrency and restrict it to the supported currencies, which are Euro and Dollar. Here either I would use POST /conversion to create a new conversion or I would use GET /conversion to read the conversion result.
POST /currency/conversion {"fromCurrency": "EUR", "toCurrency": "USD", "amount": 100}
POST /currency/conversion {"fromCurrency": "USD", "toCurrency": "EUR", "amount": 100}
GET /conversion/{amount}/{fromCurrency}/to/{toCurrency}
GET /conversion/100/EUR/to/USD
GET /conversion/100/USD/to/EUR
GET /currency/conversion?from={fromCurrency}&to={toCurrency}&amount={amount}
GET /currency/conversion?from=EUR&to=USD&amount=100
GET /currency/conversion?from=USD&to=EUR&amount=100
If your service meets the HATEOAS constraint, then this kind of URI structure matters only from service developer perspective, because it is relative easy to figure out the HTTP methods URI templates for the endpoints and bind them to controller methods.
From service consumer or REST client perspective what matters here is the operation name, which is convertCurrency and its parameters: fromCurrency, toCurrency, amount. You need to add these to the documentation and if you can with your actual MIME type attach the metadata to the hyperlink, which represent this operation. So at least do something like:
{
method: "GET",
uri: "/conversion/{amount}/{fromCurrency}/to/{toCurrency}",
type: "convertCurrency"
}
A more advanced solutions would describe the documentation of the convertCurrency operation in a machine readable way. For example Hydra does this: https://www.hydra-cg.com/ and maybe HAL forms can be another solution: https://rwcbook.github.io/hal-forms/ .
Official Documentation reports that link:
Rule matches requests from a list of sources that perform a list of operations subject to a list of conditions. A match occurs when at least one source, one operation and all conditions matches the request. An empty rule is always matched. Any string field in the rule supports Exact, Prefix, Suffix and Presence match:
Exact match: “abc” will match on value “abc”.
Prefix match: “abc*” will match on value “abc” and “abcd”.
Suffix match: “*abc” will match on value “abc” and “xabc”.
Presence match: “*” will match when value is not empty.
Does it mean that I can just apply * at beginning or end, so these kind of paths will not work ?
- operation:
methods: ["POST"]
paths: ["/example-service/test/*/operation"]
It sounds a limitation, isn't it?
It sounds a limitation, isn't it?
Yes, the path like this /example-service/test/*/operation is currently not supported.
You can use wildcard only at the start, end or whole string. You cannot use many wildcards or inside the string.
On the github you can find the issueSupport regex for ServiceRole spec.rules.paths, but it is currently open. The last sentence:
Is there any update for this feature? The support for /foo/id/*/bar would be a great plus.
Unfortunately, such use is not supported at the moment, though this may change in the future. Look also at this github issue and this question.
For the possible workaround see this github topic.
I have a Redis module with a custom command that issues commands to two different keys at once.
The custom commands receives a key (e.g. myKey), and some values, and issues HSET myKey_sd1 ... and ZADD myKey_sd2 ... commands.
I wonder what would happen in a cluster configuration, where each key could exist in a separate node.
Right now, inside the module's custom command I enclosure the key that is given to me in { and }, so I end up issuing HSET {myKey}_sd1 and ZADD {myKey}_sd2
Which works but I wonder if it's necessary.
I also wonder what happens if I receive a key that is already enclosed in curly brackets (because the user of the module wants to control the hash slot by himself) - e.g. 123_{myKey}
Right now, I would still enclose this key in my own curly brackets when I issue the HSET and ZADD - HSET {123_{myKey}}_sd1 ... and ZSET {123_{myKey}}_sd2
In this case, as far as I know, Redis would compute the hash for 123_{myKey which undermines the input of the user (since they didn't wish to enclose the 123_ part)
To fix it, I could have my custom command look for a { in the key that it received, if it didn't find a {, it would enclose the key in { and }, like I described above.
However, if it did find a {, it would leave the key as is, resulting in (in the case of the example above) HSET 123_{myKey}_sd1 ... and ZADD 123_{myKey}_sd2 - which works both for the user and for the inner workings of the module.
So I wonder
Is enclosing the keys that I receive from the user in { and } the right way to support clustering?
If so, am I handling the case where the user provides a key which is already enclosed in { and } in the right way?
Is enclosing the keys that I receive from the user in { and } the right way to support clustering?
The Redis Module cluster documentation is "missing", but I believe it's the case that your module must make sure to use the same node as the key that was passed as an argument.
So, yes, you must use hash tags to ensure that your keys are using the same hash slot as the passed key.
If so, am I handling the case where the user provides a key which is already enclosed in { and } in the right way?
Your proposed fix (not your current implementation) is right. You must hash to the same slot as the key that is passed, which means respecting any specified hash slot.
Just make sure you're following the exact algorithm for interpreting hash tags. You don't want any edge cases here.
imagine a very simple flow with a HTTP inbound and a body-to-parameter-map. Payload contains something like {prop1=aaa, prop2=eee, prop3=iii}.
My question is, why if I try to access #[payload.prop1] sometimes (and I said sometimes) it gets null value, while #[payload['prop1']] seems to be allways correct?
Those are equivalent, the only different would be that the dot notation also support objects while the key one only support collections.
It's perhaps that the you are using the dot notation with keys that already contain a dot? Like http.status. In those cases you should either escape with 'http.status'.
I need create binding key with range parameter, Have is Rabbitmq special characters for it? For example:
1. #.key.# - any names before and after key word
??.key.?? - for point to range like SQL (>10 <20).key.(>10 <20)
thx.
I do not believe it is possible to do what you want with a current exchange. You may be able to do it with a custom exchange though. You could try this one https://github.com/tonyg/script-exchange or write your own. Check out the HowTo on this page http://www.rabbitmq.com/how.html#going-further for writing your own custom exchange.