需要一些Web服务API的建议吗?

时间:2011-03-02 14:05:50

标签: wcf web-services design-patterns

我的公司有一个产品,我觉得可以从Web服务API中受益。我们使用MSMQ通过后端系统来回传递消息。目前,我们正在构建一个ASP.Net应用程序,该应用程序与Web服务(WCF)进行通信,而Web服务又为我们与MSMQ进行通信。稍后,我们可能会有其他客户端应用程序(不一定用.Net编写)。进入MSMQ的消息是一个具有由字符串数组组成的属性的对象。还有一个属性包含将通过系统路由的命令(字符串)。就个人而言,我并不是一个忠实的粉丝,但我被告知这是为了扩展性,每个系统都可以使用字符串。

我的想法,关于Web服务是基于我们的数据建模一些对象,这些对象可以传入和传出Web服务,因此客户端可以轻松使用它们。最初,我正在传递上面提到的消息对象,其中包含字符串数组。我发现我在客户端上创建对象来表示数据,使客户端负责创建这些对象。我觉得Web服务层应该真正处理这个问题。这就是我一直使用服务的方式。我这样做了,所以我更容易在客户端周围移动数据。

建议我们的小组通过提供包含命令的对象并使用一个Web服务来处理所有内容,从而将“单一入口点”保留到系统中。因此,Web服务中将有一个方法,让我们称之为MakeRequest,它将返回一个对象(序列化的XML或JSON)。建议是让一个基础对象可能包含某种其他对象可以继承的命令列表。任何其他对象可能具有自己的命令结构,但仍继承基本命令。从服务传回来的内容目前尚不清楚,但它可能是“消息对象”,其中附加了一个表示数据的对象。我不知道。

我的建议是在实际数据之后对对象进行建模,并为我们正在使用的数据类型创建服务。我们将创建一个基本服务接口,其中包含用于所有服务的任何常用方法。例如,GetById,GetByName,GetAll,Save等。特定于给定服务的任何内容都将针对该特定实现实现。因此,用户服务可能有GetUserByUsernameAndPassword方法,但由于它实现了基本接口,因此它还包含“基本”方法。我们将在服务中有几个方法,它们将根据被调用的服务返回预期的对象类型。我们可以将所有东西都放在一个服务中,但我仍然希望得到一些更有用的东西。我觉得这种方法让客户无法决定要传递什么命令。当我连接到用户服务并调用方法GetById(int id)时,我希望得到一个User对象。

当我开始开发WCF服务时,我有幸与MS合作。所以,我对这项技术有很好的基础和理解,但这次我不是那个设计它的人。 因此,我并不反对“单一切入点”的想法,但任何关于为什么这两种方法比另一种方法更具可扩展性的想法都将受到赞赏。我以前从未使用过这种系统的方法来处理服务层。也许我需要克服它?

1 个答案:

答案 0 :(得分:1)

我认为两种方法都有优点。

通常,如果您正在编写一个将由完全独立的开发人员组(可能在另一家公司中)使用的API,那么您希望API尽可能自我解释并且可被发现。从消费者的角度来看,具有返回特定对象的特定Web服务方法更容易使用。

但是,许多公司将Web服务用作其应用程序的多个层之一。在这种情况下,它可以减少维护以具有通用API。我已经看到一些聪明的机制,不需要对服务进行任何更改,以便将另一列添加到从数据库返回的表中。

我个人偏好针对特定的API。我认为具体的方法更容易使用 - 并且主要是自我记录。具体操作需要在某个时刻执行,那么为什么不将它暴露出来呢?如果你写的话,你会被嘲笑:

public void MyApiMethod(string operationToPerform, params object[] args)
{
    switch(operationToPerform)
    {
        case "InsertCustomer":
            InsertCustomer(args);
            break;
        case "UpdateCustomer":
            UpdateCustomer(args);
            break;
        ...
        case "Juggle5BallsAtOnce":
            Juggle5BallsAtOnce(args);
            break;
    }
}

那为什么要使用Web服务呢?拥有它会好得多:

public void InsertCustomer(Customer customer)
{
    ...
}

public void UpdateCustomer(Customer customer)
{
    ...
}

...

public void Juggle5BallsAtOnce(bool useApplesAndEatThemConcurrently)
{
    ...
}