为我的软件创建 API - 基本代码结构
我目前正在编写一个网络软件,客户端桌面也将通过 API 使用该软件。 我现在面临的问题是:我是否应该在应用程序中执行两次添加/更新/删除对象的每个操作? 一旦它位于正常代码中并为 API 隔离一次?
或者我应该更愿意使用 OOP 模型类系统来表示数据库中的所有对象并将它们用于 API 和普通代码?
或者直接开发 API 并从我的普通 Web 界面中使用它?
这是我一直想知道的事情。 提前致谢!
I'm currently writing a web software which is also going to be used by Client desktops via an API.
The problem I'm facing right now is: Should I implement every action of adding/updating/deleting objects in the application twice? Once as it sits in the normal code and once isolated for the API?
Or should I much rather use a system of OOP model classes that represent all objects in my database and use those for both the API and normal code?
Or develop the API first hand and use it from my normal web interface too?
This is something I have always wondered about. Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
做两次事情几乎总是一个坏主意——你最好实现 API,将其开放给最终用户,并将其也用于客户端代码,并为接口的东西提供一些额外的钩子-具体的。
Doing things twice is almost always a bad idea -- you're probably better off implementing the API, opening it up to the end-user, and also using it for the client code as well, with some extra hooks for stuff that is interface-specific.
这就是我们拥有 REST(和 SOAP)协议的原因。
桌面向您的 Web 应用程序发出 RESTful 请求。 您的 Web 应用程序接收 REST 请求并执行实际工作。
您的代码只存在于一个地方——网络。
This is why we have the REST (and SOAP) protocols.
The desktop makes RESTful requests to your web application. Your web application receives the REST requests and does the real work.
Your code exists in exactly one place -- the web.
首先我想说一下我的经验是使用 Django,它是一个丰富的 Web 框架,已经提供了 ORM。 我必须创建模型来代表我的对象; 我不执行原始sql。
所以我自然会推荐你的第二种方法。 我马上就会说你的第三种方法会让人头疼。 为什么? 因为您需要进行不同的后处理。 这就是游戏的本质。 当您在网络上建立 CRUD 界面时,某些内容将作为字段存储在模型中,用户甚至无法从 CRUD 页面中识别这些内容。 举个例子,我有一个新闻报道的 CRUD 页面,其中有不同的公司与之关联。 (这是数据库外键。)当然,这是由登录信息自动提供的。 但登录网页的过程(以及存储登录信息的位置)将与远程 API 非常不同。
我的偏好是将前两种方法结合起来。 每次保存对象时肯定应该发生一些操作。 将它们放入
save()
方法中(或者如果您想进一步分解,则将其放入update()
和insert()
方法中)。 您不应该考虑两次实现此功能。然而,反序列化/对象构造和验证在 Web 界面和远程 API 中的发生方式有所不同。 这确实应该单独实施。
人们还可能将验证视为与反序列化本质上不同,并认为某些规则是相同的,而另一些规则是不同的。 例如,在 Web 界面中,我知道当我收到故事时,我会自己标记
modification_time
,而对于远程 API,我相信客户端会标记时间。 这是故意的。 另一方面,任何没有标签的故事都必须接收一个default
标签,无论它来自哪里。 您可能更喜欢自由地使验证器对象在对象构造后插入。代码示例(Python 中):
当然,我只处理了
insert
或可能update
的情况。 调用这些函数需要的是一些方法拆分器,它知道远程 api 何时调用insert
与delete
并相应地调用不同的函数(对于网络界面也是如此)。 如果您使用的是 Web 框架,这很可能是 Web 界面部分的 urlconfig。First let me say that my experience is with Django, which is a rich web framework that already provides an ORM. I have to create models to represent my objects; I execute no raw sql.
So naturally I would recommend your second approach. Right off the bat I'll say that your third approach will be a headache. Why? Because you're going to want to do different post-processing. That's the nature of the game. When you put up a CRUD interface on the web, some things will be stored as fields in your model that the user wouldn't even recognize from the CRUD page. As an example, I have a CRUD page for news stories that have different companies associated with it. (This is a database foreign key.) Naturally, this is automatically supplied by login information. But the process for logging into the webpage (and where that login is stored) will be very different than for a remote API.
My preference is to combine a little bit of your first two approaches. There should definitely be actions that should occur every single time an object is saved. Put those in a
save()
method (orupdate()
andinsert()
if you want to break things up a bit more). You should not think about implementing this functionality twice.However, there is deserialization/object construction and validation that will occur differently in the web interface and the remote API. This really ought to be implemented separately.
One might also look at validation as inherently different from deserialization and consider that some rules will be the same and others will be different. For example, in a web interface, I know that when I receive the story, I stamp the
modification_time
myself, whereas for a remote API, I trust the client to stamp the time. This is intentional. On the other hand, any story that has no tags on it MUST receive adefault
tag, regardless of where it comes from. You might prefer the liberty to make validator objects to just plug in after object construction.A code example (in python):
Granted, I have only handled the case of
insert
or possiblyupdate
. What you need calling these functions is some method splitter, something that knows when the remote api is callinginsert
versusdelete
and calls a different function accordingly (and likewise for the web interface). If you are using a web framework, this might well be your urlconfig for the web interface portion.REST 几乎已经成为通过网络为客户端提供 API 的标准,并为您提供了很大的灵活性和灵活性。 力量也是如此。 如果您在 .net 平台上工作,您实际上可以使用 ASTORIA [ADO.Net Data Services],它通过简单地映射数据库对象来生成基于 REST 的 Web 服务。
REST has pretty much become a standard for providing an API over the web for the clients and gives you lot of flexibility & power as well. If you are working on .net platform, you can actually use ASTORIA [ADO.Net Data Services] which generates your REST based webservice by simply mapping your database objects.