What is Granitic?
Granitic is a combined framework and platform for building and running web services in Go. It focuses on minimising the amount of boilerplate code required to peform the most fundamental operations present in the majority of web services, namely:
- Defining HTTP endpoints for services
- Extracting data from HTTP requests and binding that data to application data structures
- Validating inbound data
- Storing data in and retrieving data from an RDBMS
How can it be a framework and a platform?
As Go includes an integrated HTTP server, your Granitic application will be a single self contained executable - it doesn't need to be deployed to an application server.
Why was it created?
Granitic is the result of a frustrating period in 2014 trying to debug memory allocation on an AWS/JVM/Jetty/Spring stack. A discrepancy between how the OS was allocating memory and the actual memory needs of a Spring based web service was resulting in web services with very large memory footprints.
This led to research into non-JVM languages that would allow fully featured micro-services to be deployed onto 'free-tier' cloud servers. Go was a strong contender, but the migration path away from JVM languages and Spring was not clear. Granitic is an attempt to make that migration path easier.
Who is it for?
Grantic is for anyone who wants to write web or micro services, but it will be of particular interest to:
- People looking to migrate legacy JVM/CLR web services onto a more memory efficient platform
- Dev Ops practitioners who need to run large numbers of instances of services and require completely externalised configuration.
A Granitic application will be distributed as an executable and one or more configuration files. These configuration files can be defined as a file resource or as an HTTP URL.
At runtime, these files are merged together to provide a single view of configuration. This allows the behaviour of the application to be changed at runtime according to environment without having to re-build or re-package code.
For example, an application might be started with three config files:
- A 'core' file containing configuration that is common to all instances of the application
- An 'environment' file containing configuration that changes between environments (dev, test, production etc)
- An 'instance' file that contains config specific to an individual instance (HTTP port, name etc)
As these files can be served over HTTP it becomes possible to centralis all configuration and only have executables deployed to servers/containers.
Component oriented design
Granitic includes a fully featured Inversion of Control (IoC) component container. It encourages applications to be thought of as a series of components managed by the IoC container. Granitic provides a number of features to work around the limitations of Go's statically-linked nature (specifically the lack of runtime instantiation of named types and annotations) that would otherwise hamper the use of an IoC container in Go.
Go packages the features it provides to applications into suites of functionality know as facilities. Your application can, through configuration, only enable the facilities it requires. Examples of facilities in Granitic include:
- HTTP Server
- JSON web services
- XML web services
- RDBMS management and access
- Database query templating
- Error message templating
- Runtime control
No external dependencies
Granitic has no external dependencies - even unit testing frameworks. This is based on the principle that application developers should be in complete control of the dependencies of their application.
Why doesn't Granitic just re-use framework X?
Granitic does not claim that any of its facilities are best-in-breed. There are undoubtedly better individual request binding/validation/query-templating etc solutions available.
The point of Granitic is that it provides enough functionality to support the most common use-cases for web services. It has deliberately been designed so that that if you'd prefer to include, say, a third-party ORM library, you are completely free to do so
What's with the binding step
In addition to building your application with
go build you will need to perform a pre-processing step using a tool supplied with Granitic called
grnc-bind. This is effectively a
code generation step that converts the JSON definitions for your IoC components into Go code. This is very easily macroed. For more information on this process, read the documentation for grnc-bind