I am new to REST and have some trouble finding the proper RESTful url for an API.
I have an API that, given a word, returns a JSON with a boolean that indicates if the word is a verb or not. So in a not restful universe, this API would be a isVerb method. I am having trouble with finding a proper RESTful noun for the url of my API (as verbs are not allowed in REST).
I already have an API that given a string returns the verbs in that string (the actual GET /verbs) so the option myapi.com/verbs is not possible (and wouldn't be 100% right for my problem, as I am not getting verbs, but getting a boolean).
Any hints? Thanks a lot!
If I understand you correctly, there are two use-cases:
1) Extracting verbs from a string and
2) Test if a word is a verb.
Here is how I would decompose the problem:
A) You have two inputs, a string and a word; but both can be abstracted out just as an array of words,
a strings = [‘word1’, ‘word2’, …]
B) To think of “/verbs/” as a space for all verbs
Then the problem becomes to just get a set of verbs out of the ‘virtual’ verbs space in ‘/verbs/’ by providing inputs (a string of words).
The API to access '/verbs/'could be in two forms:
A) GET /verbs/?text=‘word’,…
Return: OK with the subset of text that are verb
Return: Not found
B) GET /verbs/{word}/
Return: OK with the ‘word’ if it is a verb
Return: Not found
In my opinion '/verbs' path is very good in this scenario. But if it already has been taken consider something similar, for example: '/verbsResource', '/versSet', ...
This service will return (for GET request):
status code HTTP 200 OK when given string is a verb;
status code HTTP 404 Not Found when given string is NOT a verb.
So there are no boolean values.
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/ .
I have review multiple instructions on URL-parameters which all suggest 2 approaches:
Parameters can follow / forward slashes or be specified by parameter name and then by parameter value. so either:
1) http://numbersapi.com/42
or
2) http://numbersapi.com/random?min=10&max=20
For the 2nd one, I provide parameter name and then parameter value by using the ?. I also provide multiple parameters using ampersand.
Now I have see the request below which works fine but does not fit into the rules above:
http://numbersapi.com/42?json
I understand that the requests sets 42 as a parameter but why is the ? not followed by the parameter name and just by the value. Also the ? seems to be used as an ampersand???
From Wikipedia:
Every HTTP URL conforms to the syntax of a generic URI. The URI generic syntax consists of a hierarchical sequence of five components:
URI = scheme:[//authority]path[?query][#fragment]
where the authority component divides into three subcomponents:
authority = [userinfo#]host[:port]
This is represented in a syntax diagram as:
As you can see, the ? ends the path part of the URL and starts the query part.
The query part is usually a &-separated string of name=value pairs, but it doesn't have to be, so json is a valid value for the query part.
Or, as the Wikipedia articles says it:
An optional query component preceded by a question mark (?), containing a query string of non-hierarchical data. Its syntax is not well defined, but by convention is most often a sequence of attribute–value pairs separated by a delimiter.
It is also fairly common for request processors to treat a name=value pair that is missing the = sign, as if the it was name=.
E.g. if you're writing Servlet code and call servletRequest.getParameter("json"), it would return an empty string ("") for that last URL in the question.
I have 3 separate APIs, A, B, and C. A and B are completely independent, whereas C queries A and B to compile data together. Each API is in its own project and running on its own port (8081, 8082, and 8083, respectively).
I am able to successfully hit A and B individually AND through C...sort of. When C hits one of these endpoints, the result comes back as a glassfish.grizzlly.utils.BufferInputStream.
I've dealt with this BufferInputStream type before by using a Transform Message Component. However, doing so here simply produces an error, saying that payload.id is of the wrong type (it should be an integer). When running this in debug mode, I can see that A has an Output Payload with id: Integer (it is of a custom type). However, upon moving back into C's flow, the payload is now the aforementioned BufferInputStream type, and I'm unable to directly access payload.id.
In short: How do I retrieve data in one project from another project?
Thanks in advance!
Update:
I used an Object to String transformer on the BufferInputStream to get a better look at the value. It appears to be in the format of a URL:
id=12345&name=nameValue&otherVal=%5B8499%5D...
I can #[payload.split('&')] at this point and get most of what I need, but then there's still the issue of things like the following:
summary=Words+with+plus+signs+in+the+middle
Again, I can work around this with things like split, but surely this is not what is intended.
Update 2:
I discovered the following warning:
[[test].api-httpListenerConfig.worker.01]
org.mule.module.http.internal.listener.HttpResponseBuilder:
Payload is a Map which will be used to generate an url encoded http body but
Contenty-Type specified is application/java; charset=windows-1252 and not
application/x-www-form-urlencoded
I'm not entirely sure what to do with that info, though the Contenty-Type typo is interesting ^^
Solved! In A and B, I needed to use an Object to Byte Array transformer before returning the value. This allows me to use a Byte Array to Object transformer in C and get the original value back.
Like the title says, is it possible to write an Express GET route that accepts an array of unknown length?
I know I can use a POST request and just include an array in the body, but it isn't posting something so much as getting something!
I need to know how to encode the url. Most of what I am seeing is for arrays of particular length. This could be for 2 or 20, or more.
YES!
You can use the query parameter and use a delimiter, as search engines of old where your search string was actually in the url with spaces demarcated with +. This allows for an array of indeterminate length.
Did not get any feedback for HOW to encode an array to accept a url, so this is the approach I am going with. Even in my googling I couldn't find much on HOW to encode a URL to have an array in the params object, rather than the query object, possibly because I was searching for how to do it for an array of indeterminate length?
Web.HttpUtility.UrlEncode method in my project. When I am encoding name in English language then I got correct result. For example,
string temp = System.Web.HttpUtility.UrlEncode("Jewelry");
then I got exact result in temp variable. But if I wrote name in Russian language then I got different result.
string temp = System.Web.HttpUtility.UrlEncode("ювелирные изделия");
then I got value in temp variable like "%d1%8e%d0%b2%d0%b5%d0%bb%d0%b8%d1%80%d0%bd%d1%8b%d0%b5+%d0%b8%d0%b7%d0%b4%d0%b5%d0%bb%d0%b8%d1%8f"
Can anyone help me how to achieve exact name as per language?
Thank you!
Actually, the method has "done the right thing" for you!
It encodes non-ASCII characters so that it can be valid in all of the cases and transmit over the Internet. If you put your temp variable in an URL as a parameter, you will get your correct result at server side. That's what UrlEncode means for. Here your question is not a problem at all.
So please have a look at this link for further reading to understand about URL Encoding: http://www.w3schools.com/tags/ref_urlencode.asp
If you input that Russian word to the "URL Encoding Functions" part in the page I have given, it will return the same result as Web.HttpUtility.UrlEncode method does.
Can anyone help me how to achieve exact name as per language?
In short: not with that method, but it might depend on what is your exact goal.
In details:
In general URIs as defined by RFC 3986 (see Section 2: Characters) may contain any of the following characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]#!$&'()*+,;=. Any other character needs to be encoded with the percent-encoding (%hh).
This is why UrlEncode produces
UrlEncode("Jewelry") -> "Jewelry"
UrlEncode("ювелирные изделия") -> "%d1%8e%d0%b2%d0%b5%d0%bb%d0%b8%d1%80%d0%bd%d1%8b%d0%b5+%d0%b8%d0%b7%d0%b4%d0%b5%d0%bb%d0%b8%d1%8f"
The string of "ювелирные изделия" contains characters that are not allowed in a URL as per RFC 3986.
Today, modern browsers could work with UTF-8 in URL it might be not necessary to use UrlEncode(). See example: http://jsfiddle.net/ybgt96ms/