jeudi 13 janvier 2022

JSON deserialization for multiple messages design pattern C#?

I have a use case in which a .net app is running in the background and listening for Kafka messages. I will receive various payloads/messages from Kafka. Each payload has different structure and contains different items in it. For each payload, we must deserialize it into its own entity(not always be one to one mapping, there can be some mapping logic for payload to the entity in some cases), each of which has its own table in the database. So, after deserialization, these entities must be saved in a database and also sent to another Kafka topic.

Broadly I have divided this whole flow into 3 parts maintaining SRP. One will be deserialization, second will be database save and third will be Kafka.

I am currently implementing deserialization as shown below:

First payload examples:

{
   "type":"fuel",
   "data":{
      "fueltype":"petrol",
      "mileage":23.76,
      "tankcapacity":37
   }
}

{
   "type":"engine",
   "data":{
      "enginetype":"K series",
      "maxpower":88.50,
      "displacement":1197
   }
}

So these messages are differentiated using the type

For code I thought of using individual parsers for each type

public interface IJsonParser
    {
        Payload Parse(dynamic data);
    }

 public class FuelParser : IJsonParser
    {
        public Payload Parse(dynamic payload)
        {
            Fuel f = new Fuel();
            f.Mileage = (float)payload.data.mileage;
            return f;
        }
    }

    public class EngineParser : IJsonParser
    {
        public Payload Parse(dynamic data)
        {
            Engine e = new Engine();
            return e;
        }
    }



public class Payload
    {
        public int Id { get; set; }
    }

 public class Fuel : Payload
    {
        public string FuelType { get; set; }
        public float Mileage { get; set; }
        public int TankCapacity { get; set; }
    }

 public class Engine : Payload
    {
        public string EngineType { get; set; }
        public float MaxPower { get; set; }
        public int Displacement { get; set; }
    }
 


 public static class JsonParserFactory
    {
        public static IJsonParser GetJsonParser(string type)
        {
            switch (type)
            {
                case "fuel":
                    return new FuelParser();
                case "engine":
                    return new EngineParser();
                default:
                    return null;
            }
        }
    }

string message = "{\r\n\t\"type\": \"fuel\",\r\n\t\"data\":\r\n\t\t{\r\n\t\t\t\"fueltype\": \"petrol\",\r\n\t\t\t\"mileage\": 23.76,\r\n\t\t\t\"tankcapacity\": 37\r\n\t\t}\r\n}";
            dynamic data = JsonConvert.DeserializeObject<object>(message);

            IJsonParser parser = JsonParserFactory.GetJsonParser(data.type.ToString());
            var model = parser.Parse(data);// This model will then be saved in DB as well as sent to another Kafka topic which is the 2nd and 3rd part of the flow.

So based on the type I have create a Factory which is creating the individual parsers.

I just wanted the suggestion if this is a good design. My only concern is in the future there will be multiple types of payloads coming which will then increase the number of parsers as we go along.

Any suggestions?

Aucun commentaire:

Enregistrer un commentaire