REST API:使用客户端应用程序域向外部服务提供重定向URI

时间:2014-03-10 17:18:34

标签: rest restful-url restful-architecture

背景

我有一个通过域http://restapi.com

访问的RESTful API

我有一个使用http://restapi.com的客户端应用。客户端应用拥有域http://myapp.com

我的HATEOAS设置方式是API提供没有域的URI。因此,它不包含http://restapi.com/some/resource,而是包含指向/some/resource等资源的链接。示例API json资源如下:

{"_links":{"self":{"href":"/some/resource"}}}

这样做的好处是API不需要知道客户端应用程序,并且客户端应用程序必须做很少的事情才能从API获取正确的资源,并且不必重新格式化所有URI资源。例如,在客户端应用程序中,浏览器http://myapp.com/some/resource将使用以下URI。当应用获得请求时,它需要调用API来获取资源并简单地交换域,即http://restapi.com/some/resource

这是成功的,并且允许很多灵活性让不同的客户端使用API​​,只需要API的初始端点(域)。它还完全将API与客户端应用程序分离。

我遇到的问题是我已经开始使用一些外部服务(特别是PayPal自适应付款),我需要为取消付款和成功付款提供重定向网址。例如,浏览器导航到http://myapp.com/paymenthttp://restapi.com/payment返回的资源显示了PayPal的链接。在没有详细说明的情况下,API必须向PayPal询问付款ID,然后可以使用该ID来创建PayPal付款的链接,例如http://paypal.com?PayId-123456。部分创建过程要求提供URL以在付款取消或成功时重定向。同样,不想详细说明,但是当从PayPal请求PayId时,重定向URL作为变量发送到PayPal,我想PayPal会将它们存储在创建的特定PayId中。

浏览器导航到资源中返回的链接 - http://paypal.com?PayId-12345。付款后,PayPal会根据需要使用重定向网址重定向回我的应用,例如成功完成付款后,PayPal应重定向到http://myapp.com/paymentcomplete。注意:我意识到这不是一个重新命名的URI,但它简化了我的问题描述的构建

问题

我现在的问题可能很明显。我需要重定向回http://myapp.com/paymentcomplete其提供重定向网址到PayPal的API。它不了解客户端应用程序。由于PayPal是外部服务,因此必须提供完整的URL。 API可以做的最好的事情是发送http://restapi.com/paymentcomplete作为重定向URL,但如果PayPal重定向到此,则生成的响应将是JSON字符串(我的API的输出格式),而不是客户端应用程序的格式良好的页面

我的问题是,有什么方法可以正确地为PayPal提供重定向网址?

我有一个想法是让客户端应用程序处理创建PayPal PayId,但我不喜欢这个选项,因为我想在API端继续创建PayPal支付ID。它还需要每个客户端应用程序提供自己的实现,这也是我不想要的。

我的另一个选择是要求客户在请求中提供其域名。目前,客户端获取具有PayPal链接的资源的请求为GET http://restapi.com/payment,但我可以使用POST http://restapi.com/payment将客户端提供其域作为参数。然后,API可以使用它来构造正确的重定向URL。我不喜欢这个想法,因为它似乎有点hackish并且还要求应用程序知道必须填写此字段,即人类用户不会填写域输入。

非常欢迎其他解决方案或想法。

3 个答案:

答案 0 :(得分:1)

您应该能够使用Referer标头来确定客户端的完整URI。它可能会自动填充给您。如果没有,您可以自己添加。 URI类有方法为您提取客户端的主机。当API构建PayPal URI以返回到客户端时,它可以包括客户端的主机。

请注意,referer并非总是包含在内,有时会被中介删除,详见维基页面。由于在这种情况下您可以控制客户端和服务器,因此您应该能够告诉每个人玩得很好。

答案 1 :(得分:1)

正如您已经提到的,PayPal是一个外部API,它需要这个额外的参数,而您无法控制它。看起来客户端是唯一可以提供重定向URI信息的一方。

想到了一些想法。

  1. 客户端可以通过标头将重定向uri发送到restapi 保持你的休息网完好无损。这是一个灰色区域,并不违反宁静的api 在我看来。 (然后,这只是我的观点)。

  2. restapi可以使用占位符返回响应 客户端在渲染之前填写。这种方式API无需知道 关于重定向uri,责任留给客户 有这方面的信息。

  3. 如果您可以通过在浏览器上的Javascript代码上执行几行来实现选项2来填充占位符,那就更好了。这很容易。最终,此交易中只有2个终点可以识别重定向uri - browser&贝宝。

    这可以减轻您的大部分顾虑。处理PayPal ID的工作将继续保留在您的API中。

答案 2 :(得分:0)

我会保留GET http://restapi.com/payment并传入一个包含客户端域的查询参数

GET http://restapi.com/payment?domain=http://myapp.com (of course, the "http://myapp.com" needs to be encoded)