Code Consistency With Examples & Services Framework
Credit: www.flaticon.com

Code Consistency With Examples & Services Framework

Maintaining consistent coding guidelines across medium to large organisation is always a very challenging task and making sure that those are followed properly is an another ball game. Although for small startups with team less than ~15, this information can reside in one person's mind (Founder/CTO) :).

So, how can we make sure that consistent set of coding principles are followed? In my opinion, the solution lies in making it easier for the developers to follow those guidelines. The next obvious question is that how can we do that??

We will talk about code examples and service templates/chassis and how these two approaches can help us achieve our goal!

Code Examples

We should have specific code examples in the guidelines rather than generic coding principles and philosophy.

Let's see below a sample coding guidelines of a hypothetical organisation

1. Be explicit rather than implicit: 

Being explicit means being concrete and specific instead of 
abstract and general.

It also means not to hide the behaviour of a function.

2. Consistent logging structure:

	- Make sure to use only allowed fields as part of any log 
      statement

	- Do not create custom logger objects

.
. <More guidelines>
.        

As you can see from the above example, the author of the above guidelines has left many things to the reader's interpretation. The guidelines were shared but they were not made specific with good and bad examples.

Let's see an improved version (examples credit ) of the above mentioned guidelines

1. Be explicit rather than implicit (https://miguelgfierro.com/blog/2018/python-pro-tips-understanding-explicit-is-better-than-implicit/):?
	- Being explicit means being concrete and specific instead of 
      abstract and general.
	- It also means not to hide the behavior of a function.


	<Bad Example>
		def read(filename):
		? ? # code for reading a csv or json
		? ? # depending on the file extension


	<Good Example>
		def read_csv(filename):
		? ? # code for reading a csv


		def read_json(filename):
		? ? # code for reading a json

2. Consistent logging structure
	- Make sure to use only allowed fields as part of any 
      log statement.

	<Bad Example>
		import custom_log from custom_created_log_module

		def read_csv(filename):
			custom_log(custom_message_field=f'Reading CSV from file {filename}')

	<Good Example>

		import log from org_wide_common_log_module

		def read_csv(filename):
			# Here, 'message' is an allowed field to be used in logging
			log.debug(message=f'Reading CSV from file {filename}')
			# perform operation on file

.
. <More guidelines>
.        

As we can see from the above guidelines, it becomes simpler for the developers to follow it as there are concrete examples and it leaves no room for interpretation.

Is coding guidelines sufficient or can we do better?

Coding guidelines go a long way to write consistent code but in the end they are just guidelines! No matter how much well they are written, you would still need to invest considerable time in enforcing those guidelines on a consistent basis during code review process and by using static code checkers like Sonar .

Q. What if we can reduce the amount of code written and at the same standardised common use-cases?

Whenever you create a new micro service, there is always an additional burden of writing the plumbing code i.e infrastructure connectivity, service discovery for a downstream service, logging, observability etc. (I have copied the meaning of "plumbing" from Pete Hodgson's excellent blog on Service Templates and Service Chassis). These necessary logics are needed to make sure that the service works smoothly in a micro service environment.?

No alt text provided for this image
Multiple Services With Same Functionality

But does every team need to write the same piece of logic again and again? As you have guessed it, there is no need for every team to write the same piece of logic again. So the solution is to create and use a common runtime framework which provides all these necessary non-business (plumbing code) centric functionality so that the business related micro services can focus entirely on the business logic!

In the next section, we will talk about service template and service chassis and how it can help ease the life of developers?

What is a service template?

Service template is a ready to use "Hello World" micro service which any team can use?to create a new micro service. On other words, it can be a sample git repo which anyone can clone to create their new service. This repo can have the necessary docker files, folder structure, rest clients etc. Simple enough!

No alt text provided for this image
Service Template

The limitation with this approach is that it becomes increasingly difficult to keep the clone services up to date with the changes in the original sample repo and very quickly, teams will start drifting away from the original cloned version and would start creating their own optimisation.?

What next? We can overcome this limitation of drifting way by creating a common framework and a set of smaller libraries. These libraries can be injected into any service at the time of creation and can be updated with simple version upgrade.

In the below example, we have created a common framework having all the basic functionalities like logging, service discovery, health check and metric etc. Other optional libraries like caching and queue handler can be exposed separately since every service might not need them.

No alt text provided for this image
Service Chassis

This method of creating a broad set of independent functionalities into framework and libraries is called Service Chassis or Service Framework.

Does this approach has any limitations?

  1. Code Governance: Since with this approach, we are enforcing teams to use a particular framework, it becomes essential that the underlying framework is kept up to date and bug free.?IMO, the responsibility of maintenance for the framework should be kept with the platform team but it should be made sure that any developer in the org can raise pull request to fix the bugs and suggest optimisation.
  2. Single Programming Language: This approach would enforce all the micro services to be written in a single programming language. In most of the companies, this should not cause any issues.

Now comes another big question, does it makes sense for your org. to invest engineering bandwidth into this??

If you are a startup and you have not yet achieved product market fit or you have achieved market fit but still have not decided to split your monolith then it doesn't make sense to create a service template and/or service chassis. Having a common service template would only help when you are planning to move towards micro services else it would be an additional overhead.?

On the other hand, if your startup has necessary bank balance for the next couple of years and has achieved product market fit and is planning towards breaking the monolith then it is the best time to invest bandwidth in such a framework.

What if your company is already huge and has micro service architecture but has not yet created services framework?

In this scenario, it becomes tricky. The best way here would be to start small and make sure new services are built using this new services framework. The goal here would be to bring in adoption and that can only come if we can make the transition smoother and writing code 10x simpler for the developer. For the rest of the services, start by targeting less critical services and slowly moving towards critical services. We should not target for creating a full blown framework in the beginning. Adoption is the key and keep iterating based on the feedback.

Hope this blog would have given you useful insight on code governance, coding guidelines and services chassis/templates.

For further reading, you can refer below resources.

  1. Building micro services book by Sam Newman - Chapter 2
  2. Pete Hodgson blog
  3. Service Template
  4. Service Chassis
  5. Zen Python

要查看或添加评论,请登录

社区洞察

其他会员也浏览了