在开发网站时开发API以便网站本身实际使用API是一种好习惯吗?或者如果选择这样做会有性能影响吗?
例如,有没有人知道Facebook或Digg等成熟网站是否使用自己的API进行CRUD(创建,读取,更新,删除),或者他们是否拥有自己的后端?谢谢
我喜欢谷歌地图的api消费方式,使用脚本包括,但我很担心:
我的api是"半私有的",即可通过互联网访问,但应允许安全传输数据和某种身份验证.数据应该通过网络保持私有,并且一个消费者不应该能够获得另一个数据.
我如何使用SSL和某种身份验证来保证数据安全,但仍然可以从纯HTML页面"水平"访问,而不需要服务器端代理?我需要管理密钥吗?如何在不截获的情况下将密钥发布到服务器?我可以使用OpenId(或其他一些第三方身份验证)来验证api用户,还是必须创建自己的身份验证机制?我一直在谷歌,无法找到安全设计和部署我的API的好指南.
现在我正在使用REST和AJAX来使用它们,但是跨域调用是不可能的.任何帮助或正确方向的指针将非常感激.
我刚读完Restful Web Services,没有人理解REST或HTTP,我正在尝试设计一个RESTful设计的API.
我注意到API URI设计中的一些模式:
http://api.example.com/users
http://example.com/api/users
http://example.com/users
Run Code Online (Sandbox Code Playgroud)
假设这些设计正确使用Accept和Content-type标题用于XHTML,JSON或任何格式之间的内容协商.
这些URI是纯 RESTful实现与隐式内容协商的问题吗?
我的想法是,通过在URI中明确使用API,客户端将期望数据格式本质上不是令人愉悦的超媒体,并且可以在不明确设置Accept标头的情况下更容易地使用.换句话说,API暗示您期望JSON或XML而不是XHTML.
这是在服务器端逻辑上分离资源表示的问题吗?
我能想出为什么有人会用API子域设计URI的唯一理由是,基于我的假设,这是一种扩展技术,它应该使多层服务器基础设施中的路由请求加载更容易.也许情况下反向代理正在剥离标题?我不知道.处理不同表示的不同服务器?
也许子域仅用于外部使用者,以便服务器避免内部使用的开销.限速?
我错过了一点吗?
我提议的设计会尝试通过设置适当的标头来遵循RESTful实践,适当地使用HTTP谓词并以一种方式表示资源,我觉得在URI中包含'API'将是多余的.
为什么有人会在URI中使用'API'设计RESTful API?
或者他们可以吗?也许我不理解这个设计的问题是,只要它遵循一些规范的组合,这可能不会导致RESTful API实现但是接近,这无关紧要?键盘猫皮肤的方法不止一种. HATEOAS有关吗?
更新:在研究这个主题时,我得出结论,重要的是要考虑来自REST的想法,而不是将其视为宗教.因此,在URI中是否具有"api"更多的是设计决策而不是坚定的规则.如果您计划公开公开您的网站的API,最好使用api子域来帮助处理应用程序的逻辑.我希望有人能为他人贡献自己的洞察力.
我正在为这个服务设计一个资源,它有一组可变属性和一组不可变属性(例如,status由服务生成而不是客户端可能更改的内容).
我需要将此包含在对GET资源请求的响应中,但如果有人随后通过PUT请求发送资源,我不知道该怎么办.
强制调用者知道哪些属性是不可变的感觉是错误的,但是默默地丢弃更新也感觉不正确.响应PUT请求的更新资源可能会解决问题,但它不完美,因为调用者不应该对其请求和服务的响应进行区分,以确定是否接受了属性.
对正确前进的任何想法?
PS我看了如何更新REST资源?但它与这个问题不同,并且促进了过于繁琐的API设计.
我目前正在为图像共享应用程序创建一个API,该应用程序将在网络上运行,并在将来的某个时间在移动设备上运行.我理解API构建的逻辑部分,但我仍然在努力满足自己对身份验证部分的要求.
因此,我的API必须是全世界都可访问的:具有访客访问权限(例如,未登录的人可以上载)以及注册用户.因此,当注册用户上传时,我显然希望将用户信息与请求一起发送,并通过我的数据库中的外键将该用户信息附加到上载的图像.
我已经明白OAuth2是API身份验证的方法,所以我要实现这一点,但我真的很想知道如何处理我的情况.我想到使用client credentials授权并为我的Web应用程序仅生成一组凭据,并让它向API发送请求,client secret以获取访问令牌并让用户执行操作.用户注册过程本身将使用此授权进行处理.
但是当用户注册并登录时呢?我现在如何处理身份验证?这是否需要另一笔补助金来接管?我在考虑在用户登录期间进行一些授权过程,以生成新的访问令牌.这种方法有误吗?
我需要你的输入如何正确处理我的情况下的身份验证流程.这种双向身份验证过程可能不是我需要的,但它是我理解它的方式.我非常感谢您的支持.
authentication api-design credentials user-accounts oauth-2.0
例如,而不是
void shared_ptr::reset() noexcept;
template <typename Y>
void shared_ptr::reset(Y* ptr);
Run Code Online (Sandbox Code Playgroud)
人们可能会想到
template <typename Y = T>
void shared_ptr::reset(Y* ptr = nullptr);
Run Code Online (Sandbox Code Playgroud)
我认为这里的性能差异可以忽略不计,第二个版本更简洁.有没有具体的原因C++标准是第一种方式?
在同样的问题已经被问了科特林语言,默认参数为首选那里.
更新:
std::unique_ptr::reset()遵循默认参数设计(参见此处).所以我认为std::shared_ptr::reset()使用重载的原因是因为它们有不同的异常规范.
c++ api-design overloading language-lawyer default-arguments
我的理解是numpy中的1-D数组可以被解释为面向列的向量或面向行的向量.例如,具有形状的1-D阵列(8,)可以被视为形状(1,8)或形状的2-D阵列,(8,1)这取决于上下文.
我遇到的问题是我编写的用于操作数组的函数在2-D情况下倾向于很好地推广以处理向量和矩阵,但在1-D情况下则不太好.
因此,我的函数最终会做这样的事情:
if arr.ndim == 1:
# Do it this way
else:
# Do it that way
Run Code Online (Sandbox Code Playgroud)
甚至这个:
# Reshape the 1-D array to a 2-D array
if arr.ndim == 1:
arr = arr.reshape((1, arr.shape[0]))
# ... Do it the 2-D way ...
Run Code Online (Sandbox Code Playgroud)
也就是说,我发现我可以概括代码来处理2-d的情况下(r,1),(1,c),(r,c),但也不是没有分支或重塑1-d的情况.
当函数在多个数组上运行时,它会变得更加丑陋,因为我会检查并转换每个参数.
所以我的问题是:我错过了一些更好的成语吗?我上面描述的模式是否与numpy代码相同?
此外,作为API设计原则的相关问题,如果调用者将1-D数组传递给返回新数组的某个函数,并且返回值也是向量,则通常的做法是重新形成2-D向量(r,1)或(1,c)回到1-D数组或简单地说明该函数返回2-D数组而不管?
谢谢
我的问题是在为API目的构建URL时嵌套资源的优势.考虑以下两种用于访问员工资源的备选方案:
/api/employees?department=1 # flat
Vs.
/api/departments/1/employees # nested
Run Code Online (Sandbox Code Playgroud)
现在考虑开发通用库以从API访问REST资源的任务.如果所有路由都是平坦的,那么这样的REST包装器库只需要知道被访问资源的名称:
store.query('employees', {department_id:1}) => /api/employees?department=1
Run Code Online (Sandbox Code Playgroud)
但是,如果我们要支持嵌套路由,那么这个包装器需要知道有关嵌套模型和其他资源的额外信息,以便了解如何构建用于引用此类模型的URL.鉴于并非所有模型都嵌套在相同的父资源下,甚至一些模型根本不会嵌套,REST包装器库需要具有某种配置来描述所有这些额外的知识,否则这些知识是不需要的.
所以我的问题是:
API中的嵌套资源路由是否有任何实际优势?(这并不意味着最终用户使用,因此拥有更漂亮的URL可以获得更少的收益).
嵌套方法是否真的比平面更好,超越美学,以便证明为支持资源URL构建缺乏统一性而引入的额外努力和复杂性?
另见:https://stackoverflow.com/a/36410780/621809
更新:重要的澄清
我从一些评论和答案中了解到,我对一个方面不够清楚:我并不反对使用/employees/5或等URL来处理单个资源/departments/1.我不认为这是嵌套的.
当我说嵌套资源时,我指的是像/departments/1/employees资源一直在另一个资源的上下文中寻址的URL .主要问题是,对于URL构建,通用库需要知道额外的东西,如"员工嵌套在部门下",但"分支不嵌套在任何东西下".如果所有资源都可以通过REST来解决,但是以平面方式解决,知道如何解决它们会更简单,更容易预测.
当您考虑它时,在数据库中,您不需要知道额外的信息,以便知道如何处理对象集合(例如RDMS中的表).您总是将员工集合称为employees,而不是departments/5/employees.
注意:问题已更新,以解决评论中提出的问题,并强调问题的核心是运行时和驱动程序API之间的相互依赖性
CUDA运行时库(如CUBLAS或CUFFT)通常使用"句柄"的概念来概括这种库的状态和上下文.使用模式非常简单:
// Create a handle
cublasHandle_t handle;
cublasCreate(&handle);
// Call some functions, always passing in the handle as the first argument
cublasSscal(handle, ...);
// When done, destroy the handle
cublasDestroy(handle);
Run Code Online (Sandbox Code Playgroud)
但是,有许多关于这些句柄如何与Driver-和Runtime上下文以及多个线程和设备进行互操作的细微细节.该文档列出了有关上下文处理的若干分散细节:
"CUDA编程指南"中对上下文的一般描述,请访问http://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#context
处理多个上下文,如"CUDA最佳实践指南"中所述,网址为http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/index.html#multiple-contexts
运行时和驱动程序API之间的上下文管理差异,请参阅http://docs.nvidia.com/cuda/cuda-driver-api/driver-vs-runtime-api.html
CUBLAS上下文的一般描述为/处理http://docs.nvidia.com/cuda/cublas/index.html#cublas-context和他们的线程安全http://docs.nvidia.com/cuda/cublas/index的.html#线程安全2
然而,一些信息似乎并不完全是最新的(例如,我认为应该使用cuCtxSetCurrent而不是cuCtxPushCurrent和cuCtxPopCurrent?),其中一些似乎是在"主要上下文"处理通过驱动程序API公开之前的一段时间,有些部分过于简单,因为它们只显示最简单的使用模式,只制作关于多线程的模糊或不完整的语句,或者不能应用于运行时库中使用的"句柄"的概念.
我的目标是实现一个提供自己的"句柄"类型的运行时库,并允许在上下文处理和线程安全方面与其他运行时库等效的使用模式.
对于只能使用Runtime API在内部实现库的情况,事情可能很清楚:上下文管理完全由用户负责.如果他创建自己的驱动程序上下文,则将适用有关运行时和驱动程序上下文管理的文档中陈述的规则.否则,Runtime API函数将负责主要上下文的处理.
但是,可能存在库在内部必须使用Driver API的情况.例如,为了将PTX文件作为CUmodule对象加载,并从中获取CUfunction对象.当库 - 应该 - 对于用户 - 表现得像运行时库,但内部必须使用驱动程序 API时,会出现一些关于如何在"引擎盖下"实现上下文处理的问题. …
"API设计就像性:做出一个错误并在你的余生中支持它" (Josh Bloch在Twitter上)
Java库中存在许多设计错误.Stack extends Vector(讨论),我们无法在不造成破损的情况下解决这个问题.我们可以尝试弃用Integer.getInteger(讨论),但它可能会永远存在.
尽管如此,某些类型的改装可以在不造成破损的情况下完成.
有效的Java第2版,第18项:首选接口到抽象类:现有的类可以很容易地进行改进,以实现新的接口".
例如:String implements CharSequence,Vector implements List,等.
有效的Java第2版,第42项:明智地使用varargs:您可以改进现有方法,该方法将数组作为其最终参数,而不是对现有客户端采取varags.
一个着名的例子是Arrays.asList引起混淆(讨论),但没有破坏.
这个问题是关于不同类型的改造:
void不破坏现有代码的情况下改进返回方法的方法?我最初的预感指向是,因为:
void退货换货是合法的(但不是相反!)Class.getMethod也不会在返回类型上区分但是,我希望听到其他在Java/API设计方面经验丰富的人进行更全面的分析.
正如标题中所建议的那样,一个动机是促进流畅的界面风格编程.
考虑这个简单的代码片段,它打印一个混洗的名称列表:
List<String> names = Arrays.asList("Eenie", "Meenie", "Miny", "Moe");
Collections.shuffle(names);
System.out.println(names);
// prints e.g. [Miny, Moe, Meenie, Eenie]
Run Code Online (Sandbox Code Playgroud)
已经Collections.shuffle(List)被宣布为返回输入列表中,我们可以这样写:
System.out.println(
Collections.shuffle(Arrays.asList("Eenie", …Run Code Online (Sandbox Code Playgroud) api-design ×10
rest ×3
c++ ×1
credentials ×1
cuda ×1
http ×1
java ×1
javascript ×1
jcuda ×1
jvm ×1
numpy ×1
oauth-2.0 ×1
overloading ×1
python ×1
restful-url ×1
scalability ×1
uri ×1
web-services ×1