Grandpa: Nothing gave Buttercup as much pleasure as ordering Westley around.
Buttercup: Farm boy, polish my horse’s saddle. I want to see my face shining in it by morning.
Westley: As you wish.
Grandpa: “As you wish” was all he ever said to her.
Buttercup: Farm boy, fill these with water – please.
Westley: As you wish.
-The Princess Bride
Here to serve.
That sounds fantastic when somebody says that to me. It’s a bit harder for me to say that even though I know full well that when I serve others I usually benefit greatly if not more than the one I’m serving. My focus is not about you or me but about software. Software that can be a service to others.
Wow, really!? …and that’s just scratching the surface. This is not a new idea by any means. There seems to be an ebb and flow to centralizing and decentralizing the elements that make up a given application. What I have found is that in and of themselves they are neither right nor wrong. They are what they are. It’s for a given context that a level of appropriateness comes to play. Hardware capabilities, intranet and internet speeds and accessibility, user expectations and usage patterns. These all start telling a story and create a setting in which to place an application.
Distributed applications are cheered and jeered at the same time. Sometimes by the same people. They represent an incarnation of DRY (Don’t Repeat Yourself). As such they can be awesome. “You need widgets? Call the Widget Service!” The ease in which you can get data and functionality can be very impressive. Pulling an application into a hundred remote calls can also be something else. Slow.
If you have a single application it may not make sense to go the SOA route. You can still design and build this way to think separate but deploy combined smartly making everything a local call without the over head of serialization. This pattern really works best to serve multiple applications that have shared needs or need shared data.
If the functionality is not intended to be shared with multiple applications do not make it a service. Don’t pull in consultants and fire up a major ESB project with crazy orchestration to negotiate and transform data between disparate systems when there’s only one consumer. We’ll talk more about application design another time. Right now I’m focused on services.
What is a service?
To me it’s just an application. Instead of the consumer being a user it is another application. It’s also data with behavior. Hey… that sounds like encapsulation from the OOD school. Go figure. It is. At it’s core SOA is a very Object Oriented approach to designing an application. This is why you can design this way regardless if you’re deploying as a separate service or as an integrated business unit within your application. You should be thinking this way already. We’re just gonna pull part of the application out so others can call it without:
1. Copy and pasting the original code (bad coding practice fraught with maintenance issues)
2. Making a static reference to your application (inappropriate coupling)
This service should offer value. It should be strongly cohesive and fully encapsulated. The service should only do what it is named to do. A ‘beach finding’ service should not know anything about gas stations. It knows beaches. You should not have any beach logic in your application, it’s in the beach service. If you want to know where it is ask the service. If you want to know how popular it is ask the service. If you want to know how to get there… ask the mapping service, the beach service doesn’t understand directions.
I like to think of services as Legos. Very simple to use and combine. By connecting a few together I have a working application. That’s when the magic happens. The real benefit is that the service is independent of your application and has it’s own delivery and maintenance schedule. If it’s tested and solid that part of your app is already done. Don’t do it again. It’s free for everybody after the first consumer. When your library is big enough you can build a robust new application quickly and primary focus on the business needs at hand. That’s adding value!
From a deployment standpoint I like my service layer to be out of the DMZ and locked up tighter. It’s an extension of your data and is equally sensitive. Lock it up and protect it as best you can. Sure this is a hardware issue but at some point we’re going to actually deploy something on a real box and it’ll be subject to real users in the real world. I recommend doing a security audit periodically so you know where you stand.
If you’ve followed our RESTful talks you should already be thinking of making RESTful services. Keeping them stateless will allow you to load balance and scale this tier as needed with minimal effort. Be careful as you may be stateless but if you’re caching data (yeah, yet another topic to dig into) make sure you’re either caching that externally or have a way to synchronize.
I’d be remiss not to state that your RESTful service should probably return plain text JSON constructs. They’re so easy to use these days. Most languages have utilities available to generate and consume JSON so you don’t even have to sweat this one. So you’re service can now be consumed by anyone, anywhere, and… wait. No, I don’t really like that all that much. I’m going to go back to locking up my service tier. If I really want this exposed externally I recommend creating a gateway application to handle those chores. Keep your tiers intact, and in ship shape. You’ll do just fine.
“I am Juan Sánchez Villalobos Ramírez, Chief metallurgist to King Charles V of Spain. And I’m at your service.”
*ASP is an acronym that meant “Application Service Provider” before “Active Server Pages” from Microsoft came along.