3

My web api method should return some structured data about my profile. To do it I created the following POCO classes:

public class ProfileInfo
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    //....

    public ProfileAddress Address { get; set; }
    public ProfileDriverLicense DriverLicense { get; set; }
    public ProfileEmergency Emergency { get; set; }
    public ProfileEmployment Employment { get; set; }
    public ProfileCompensation Compensation { get; set; }
    public ProfileFuel Fuel { get; set; }
    public ProfileCompanyInfo CompanyInfo { get; set; }
}

public class ProfileAddress
{
    public string Address { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
}

public class ProfileDriverLicense
{
    //....
}

public class ProfileEmergency
{
    //....
}

public class ProfileEmployment
{
    //....
}

public class ProfileCompensation
{
    //....
}

public class ProfileFuel
{
    //....
}

public class ProfileCompanyInfo
{
    //....
}

So, as you can see, there are many POCO classes which nested one to another.

service method, which fills and returns ProfileInfo object:

    public ProfileInfo GetProfile(string username)
    {
        var profile = _db.Drivers.Where(p => p.AspNetUser.UserName == username).Select(k => new ProfileInfo()
        {
            FirstName = k.AspNetUser.FirstName,
            LastName = k.AspNetUser.LastName,
            Username = username,
            Address = new ProfileAddress()
            {
                Address = k.StreetAddress,
                City = k.City,
                State = k.State,
                Zip = k.ZIP
            },
            AvatarUrl = k.AvatarUrl,
            CompanyInfo = new ProfileCompanyInfo()
            {
                //....
            },
            Compensation = new ProfileCompensation()
            {
                //....
            },
            DateOfBirth = k.DOB,
            DriverLicense = new ProfileDriverLicense()
            {
                //....
            },
            Email = k.AspNetUser.UserName,
            Emergency = new ProfileEmergency()
            {
                //....
            },
            Employment = new ProfileEmployment()
            {
                //....
            },
            Fuel = new ProfileFuel()
            {
                //....
            },
            Phone = k.PhoneNo,
            SSN = k.SSN,
            Notes = k.Notes,
            Truck = (k.Truck != null) ? k.Truck.TruckNo : null,
            Trailer = (k.Trailer != null) ? k.Trailer.TrailerNo : null
        }).FirstOrDefault();

        if (profile == null)
            throw new Domain.InvalidDriverException(username);

        return profile;
    }

and WebAPI method:

    [HttpGet]
    [Route("MyProfile")]
    public HttpResponseMessage GetProfile()
    {
        string username = GetUsernameFromClaims();
        if (String.IsNullOrWhiteSpace(username))
            return Request.CreateErrorResponse(HttpStatusCode.NotFound, "User not found");

        var profile = _serviceDriver.GetProfile(username);
        return Request.CreateResponse<Domain.POCO.Profile.ProfileInfo>(profile);
    }

it works and works fine. But any benefits to use POCO classes in concrete this case? Or I can use dynamic and have the same effect, with much less code and no disadvantages? With dynamic I have not to write all these POCO classes and very easy to modify. I understand, that dynamic works much slowly, not easy to find mistake (no compilation errors), but in result Web API returns JSON, which is not strong type by default. What sense to create and use POCO classes?

PS. I use strong types, it's more comfortable for me :) But probably for concrete case I write much extra-code?

9
  • 2
    no disadvantages? Really? It's slow; you get no intellisense; no compile-time checking of fields, all fields are read/write (admittedly not a problem in your case as your POCOs are read/write too), which in turn makes it harder to maintain the code as those profile fields can be created, read and written to all over the place as there's no central data structure that defines their contents. Yep, you are right: no disadvantages at all :) Commented Mar 21, 2018 at 14:50
  • no intellisense - it's not necessary in this case. I write name of field once, when I fill it. no compile-time checking of fields - what sense to checking field names for json? Commented Mar 21, 2018 at 15:26
  • 1
    Well what do you mean by 'easy'? 'Easy' is subjective. To me, at least, a modification I can do with confidence (because it's typed) is 'easier'. What about consumers of your web service - could it be that you accidentally rename a property? A dynamic would cope with this with no problem at all - but the consumer might blow up. That's not easy. It's easier to do what you're saying in the here and now, of course, but a lot of 'sound' programming principles occasionally cost a little bit more time. It's time well spent. EDIT: Not to say there's no place for the use of dynamic, there is. Commented Mar 21, 2018 at 15:34
  • 1
    @user285336: why not easy to modify? Maybe easy to modify, but hard to maintain. Developers mainly measure code complexity by the difficulty of figuring out what to change, as opposed to the actions needed to make a change in something you already understand. Your dynamic approach makes it very hard to figure out what the names of the properties should be. Comparatively, if these property names are available via Intellisense, a developer doesn't need to worry if he made a typo or not, because the compiler will tell him automatically if he used a non-existing property name. Commented Mar 26, 2018 at 15:09
  • 1
    @JᴀʏMᴇᴇ: To extend your point, think of a dynamic which uses the Color property. Now hire a British developer who instinctively uses Colour (UK spelling). The compiler does not tell him he's wrong, since the compiler doesn't bother to factcheck dynamics. If the British developer had had Intellisense, he would've immediately seen the issue. Without Intellisense, and with a completed build, the developer is now forced to go on a bug hunt because something broke and he doesn't know what. The time cost between the two is immense, and this happens for every typo any developer can make. Commented Mar 26, 2018 at 15:14

2 Answers 2

4

The advantage of having a strongly-typed return value is that you can have a descriptive document (for example swagger using Swashbuckle) that allows people to auto-generate a client for your API.

If you just return JSON data that is not documented what it looks like, not only do you have to build it dynamically without much error checking on your part, the client will have no way to know how it looks like. So that's trial and error on both sides.

7
  • 1
    I don't buy this. It's easy enough to look at the JSON data and construct a DTO for it (or even use it as-is in Javascript, which already deals with it dynamically), assuming that the JSON is consistent. Commented Mar 21, 2018 at 16:38
  • @RobertHarvey Swagger (or similar things like WSDL for SOAP) are a way to make sure the JSON is consistent. How else would you know? Trial and error? Commented Mar 21, 2018 at 16:46
  • I'm familiar with WSDL. But that just begs the question: if you're using dynamic binding, you shouldn't require any of those things. Granted, it's a different world, with a different sweet spot. Commented Mar 21, 2018 at 16:59
  • It's not required per se, but I would consider anyone super-unprofessional that says "oh, just call it a few times, you will see what you get". If you have an API endpoint for users, how will you know that a user object can have a car object and a car object can have a color property? You need documentation, everything else is guessing. Commented Mar 21, 2018 at 17:09
  • Documentation, yes. But my real-world experience with API's like Twitter and Facebook is that the kind of world you're describing (where everything is standards-based and just works via templates) is pretty rare. Naturally, one should always strive for the ideal, but I wonder how practical that is, given that few seem to achieve it. Professional is as professional does. Commented Mar 21, 2018 at 17:23
1

You are right in that there is little advantage to the Strongly typed POCO object in the hosting layer.

In fact, even though I am a proponent of using strong typing, I would be happy to use dynamic over creating new Request/Response type objects which mearly wrap some parameters for the purpose of serialisation.

However! The strong types do serve a purpose in your service layer. ie compile time error checking etc, which is where you construct them.

Additionally, I would expect you to provide a client library to your api, where again, using the same strong types and interface as your service layer has many benefits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.