locked
Creating an Endpoint that can read any json. A generic endpoint API RRS feed

  • Question

  • User-1204637165 posted

    So I have a requirement to have one endpoint that can read json payload that can hit it from different system. We have several partners that would be posting data to our system.  So we want one endpoint that would handle getting data from any of our partners posting data.

    I have something like this already.

    [HttpPost]
    public string Getdata([FromBody]Object data)
    {
    
      //how do I convert it to the specific class that sooths the  json payload.
    
      //Or how do I read the data attribute of the object data pasted without knowing the payload structure.
    }

    I need to be able to create a generic json reader like this system here

    https://quicktype.io/csharp/

    So when data hits me I can read the data.

    Best Regards,

    Thanks in Advance

    Wednesday, May 27, 2020 9:29 AM

Answers

  • User475983607 posted

    The partners are already populating two different objects why can't you simply provide each with a different URL?  Seems like a non-issue.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, May 31, 2020 5:08 PM

All replies

  • User753101303 posted

    Hi,

    Or you could use https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsondocument?view=netcore-3.1 to inspect the json payload. Else you have https://docs.microsoft.com/en-us/dotnet/api/system.reflection?view=dotnet-plat-ext-3.1 if you want to inspect an object.

    Note sure about your design. You'll forward that to something strongly typed or you are supposed to handle any unkown json payload a partner could post ? Make sure to not make things harder than needed.

    Wednesday, May 27, 2020 9:54 AM
  • User2078676645 posted

    Hi,

    You can use the Nuget installation package JsonToCSharp, and then try this code:

    public class Program
        {
            public static void Main(string[] args)
            {
                JsonToCsharp toc = new JsonToCsharp();
                IEnumerable<CsharpClass> o= toc.Convert("{'animal':{'id':'1','name':'tt'}}");
                
                for(var i = 0; i < o.Count(); i++)
                {
                    Console.WriteLine(o.First().ClassName);
                }
            }
        }

    Regards,

    Evern
     

    Wednesday, May 27, 2020 10:08 AM
  • User475983607 posted

    So when data hits me I can read the data.

    Reading the data is not the problem,   The problem is what to do with the data; the intent.  If you do not know what to expect then how do you know what to do with the data or what the data means?  Can you explain the application design or intended?

    Wednesday, May 27, 2020 10:09 AM
  • User-1204637165 posted

    Dear All,

    Thanks for you feedbacks, We have decided to simplify the requirements. So we are giving each partner a data format to send to us.

    So we want one single endpoint to handle all partners.

    public class PartnerARequest{
    
      public string Firstname{get;set;}
    
      public string Lastname{ get;set;}
    
    }
    
    
    public class PartnerBRequest{
    
      public string School{get;set;}
    
      public string NumbersofPupils{get;set;}
    
      public string ContactPerson{get;set;}
    }

    So right now I just need to determine which request is been posted then I convert the object request to the particular class.

    Thanks alot.

    Best Regards.

    Wednesday, May 27, 2020 5:57 PM
  • User-1204637165 posted

    so I saw something like this online

    Object.getClass().equals(this.getClass()) not sure would test and get back. if you have better suggestion let me know thanks.

    Wednesday, May 27, 2020 6:00 PM
  • User-474980206 posted

    its:

    [HttpPost]
    public string Getdata([FromBody] JsonElement data)
    {
      if (data.ValueKind == JsonValueKind.Object)
      {
         foreach (JsonProperty p in data.EnumerateObject())
         {
             Console.WriteLine($@"name: {p.Name} type: {p.Value.ValueKind}");
         } 
      }
    
    ...
    }

    see JsonDocument documentation:

    https://docs.microsoft.com/en-us/dotnet/api/system.text.json?view=netcore-3.1

    Wednesday, May 27, 2020 7:16 PM
  • User753101303 posted

    This is Java code for testing if two objects have the same class. 

    If you really want to follow this path, If found https://www.codementor.io/blog/batch-endpoints-6olbjay1hd

    For example rather than posting {"name":"me"} to /baselocation/user you could post {"user":{"name":"me"}} to /baselocation. This way you can read the first property name to get the "virtual endpoint" to which this query should be directed.

    Wednesday, May 27, 2020 7:38 PM
  • User-474980206 posted

    InspiredJide

    Dear All,

    Thanks for you feedbacks, We have decided to simplify the requirements. So we are giving each partner a data format to send to us.

    So we want one single endpoint to handle all partners.

    public class PartnerARequest{
    
      public string Firstname{get;set;}
    
      public string Lastname{ get;set;}
    
    }
    
    
    public class PartnerBRequest{
    
      public string School{get;set;}
    
      public string NumbersofPupils{get;set;}
    
      public string ContactPerson{get;set;}
    }

    So right now I just need to determine which request is been posted then I convert the object request to the particular class.

    Thanks alot.

    Best Regards.

    a better approach is a generic request object with properties for each request type:

    public class ApiRequest
    {
       public PartnerARequest PartnerARequest {get; set;}
       public PartnerBRequest PartnerBRequest {get; set;}
    ...
    }
    

    then the json will look like:

    // first request
    {
       "PartnerARequest": {
          "Firstname": "bob",
          "Lastname": "Smth"
      }
    }
    
    // second request
    {
       "PartnerBRequest": {
          "School": "!st School",
          "NumbersofPupils": 300,
          "ContactPerson": "John Doe"
       }
    }
    

    in your code you just check which objects are not null.

       if (model.PartnerBRequest != null) ...

    or better yet, use graphQL

       https://graphql.org

    Wednesday, May 27, 2020 10:07 PM
  • User-1204637165 posted
    public class ApiRequest
    {
       public PartnerARequest PartnerARequest {get; set;}
       public PartnerBRequest PartnerBRequest {get; set;}
    ...
    }

    I would have preferred this approach but it wont work. becos the partners would be post the individual object to my endpoint.

    It either Parter A is posting

    public PartnerARequest PartnerARequest {get; set;}

    or

    Partner B is posting

    public PartnerBRequest PartnerBRequest {get; set;}

    So I have to write a code to figure which object is posted. So am thinking of doing a json lookup. Would have used Graphql but I dont konw not familiar with it.

    Sunday, May 31, 2020 1:35 PM
  • User-474980206 posted

    You just check which object is not null. The documentation for the api tells partnera to post

    public class Api
    {
       public PartnerARequest PartnerARequest {get; set;}
    }

    But what is wrong with learning graphQL? 

    Sunday, May 31, 2020 3:56 PM
  • User475983607 posted

    The partners are already populating two different objects why can't you simply provide each with a different URL?  Seems like a non-issue.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, May 31, 2020 5:08 PM
  • User753101303 posted

    So I have to write a code to figure which object is posted.

    This is what you asked for. Either you are using distinct endpoints for each object kind and then you start coding straight away how to process yhis particular object but for some unknown reason you insist on having a single endpoint.

    It is also unusual to have each partner using its own model. You won't increase what they can post or get over time. Graphql is an option but I wouldn't suggest to use it right now if you can't get a simple approach to work.

    Which problem are you really trying to solve? What the problem if you have multiple endpoints? You coudl still use permissions so that all partners can't use all endpoints.

    Monday, June 1, 2020 8:02 AM
  • User-1204637165 posted

    Thanks boss,

    Ordinaryly I would have just choosen different endpoints. but it CTO decision. So for now I am doing a json look up and checking against all the Mandatory parameter posted for each Gateways so I decipher who sent the request.

    So I am using Rest for this not graphql cos that is what the requirement specification says.

    Thanks alot.

    Thursday, June 4, 2020 7:42 AM