samedi 13 janvier 2018

Generating different results from Web API call using an Anonymous type

I am trying to figure out the best way to return scatterplot data from API call. This is a graph that plots scores for the selected empoyees.

My requirement are that the caller can specify one of a number of scores for each axis, either a named result score, an attributeId score or a domainId score.

So in total there would be 30 total possibilities for the returned results.

enter image description here

API Call:

[HttpPost("{id}/scatterplot")]
public ActionResult Scatterplot([FromRoute] int id, [FromBody] ScatterplotAxis axis)

ScatterplotAxis .cs

public class ScatterplotAxis
{
    public Axis XAxis { get; set; }
    public Axis YAxis { get; set; }
}

public class Axis
{
    public int? TeamId { get; set; }  // optional
    public string NamedScore { get; set; }
    public int? AttributeId { get; set; }
    public int? DomainId { get; set; }
}

So the idea is that you can call it with data such as:

{
  "xAxis": {
    "teamId": 1362,
    "namedScore": "NamedScore2",
    "attributeId": null,
    "domainId": null
  },
  "yAxis": {
    "teamId": 1362,
    "namedScore": "",
    "attributeId": 35,
    "domainId": 0
  }
}

So in the above example I would want to return a result with the score for 'NamedResult2' on X axis and the score for the given attributeId on the Y axis.

My problem is that I am trying to get what has been selected from the posted json and shape the results:

So far I have:

 var employees = ... // omitted for brevity
 // get employees and filter by teamId if it is supplied...

 var xAxisSelection = FindAxisSelection(axis.XAxis);
 var yAxisSelection = FindAxisSelection(axis.YAxis);

 if (xAxisSelection == "NotFound" || yAxisSelection == "NotFound")
     return BadRequest("Axis Selection not Found");

        // e.g. would have to do something like this for all 30 combinations using if/else
        // if(xAxisSelection == "NamedScore2" && yAxisSelection == "Attribute")

        var results = employees.Select(e => new
        {
            Id = e.Id,
            FullName = e.FullName,
            TeamName = e.MemberTeams.FirstOrDefault() == null ? "" : e.MemberTeams.FirstOrDefault().Name,

            // how to do this for all combinations???
            XAxis = e.NamedScores.NamedResult2,  
            YAxis = e.AttributeResults.Where(a => a.AttributeId == axis.YAxis).Score
        }).ToArray();

        return Ok(results);
    }

    private string FindAxisSelection(Axis axis)
    {
        if (axis.AttributeId != null || axis.AttributeId > 0)
            return "Attribute";
        else if(axis.DomainId != null || axis.DomainId > 0)
            return "Domain";
        else if(axis.NamedScore == "NamedScore1")
            return "NamedScore1";
        else if (axis.NamedScore == "eq")
            return "EQ";
        else if (axis.NamedScore == "cq")
            return "CQ";
        else if (axis.NamedScore == "sq")
            return "SQ";

        return "NotFound";
    }

So my question is regarding generating the results. I do not really want to use a massive if else statement block for each of the 30 combinations. Are there any design patterns I should use to make this cleaner and more efficient.

I think its best to use anonymous type so that I don't have to create concrete types for each of the 30 combinations?

I hope this is clear - sorry it's quite difficult to explain. Appreciate any help on this.

Aucun commentaire:

Enregistrer un commentaire