Jim Carnicelli - Full-stack developer

- 608-332-4932 - JimCarnicelli.com

What does that mean?

For starters, the "stack" here is essentially all the technologies required to deliver a complete application. For a basic web app that couple mean HTML, CSS, and JavaScript on the client side. And then ASP.NET and JSON-faced web services written in C# on the back end for feeding the client. And then T-SQL stored procedures (SPs) in a Sql Server database. And that's before we start talking about client-side JS and CSS libraries, .NET components, and other add-ons. Let alone all the satelite services and integration points to round out a larger enterprise system. And then there's the operating system and platform components undergirding the app. It's handy to think of this all as being like a stack of pancakes. Each typically communicates with pancakes above and below it. And the user communicates with the delicious pancake on top of it all.

Many business apps — especially at the enterprise level — are created by people with a variety of skill sets. You may have whole teams of specialists doing database design, middle tier construction, user experience (UX) design, JavaScript programmers and so forth on the pure engineering side.

A full-stack developer has the skills necessary to do all these development tasks.

A broader interpretation of "full-stack developer" could be synonymous with "software engineer" and imply that such a person can design, implement, and maintain entire projects. These people will be comfortable with roles of project manager, business analyst, technical designer, coder, tester, documenter, maintainer, database designer, database administrator, and so on.

That's me

I've served every basic role in the software development life-cycle. I describe myself as a software engineer, but also as a full-stack developer. I can take on all the essential roles and design and implement all the layers of a typical business application. I have worked on teams of all sizes for companies of all sizes. I have done entire enterprise systems by myself and with small teams assisting me. I have been project manager and chief architect for larger teams repeatedly.

I'm flexible. I like having control over how a project is engineered. I work well as a sole creator, as a team leader, or as a colleague in a larger team.

Some opinions about web apps

When looking for a job I naturally have to be prepared to adopt whatever technologies and standards my employer or client has set. But like any good engineer I have opinions about how to best approach architecting a software solution. Consider the following thoughts to be preferences and not hard rules for my work.

Most of my work over the past few decades has boiled down to creating web applications. There's usually a very complex suite of internal features for employees and sometimes external business partners. And there's a simpler, prettier set of features and more static content aimed at Joe Public. After so many iterations of this I have developed a pattern I favor. They are primarily aimed at making it fast and easy to create and change user features for larger scale enterprise apps with lots of operational data. Let me summarize some aspects of this pattern and explain why I favor them.

The most critical principle of the pattern is keeping the platform simple. That means minimizing dependencies and using as few programming languages as possible to deliver a solution. On the client side that means only using pure JavaScript, HTML, and CSS. The latest generations of these technologies provide amazing capabilities that I believe are not meaningfully improved upon by application frameworks like React.js and Angular.

To keep large systems manageable I favor implementing functional units like customer search and order entry as though they were single-page applications (SPAs). Visiting a page like, say, a product detail means downloading a small bit of server-generated HTML that mostly just points the browser to the static CSS and JavaScript files to download for the page. But it also contains initial data structured as a JavaScript object literal. Interacting with the page will often require Ajax/JSON requests back to the server to fetch more data. This arrangement tames even the most complex features. It also allows users to open as many browsers or tabs as they need to deal flexibly with their workflows.

In keeping with that theme, the server side is ideally very flat. Page requests and JSON remote procedure calls (RPCs) get treated almost exactly the same as far as the coder is concerned. This greatly aids in testability and debugging. The most important key here is that the "middle tier" is nearly empty. This could be implemented in ASP.NET but just as easily some other server-side web platform. The middle tier is really just a glue layer. It shouldn't contain what you'd generally consider business logic. So where is it then?

Somewhere along they way I did a 180° on stored procedures. I went from putting all business logic in a middle tier that could sit on top of any database to putting all the business logic in the database itself. Why? Business logic comes in three flavors. First one is trivial reads and writes. What's the point of creating a bit of, say, C# code whose only purpose is to fetch a few records and package them up to ship to the client-side code? Why not just put that trivial logic in a simple SP? One that is super easy to create and unit test? The second flavor is painfully complicated queries. This is the handful of expensive searches you have. Or the monthly aggregate reports. This stuff is almost always nothing but complex queries that are best executed directly in the database. The third flavor is expensive batch processing. This is the scheduler algorithm that decides which customers need to receive which marketing emails when. Or the OLAP data feed that runs every night to power your data cubes. In any case nearly 100% of this is best kept in the database.

And let's not pretend we're going to run this against a bunch of different database back-ends. That rarely happens. And when it does you still end up having to write custom SQL for each of them.

The main reason the middle tier is nearly empty is that the database and the client-side JavaScript exchange information as named values and named row-sets. To JavaScript these are expressed simply as objects with named arrays of other objects. Almost every business case is covered very well by this. And the middle tier can just pass these along. Yes, of course there is very tight security. Every page and RPC handler has a unique stored procedure. They are all named carefully so no hacker can call SPs not designed for front-end access. And every one of these SPs indicates which user roles have access to execute them and constrains which data the current user can see.

To someone used to one of the many popular app development patterns this may sound complicated at first. But it's actually incredibly simple. Some simple pages end up being implemented using nothing more than short stored procedures because they can rely on reusable page templates. Most pages will include at least one page-specific JavaScript file that describes the layout in terms of a handful of standard controls such as text boxes and data grids. Those controles manage data binding to the data that comes straight out of the stored procedures that feed the page. And that JS code responds to users clicking buttons entering text, and other events. Sometimes that means making straightforward RPCs and pushing data to some SPs that send whatever data is needed back. Only rarely will a page require a custom CSS file or some other extra resource.

And only extremely rarely will the middle tier need to get involved. It may be to generate an image file from data coming from a stored procedure, for example. Or to store some uploaded file somewhere. In almost all cases the SP gets executed first and sends special output data that instructs the middle tier in how to proceed.

One quitessential example of this was a complete enterprise management system I created for a client. I was able to hire and quickly train a few coders to work on it because nearly 100% of their work was in writing JavaScript and T-SQL stored procedures. Here's a quick-n-dirty video I produced as a progress report to the management team along the way:

The key to making this super easy for application development — and hiring programmers to do some of it — using this pattern is creating a custom framework for each big project. The framework ends up doing most of the heavy lifting. It gives your pages a consistent look and feel. It makes page layout a largely descriptive process. It powers all those app SPs on the back end. It takes some work to get it all ready. But it's so worthwhile. And improvements to the framework get inherited by all app pages.

I've tried N-Tier. I've tried MVC. I've tried code generators. I've tried an awful lot of the patterns in use in most mid to large companies. Most of them create enormous busy work for programmers. And they can be next to impossible to follow. In short they are expensive to employ in the short and long term.

And most of the third party UI frameworks disappear within a few years. It's one of the most important reasons to avoid them. Use the baseline platform and create your own minimal, application-specific framework.

One of the greatest benefits of the approach I've described is that it encourages the programmer to engage in nearly pure procedural programming. Every stored procedure that serves up a page or some data for one is a singular procedure. It gets all its state from browser inputs or from database tables. It does one well-defined thing like save a customer record. It returns one chunk of well-structured data. And it usually runs for under a second. Once you are familiar with the pattern it becomes easy to read and even alter the code. Funny enough the same goes for the page JavaScript code. There's one routine for layout, which is another linear procedure. And there are single functions laid out for any event handlers that are nontrivial. And as a result it is relatively easy to understand how any page works.

One of the other benefits of this design pattern is that these apps almost always run very fast. Despite having rich UIs and being quick to assemble, the lightweight frameworks add almost no overhead and massively shrink the code you need to write for each page. And they let you focus on optimizing performance by adding indexes or trying out different designs with stakeholders to find a good balance.

I don't mean to suggest that the above works perfectly for every application. It really does cater well to larger enterprise apps, whether for internal use or facing the public. I'll also say that each time I implement a system like this I experiment with the exact frameworks looking for opportunities to improve on the previous app I made using this pattern. And sometimes the frameworks get trimmed down because a given app has more modest needs.