Pergunta

When writing API clients, what is considered the proper way of concatenating a URL together with multiple endpoints?

For example with the Blizzard API:

WowEndpoints := [...]string{"achievements", "realm"}
Bliz := &Blizzard{
        Url: "https://us.api.battle.net/wow",
        Params: ReqParams,
        Client: BClient,
        Endpoints: WowEndpoints,
    }
// build the realm status request.
req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s/status", Bliz.Url, Bliz.Endpoints[1]), nil)

If you look at Bliz.Url, there is no trailing slash in the top-level URL. Normally, I just add the slashes when formatting API endpoints as if it was a folder structure, as you can see when I do the fmt.Sprintf operation.

I'm not sure where I picked up this habit, but I wanted to see if there was a recommended or preferred way of building URL endpoints for APIs.

Foi útil?

Solução

While it is not universally used, the standard way of joining a URL with a relative URL is:

  • If the URL fragment contains a protocol part, it completely replaces the original URL
  • If it contains a host part, it keeps the protocol of the original URL but otherwise replaces all components
  • If it starts with a slash, it keeps the protocol and host but loses all of the path
  • If it begins with the query separator, '?', only the query and/or fragment parts of the URL are changed
  • If it begins with the fragment separator, '#', only the fragment part of the URL is changed
  • Otherwise, it is a path interpreted relative to the current URL's path (this is the case you appear to have here). Anything after the last slash in the path part of the original URL is removed. Any leading "../" sequences remove the last component of the path, back to the prior slash. Then the rest is concatenated with the result.

The code you quote doesn't do this, presumably because this complexity is unnecessary in this particular case ... although while I don't recognize the language your example is written in, I would presume it has a standard URL class/datatype that already includes this operation, which is widely implemented in most languages' standard libraries (e.g. in Java it is performed by the resolve method of class URI), and it would probably have been better for this implementation to use it.

Licenciado em: CC-BY-SA com atribuição
scroll top