在 API 请求中传递查询参数

Passing query-prameters in an API-request

为什么要用字典和设置参数? 比如下面的lat,lng:

parameters = {
    "lat": MY_LAT,
    "lng": MY_LONG,
    "formatted": 0
}

response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters)

为什么我不能执行以下操作,例如输入纬度?

response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters, lat=MY_LAT)

您不能按名称传递参数,因为 Python requests 库不知道给定的 URL 接受哪些参数。日出时的 API-sunset.org 接受 latlng 参数,但大多数其他 API 对它们没有用。通过传递 key=value 对的字典,您可以告诉 requests 您正在调用的特定 API 期望的参数的名称和值。

因为这就是您正在使用(请求)的库的工作方式。这也是 Python 以及几乎所有编程语言处理方法参数的方式。

你有没有写过这样的函数...

def add(a, b):
    return a + b

请注意,ab 是什么非常清楚。

您正在使用的库也是如此,requests。它不知道您要发布到的端点有一个 lat 参数,它怎么知道的?你会如何处理不知道参数是否正确的错误?

如果我是你,我会阅读 Python 方法中如何处理参数以及 HTTP 请求,也许这会帮助你了解为什么它们不能对齐。

您的想法在概念上朝着正确的方向发展。

将查询参数作为任意键值对传递

使用 lat=MY_LAT 等参数调用 requests.get 方法正是该方法所需要的。但是 requests 库的设计者想要保留方法 generic。这意味着,它应该适用于所有 GET 请求,无论它们的查询参数是什么。

因此,如果事先不知道未来的查询参数将被命名为什么,它们需要什么类型,或者需要多少,他们就无法命名并计算它们的修复。 情况恰恰相反:查询参数应该是灵活的并遵守 HTTP query-string 规范 (RFC)。 那么,为什么不设计一个参数来保存这个查询字符串,或者它的组件作为灵活的键值对?!

字典参数像kwargs一样多用包

每当你想为任意数量的参数设计一个方法时,你都会像众所周知的 那样设计一个参数。这实际上是一个字典或映射,可以容纳尽可能多的命名参数。

名为 params 的参数非常相似

现在,requests.get() 方法中名为 params 的参数正是您可以将其作为多种键值对放入的字典。

你的情况:

parameters = {
    "lat": MY_LAT,
    "lng": MY_LONG,
    "formatted": 0
}

parameters就是上面定义的那个字典或者地图。它可以用作包罗万象的单个 param 来保存所有查询参数及其任意名称和值。正如当前调用的 web-API 或 URL 资源所要求的那样。

您可以包装调用,明确使用坐标

您可以做什么,尤其是在域驱动设计中,将 GET 调用包装在您自己的方法中。例如:

def get_sunrise_sunset_for(lat, lng):
    parameters = {
        "lat": lat,
        "lng": lng,
        "formatted": 0
    }
    response = requests.get(url="https://api.sunrise-sunset.org/json", params=parameters)
    return response.json() # actually you would parse and return extracted times, etc.

您为特定目的设计了它(sunset/sunrise,而不是通用的 HTTP GET)。所以你可以明确地使用参数 latlng。此外,您可以 return 特定的回复,例如白天。