是否相当于将某些东西作为路径的一部分并作为参数?
Is it equivalent to put something as part of the path and as a parameter?
现在我有两种方法可以(显然)在我的应用程序中完成同一件事。我可以让我的网址看起来像这样 https://something/product/shirt or https://something/product?q=shirt。在这两种情况下,我都可以从中提取我需要的东西,即衬衫。
第一种方式(使用正则表达式):
class FirstHandler(BaseHandler):
def get(self, page_id):
target = page_id
PAGE_RE = r'(/(?:[a-zA-Z0-9_-]+/?)*)'
app = webapp2.WSGIApplication([('/something' + PAGE_RE, FirstHandler)],
debug=True)
第二种处理方法是使用参数,如下所示:
class SecondHandler(BaseHandler):
def get(self):
target = self.request.get('q')
app = webapp2.WSGIApplication([('/something' SecondHandler)],
debug=True)
我的问题是,这些方法是否等效?如果我做一个或另一个是一样的还是我必须考虑其他事情?
app.yaml
可以为您预先路由(到不同的 WSGI 应用程序——甚至在 dispatch.yaml
的帮助下,到不同的 模块 ),基于 URLs,但 而不是 基于对给定 URL.
的特定查询
因此,如果您将资源标识为 /something/product/shirt
,您将来 可能 "administratively"(通过更改 app.yaml
并且可能 dispatch.yaml
配置文件,而不是 Python 代码)将某些产品预先路由到不同的 WSGI 应用程序甚至模块;如果您将其标识为 /something/product?q=shirt
,基于配置文件的管理路由将仅基于 /something/product
到单个 WSGI 应用程序,然后将由服务于该应用程序的代码来处理 w/the 查询部分.
因此,在其他条件相同的情况下,您可能更愿意使用 URLs 来为将来保持更多的路由灵活性。查询部分对于诸如可选参数和顺序独立性之类的东西是宝贵的——想象一下,例如 /something/product/shirt?fmt=json&size=xl
,其中 fmt
和 size
都是可选的,有一些默认值,并且可以选择以任何顺序出现,这将是 nasty/complex 与 URL 的关系,而它很容易通过查询实现。
但是带有单个 mandatory 参数的 "query syntax" 是一个(适度的)"API design smell" —— 不仅在 App Engine 中;虽然 App Engine 有自己的路由和调度机制,但它们与您对其他服务器的期望并没有特别不一致。
查看您希望发出的所有请求,并决定其中哪些应该由唯一端点 (/shirt
) 表示,哪些将允许一个或多个参数。您可以在必要时结合使用这些方法。
使用 url 路径或参数没有性能损失或任何其他优势。关键因素是:
- 了解您的 API 是否被或将被外部开发人员使用的难易程度
- 组织和维护代码的难易程度
- 当您需要扩展时,您的方法有多灵活
例如,/shirt
现在看起来可能是个好主意,但是一旦您拥有数千种产品类型,维护起来就会变成一场噩梦。相反,您可能想使用类似的东西:
/product/?type=shirt&size=10&orderBy=price&results=20&offset=40
现在我有两种方法可以(显然)在我的应用程序中完成同一件事。我可以让我的网址看起来像这样 https://something/product/shirt or https://something/product?q=shirt。在这两种情况下,我都可以从中提取我需要的东西,即衬衫。
第一种方式(使用正则表达式):
class FirstHandler(BaseHandler):
def get(self, page_id):
target = page_id
PAGE_RE = r'(/(?:[a-zA-Z0-9_-]+/?)*)'
app = webapp2.WSGIApplication([('/something' + PAGE_RE, FirstHandler)],
debug=True)
第二种处理方法是使用参数,如下所示:
class SecondHandler(BaseHandler):
def get(self):
target = self.request.get('q')
app = webapp2.WSGIApplication([('/something' SecondHandler)],
debug=True)
我的问题是,这些方法是否等效?如果我做一个或另一个是一样的还是我必须考虑其他事情?
app.yaml
可以为您预先路由(到不同的 WSGI 应用程序——甚至在 dispatch.yaml
的帮助下,到不同的 模块 ),基于 URLs,但 而不是 基于对给定 URL.
因此,如果您将资源标识为 /something/product/shirt
,您将来 可能 "administratively"(通过更改 app.yaml
并且可能 dispatch.yaml
配置文件,而不是 Python 代码)将某些产品预先路由到不同的 WSGI 应用程序甚至模块;如果您将其标识为 /something/product?q=shirt
,基于配置文件的管理路由将仅基于 /something/product
到单个 WSGI 应用程序,然后将由服务于该应用程序的代码来处理 w/the 查询部分.
因此,在其他条件相同的情况下,您可能更愿意使用 URLs 来为将来保持更多的路由灵活性。查询部分对于诸如可选参数和顺序独立性之类的东西是宝贵的——想象一下,例如 /something/product/shirt?fmt=json&size=xl
,其中 fmt
和 size
都是可选的,有一些默认值,并且可以选择以任何顺序出现,这将是 nasty/complex 与 URL 的关系,而它很容易通过查询实现。
但是带有单个 mandatory 参数的 "query syntax" 是一个(适度的)"API design smell" —— 不仅在 App Engine 中;虽然 App Engine 有自己的路由和调度机制,但它们与您对其他服务器的期望并没有特别不一致。
查看您希望发出的所有请求,并决定其中哪些应该由唯一端点 (/shirt
) 表示,哪些将允许一个或多个参数。您可以在必要时结合使用这些方法。
使用 url 路径或参数没有性能损失或任何其他优势。关键因素是:
- 了解您的 API 是否被或将被外部开发人员使用的难易程度
- 组织和维护代码的难易程度
- 当您需要扩展时,您的方法有多灵活
例如,/shirt
现在看起来可能是个好主意,但是一旦您拥有数千种产品类型,维护起来就会变成一场噩梦。相反,您可能想使用类似的东西:
/product/?type=shirt&size=10&orderBy=price&results=20&offset=40