简体   繁体   English

API架构

[英]API architecture

I am in the process of designing an API. 我正在设计API。 I would like to know if what I have come up with is a good solution: 我想知道我提出的是一个很好的解决方案:

I have a respository type of data layer that talks to a database by converting business classes into entities(generated from LLBL GEN, I didn't want to use the entities directly as my business objects because I wanted to keep them simple and allow me to swap out to Entity Framework or some other mapper is I needed to) 我有一个存储库类型的数据层,通过将业务类转换为实体(从LLBL GEN生成,我不想直接使用实体作为我的业务对象,与数据库对话,因为我想保持它们简单并允许我交换到Entity Framework或其他一些mapper是我需要的)

I have a WCF service layer that I'm using as a type of facade. 我有一个WCF服务层,我正在使用它作为一种外观。 It calls the respository layer and converts the business objects to DTOs and passes them through the API service call via a message to the client. 它调用存储库层并将业务对象转换为DTO,并通过API服务调用将它们传递给客户端。 The client can be an ASPX website, Silverlight app, WPF app, or even a WP7 app. 客户端可以是ASPX网站,Silverlight应用程序,WPF应用程序,甚至是WP7应用程序。 The problem I keep runnnig into is when I want to run business logic I have to send the DTO back to the WCF service and then back to the client. 我保持运行的问题是当我想运行业务逻辑时,我必须将DTO发送回WCF服务然后再返回客户端。 This doesn't seem "right" to me. 这对我来说似乎并不“正确”。 I can't put business logic in the DTO because that defeats the purpose. 我不能把业务逻辑放在DTO中,因为这会破坏目的。 But if I want business type code to run on the client I have a lot of duplication of code throughout my different clients. 但是,如果我想在客户端上运行业务类型代码,那么我的不同客户端会有很多代码重复。

My business layer does not know of the data layer, my data layer knows of the business layer and my facade layer knows of the data layer and the business layer and the DTOs. 我的业务层不知道数据层,我的数据层知道业务层,而我的外观层知道数据层,业务层和DTO。 Is this a bad design for an API? 这对API来说是一个糟糕的设计吗? And can anyone offer me any suggestions? 任何人都可以给我任何建议吗? I have only learned of enterprise level apps through reading different articles online. 我只是通过在线阅读不同的文章了解了企业级应用程序。

Thanks! 谢谢!

Relations between layers 层之间的关系

If I understand your design well, the business layer does not know of (=does not use) the data layer, and the facade actually interconnects them by translating DAOs into DTOs and vice-versa. 如果我理解您的设计,业务层不知道(=不使用)数据层,并且外观实际上通过将DAO转换为DTO来互连它们,反之亦然。

You should consider a rather different approach: Define interfaces for all data-related objects (regardless if DAOs or DTOs) and use an Inversion-of-Control container to weave the business layer and data access layer together. 您应该考虑一种相当不同的方法:为所有与数据相关的对象(无论是DAO还是DTO)定义接口,并使用Inversion-of-Control容器将业务层和数据访问层编织在一起。 The reason is that in your design you might quickly run into the inability to retrieve additional data in right in the business layer. 原因是在您的设计中,您可能很快就会无法在业务层中检索其他数据。 You'd end up with the facade substituting this lack and hence doing too much actual business logic. 你最终会用这个缺点代替这个缺点,因此做了太多的实际业务逻辑。

In case you make a clear connection between the business layer and the underlying data layer, while separating them with well-designed interfaces and an IoC container, you prevent this problem while maintaining good and concise internal design. 如果您在业务层和底层数据层之间建立了明确的连接,同时使用精心设计的接口和IoC容器将它们分开,则可以在保持良好和简洁的内部设计的同时防止出现此问题。

Usage of DTOs DTO的用法

I think it's alright that you have to pass the DTOs back to the back-end of your app. 我认为你必须将DTO传递回应用程序的后端。 In your case the purpose of DTOs is (1) to supply information for the presentation layer, and (2) to provide a way of passing modified or new data to the back-end for further processing. 在您的情况下,DTO的目的是(1)为表示层提供信息,以及(2)提供将修改的或新数据传递到后端以进行进一步处理的方法。 DTOs for cases (1) and (2) need not be the same. 案例(1)和(2)的DTO不必相同。 Hence if it makes sense, you can pass to the back-end just a DTO representing a subset of the whole information. 因此,如果它有意义,您可以传递给后端只是一个代表整个信息子集的DTO。

However, the back-end shall return a new DTO after processing, which, again, needs not to be the same DTO as the input DTO. 但是,后端应在处理后返回一个新的 DTO,同样不需要与输入DTO相同的DTO。 This way the presentation layer can easily adapt to changes made by the back-end into related parts of the whole object. 这样,表示层可以很容易地适应后端对整个对象的相关部分所做的更改。

Imagine a simple Get / Update API such as this one: 想象一下一个简单的Get / Update API,例如:

CustomerDTO GetCustomer(int customerID);

CustomerDTO UpdateCustomerAddress(int customerID, AddressDTO address);

CustomerDTO UpdateCustomerPrimaryContact(int customerID, PersonDTO primaryContact);

You are using an ID to identify a customer and passing in a DTO that represents a subset of the customer record to be updated (regardless of the underlying data architecture). 您使用的ID识别客户,并 DTO表示客户记录的一个子集要被更新传递(基础数据架构的无论)。 The out DTO represents the customer as a whole, simplifying the presentation-layer's task of updating the information shown to the user. out DTO代表整个客户,简化了表示层​​更新显示给用户的信息的任务。 The advantage is the back-end does not need to know which subset of customer data the presentation layer actually needs, and the presentation layer can pass the back-end only those parts that were really modified. 优点是后端不需要知道表示层实际需要哪个客户数据子集,并且表示层只能传递那些真正修改过的部分的后端。

Update — technical note: Consider using a tool like AutoMapper (C#) to automate translations between DTOs and DAOs. 更新 - 技术说明:考虑使用AutoMapper (C#)等工具自动执行DTO和DAO之间的转换。 While this matter is a subject of technology used, generally this approach saves a lot of manual work and is able to eliminate hard-to-discover bugs. 虽然这个问题是所使用技术的主题,但通常这种方法可以节省大量的手工工作,并且能够消除难以发现的错误。 Having such an object translation automation in place helps promote better design practices and allows you to produce more-specialized and hence semantically more accurate DTOs. 实现这样的对象翻译自动化有助于促进更好的设计实践,并允许您生成更专业化,因此语义更准确的DTO。


Disclaimer: While this is a rather general question, my recommendations may not seem right in respect to further details of your application which are not covered in your question. 免责声明:虽然这是一个相当普遍的问题,但就您的申请的进一步细节而言,我的建议似乎并不正确。

My business layer does not know of the data layer, my data layer knows of the business layer and my facade layer knows of the data layer and the business layer and the DTOs. 我的业务层不知道数据层,我的数据层知道业务层,而我的外观层知道数据层,业务层和DTO。 Is this a bad design for an API? 这对API来说是一个糟糕的设计吗?

No layer should know about the layer above. 没有层应该知道上面的层。

I have a WCF service layer that I'm using as a type of facade. 我有一个WCF服务层,我正在使用它作为一种外观。 It calls the respository layer and converts the business objects to DTOs and passes them through the API service call via a message to the client. 它调用存储库层并将业务对象转换为DTO,并通过API服务调用将它们传递给客户端。 The client can be an ASPX website, Silverlight app, WPF app, or even a WP7 app 客户端可以是ASPX网站,Silverlight应用程序,WPF应用程序,甚至是WP7应用程序

Theres a design principle called You Aint Gonno Need It which is the almost the same thing as Keep It Simple (and) Stupid . 这是一个名为You Aint Gonno Need It的设计原理它与Keep It Simple(和)Stupid几乎相同。

They both is all about NOT adding features that you might need. 它们都是关于不添加您可能需要的功能。 If you start with only having a website that uses the service layer, then simply use it directly without a WCF service. 如果您只从一个使用服务层的网站开始,那么只需在没有WCF服务的情况下直接使用它。

If you need a WCF service later on, then add it later. 如果以后需要WCF服务,请稍后再添加。

If you are defining the services using interfaces it's quite to swap a implementation that you are using directly to a WCF service implementation. 如果您使用接口定义服务,则可以将您正在使用的实现直接交换到WCF服务实现。 (if you are using a IoC container ) (如果您使用的是IoC容器

Concretes vs interfaces 混凝土与界面

You should always put the interfaces and business objects in a separate assembly from implementations (classes) to make it easier to swap implementations of each layer. 您应该始终将接口和业务对象放在与实现(类)不同的程序集中,以便更容易地交换每个层的实现。 It's a design pattern called Separated interace which you can read about here: http://martinfowler.com/eaaCatalog/separatedInterface.html 这是一个名为Separated interace的设计模式,你可以在这里阅读: http//martinfowler.com/eaaCatalog/separatedInterface.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM