Mattia Durli
Mattia Durli

Reputation: 767

Sending a List of heterogeneous objects

I have a series of "Messages" to be sent to a server application from a mobile client. Each message has some common information (MAC, timestamp etc) and its So ObjMessage is the base class that has a MessageInfo and a TransactionInfo class, then I have a ObjReqMsg1 and ObjReqMsg2 that differ for a int and string property, just for test.

// Messaging classes

[ProtoContract]
public class MessageInfo
{
    [ProtoMember(1)]
    public string MAC { get; set; }
    [ProtoMember(2)]
    public string version { get; set; }
    [ProtoMember(3)]
    public Guid guidMessage { get; set; }
    [ProtoMember(4)]
    public DateTime timeGenerated { get; set; }
}

[ProtoContract]
public class TransactionInfo
{
    [ProtoMember(1)]
    public string user1 { get; set; }
    [ProtoMember(2)]
    public string user2 { get; set; }
    [ProtoMember(3)]
    public DateTime timeOperation { get; set; }
}


[ProtoContract]
public class ObjMessage
{
    [ProtoMember(1)]
    public TransactionInfo transactionInfo { get; set; }
    [ProtoMember(2)]
    public MessageInfo messageInfo { get; set; }
}

// LIST of different messages

[ProtoContract]
public class ObjReqMsg1 : ObjMessage
{
    [ProtoMember(1)]
    public int intValue { get; set; }
}

[ProtoContract]
public class ObjReqMsg2 : ObjMessage
{
    [ProtoMember(1)]
    public string stringValue { get; set; }
}


[ProtoContract]
public class ReqListMessages : IReturn<RespListMessages>
{
    [ProtoMember(1)]
    public List<ObjMessage> objsReqMessage { get; set; }
}

All my tests are done with json and protocol buffers, and sending single messages of lists of eterogeneous messages works.

My questions are: 1) my idea, instead of sending ten ObjReqMsg1 requests, is to make just one request with a List<ObjReqMsg1>, to save on network calls. It works and it actually saves some time, does it make sense? Or it would be more correct to make the 10 calls?

2) Then, if it makes sense and is the right path, i thought it would be great instead of making two List<ObjReqMsg1> and List<ObjReqMsg2> calls, to make a single List<ObjMessage> call, and on the server check if each ObjMessage is ObjReqMsg1 or ObjReqMsg2 , cast and act accordingly.Is it feasible?

If it is, what am I doing wrong, because, when I create a List<ObjMessage> adding 3 ObjReqMsg1 and 3 ObjReqMsg2, and checking with inspector that intValue and stringValue are present, when I do:

string serialized = ServiceStack.Text.JsonSerializer.SerializeToString<ReqListMessages>(reqListMessage);

I don't find intValue and stringValue serialized.

And obviously on the server side I receive a list of 6 ObjMessage, instead of a list of 3 ObjReqMsg1 + 3 ObjReqMsg2.

Can you help? Thanks

Upvotes: 2

Views: 125

Answers (2)

Martin Tapp
Martin Tapp

Reputation: 3396

You should consider using a variant (i.e union) for clients to better expect the possible data variability. Otherwise, your clients will be coupled to the service.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1063338

1: in most API scenarios, sending fewer chunkier requests is usually the simplest way of improving performance; "does it make sense" depends on the context, but if it makes sense to you then: probably

2: add [ProtoInclude(5, typeof(ObjReqMsg1))] and [ProtoInclude(6, typeof(ObjReqMsg2))] to the class ObjMessage declaration, and try again.

Re "cast and act accordingly" - you might also consider polymorphism, i.e. a virtual or abstract method on ObjMessage that ObjReqMsg1 and ObjReqMsg2 can override. Then you don't have to do anything; you just call obj.TheMethod(args).

Upvotes: 2

Related Questions