我面临 API 设计问题。考虑以下流程:
正如您所看到的,我有 2 个类来代表我的模型(SomethingDTO和SomethingResponse),还有 2 个类来代表第 3 方模型(3rdPartyRequest和3rdPartyResponse)。我正在使用映射器提供从 3rdPARty 模型类到我的模型类的转换。
问题是:这 4 个类都具有完全相同的属性。
我应该在所有这些类中重复这些属性吗?我应该在整个流程中只使用一个 DTO 类吗?
解决这个问题的最佳实践(或模式)是什么?
谢谢
我正在制作一个需要登录的应用程序。
我使用node.js作为API。
我知道我必须在后端加密密码,以防数据库被盗。但是,如果由于某种原因 HTTPS 失败或者我们这边的某些开发人员有恶意,如果前端也没有加密,他/她就可以轻松窃取原始密码。
所以我的问题是,如果我在后端使用 Argon2 并在前端使用 BCrypt 会出现问题吗?
(另外我认为 Argon2 更快,所以如果攻击者想要暴力破解,他也必须使用慢速的,而不是我的 api 重载他/她的 shannigans)
我知道有一些类似的问题,但他们问我是否应该使用其中一个或另一个,答案是后端和 HTTPS。
我将使用 HTTPS 和后端加密。但我问是否也可以(或一个好主意)在前端使用加密。
我有一些代码在C++中有一个动态类系统,它有一个名为GetClassName()的成员,一个人们可以想象的无害的名字.然而,当包含在一个带有Windows标题的大型项目中时,所有地狱都会崩溃.显然,Windows使用#define GetClassName(GetClassNameA或GetClassNameW)搞砸了所有东西,我的虚拟调用树变得一团糟,让我在黑暗中愚蠢的编译器调试中失去了一天,试图弄清楚出了什么问题.
所以除了我诅咒微软使用这样一个非常容易冲突的#define名称这一点之外(我的意思是有人应该诚实地为此拍摄!)我要求3个目的.
我将为Web应用程序开发一个iOS应用程序.(网络应用使用代码点火器)
我将创建一个iOS应用程序将使用的API服务.
我正在考虑创建一个api版本,所以当web api改变时,iOS应用程序就会知道.
关注:
我的iOS应用程序应该指定它所需的api版本吗?
这是最佳做法吗?
我应该为每个版本制作api类并扩展以前的版本并在它们更改时覆盖方法吗?
例
ApiV1 extends CI_Controller
{
function list_customers(){//Code}
function saveSale() {//Code}
}
ApiV2 extends ApiV1
{
function saveSale()
{
//New way of saving sale
}
}
Run Code Online (Sandbox Code Playgroud)
如果我对v1 api不再有效的数据库结构进行更改,会发生什么?(例如,更改了数据库表的名称?)
我在堆栈上有一个对象需要另一个对象作为它的构造函数,如下所示:
{
ObjectDef def(importantData); // should die as soon as obj is created
def.setOptionalData(100);
Object obj(def); // should live for the remainder of the function body
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,我喜欢将变量def放在自己的范围内.这给了我"def"的名字,并且清楚地表明它不再有用了.
例如,result我想做的事情是obj:
// scope block
{
int result = complexFunction() + anotherFunction();
printf("the result is %i", result);
doMoreThingsWithIt(result);
}
// "result" is now gone
Run Code Online (Sandbox Code Playgroud)
但问题是,我无法在这里做到这一点,我可以看到.构造函数Object obj不能在范围之前,因为它是构造函数需要的def,并且它不能在范围内,因为obj需要存活的时间比def.
无论如何要将限制def的范围缩短obj,或者我应该接受它必须至少保持一定的范围?
我想知道,为什么Microsoft开发人员不向我们提供各种不可靠方法的"尝试"版本?
如果我使用数据库连接或smtp客户端,我总是必须考虑例外:
try
{
smtpClient.Send(message);
}
catch (SmtpException)
{
// test with real smtp server and analyze an exception and it's contents here
}
Run Code Online (Sandbox Code Playgroud)
但我想要的用户是:
if(!smtpClient.TrySend(message, out reason))
{
// analyze reason here
}
Run Code Online (Sandbox Code Playgroud)
对我来说最大的问题是异常性能开销.我无法承担在我的服务的每个客户电话上抛出异常.如果我需要检查几十个连接/提供者,这可能会导致每个客户端请求有几十个例外.
我的问题是:.NET中这种API设计决策的基本原理是什么?我不认为这是一个错误,因为它无处不在,而不是单一的技术.
更新
我必须再给你一个.NET异常的例子来停止谈论网络延迟.例如,如果停止了Windows服务,则System.Diagnostics.EventLog.WriteEntry可以抛出方法System.ComponentModel.Win32Exception.
我们有一个REST API,用于一些评论.目前,最有趣的URI是:
GET /products/1/comments // get all comments of product 1
GET /products/1/comments/5 // get the 5th comment of product 1
GET /products/1/comments/5/user // get the user of the 5th comment
GET /products/1/comments/latest // get the latest comment of product 1
GET /products/1/comments/latest/user // get the user of the latest comment
Run Code Online (Sandbox Code Playgroud)
此外,您还可以直接访问评论
GET /comments/987 // get the comment with id 987
GET /comments/987/user // get the user of comment with id 987
Run Code Online (Sandbox Code Playgroud)
所以,我们有两个@RestController:
@RestController
@RequestMapping("/products/{productId}")
public class ProductsCommentsResource …Run Code Online (Sandbox Code Playgroud) 我有两个基本相同的特征,但是一个提供了比另一个更低级别的接口.鉴于较高水平的特性,人们可以轻松实现较低水平的特质.我想写一个接受任一trait实现的库.
我的具体案例是遍历树的特征:
// "Lower level" version of the trait
pub trait RawState {
type Cost: std::cmp::Ord + std::ops::Add<Output = Self::Cost> + std::marker::Copy;
type CulledChildrenIterator: Iterator<Item = (Self, Self::Cost)>;
fn cull(&self) -> Option<Self::Cost>;
fn children_with_cull(&self) -> Self::CulledChildrenIterator;
}
// "Higher level" version of the trait
pub trait State: RawState {
type ChildrenIterator: Iterator<Item = (Self, Self::Cost)>;
fn children(&self) -> Self::ChildrenIterator;
}
// Example of how RawState could be implemented using State
fn state_children_with_cull<S: State> (s: S)
-> impl Iterator<Item = (S, …Run Code Online (Sandbox Code Playgroud) 我已经使用C#在.NET Core 2中创建了一个API。它返回ActionResult带有状态代码和字符串消息的。在另一个应用程序中,我使用Flurl调用API。我可以获取状态码号,但是找不到消息的方式。我如何获取消息,或者需要什么更改API才能以某种方式将消息放入Flurl即可获取?
这是API的代码。在此示例中,“消息”为“对不起!”。
[HttpPost("{orderID}/SendEmail")]
[Produces("application/json", Type = typeof(string))]
public ActionResult Post(int orderID)
{
return StatusCode(500, "Sorry!");
}
Run Code Online (Sandbox Code Playgroud)
这是另一个调用API的应用程序中的代码。我可以使用获取状态代码编号(500),(int)getRespParams.StatusCode并使用获取状态代码文本(InternalError)getRespParams.StatusCode,但是如何获得“抱歉!” 信息?
var getRespParams = await $"http://localhost:1234/api/Orders/{orderID}/SendEmail".PostUrlEncodedAsync();
int statusCodeNumber = (int)getRespParams.StatusCode;
Run Code Online (Sandbox Code Playgroud) 我正在写我的第一个C库,我不知道该走哪条路.例如,从某些数据存储中检索字符串值的函数可以是:
int get_value(void * store, char ** result);
Run Code Online (Sandbox Code Playgroud)
要么
char * get_value(void * store, int * error);
Run Code Online (Sandbox Code Playgroud)
我很难有任何客观的理由偏爱一个人而不是另一个人,但不止于此,我不会写那么多C.当存在多个输出参数时,返回错误代码看起来会更加一致,但返回值可能更容易使用?不确定.
关于哪种风格更好以及为什么或仅仅是个人偏好,是否存在普遍共识?
api-design ×10
c++ ×2
java ×2
rest ×2
.net ×1
api ×1
asp.net-core ×1
c ×1
c# ×1
encryption ×1
exception ×1
flurl ×1
ios ×1
raii ×1
rust ×1
scope ×1
spring ×1
spring-mvc ×1
traits ×1
windows ×1