Fluent Interface API Design

I’m working at a new client and have written a few services to support a DotNetNuke CMS install, as well as a few modules.  To support the modules I’ve written one or two of my services using a Fluent Interface API.  This was fun and exciting, but some APIs didn’t make sense to be used fluently, or it complicated things more than I would have liked.

As a developer I think it is important to write the API so that it is usable and easy for a junior to understand.  Fluent is one way to do it, but it isn’t necessarily the only or best way!

Some places where I found Fluent difficult to use was if I needed to provide two parameters to an underlying service.  For instance its not uncommon in DotNetNuke to have to provide a User ID and a Module ID to one method call.  A Fluent Interface might say DoSomething.ForUser(userId).WithModule(moduleId), but that means storing the userId.  And to prevent the user from doing DoSomething.WithModule(moduleId).ForUser(userId) you would have to do some tricks with interfaces, and that is just not fun or easy for another developer to understand or use!

Sometimes it makes more sense to DoSomething.ApplyToSomthing(moduleId, userId) – it just does.

Of course, there are always tricks like Func<T> out there that we can use.  Because Func<T> is a .NET Framework feature I would expect another developer to understand how to use it, maybe not a raw cadet just out of school, but the documentation is there on MSDN for us to learn from.  Still I would probably have to define a class and use a lamda expression to use the method.  Lambdas are awesome for condensing code into readable chunks, but DoSomething.Using(p => { p.ModuleId = moduleId, p.UserId }) feels unwieldy to me. It makes a lot more sense in FluentNHibernate than it does in a small API or wrapper because you’re creating configurations and large sets.

So I’m going to be careful with my API designs and continue to make them usable.  After all, the best developer is one who’s code is readable and usable when its done.  And the best code does what it is supposed to but is maintainable by a noob.

Leave a Reply

Your email address will not be published. Required fields are marked *