webwire-example-postboard

module
v0.0.0-...-9ca37e5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2018 License: MIT

README

Postboard - the real-time example application

MIT Licence Go Report Card

This example demonstrates a full-blown single-instance real-time API server written in Go and powered by the WebWire websocket library.

It includes the following features:

  • A modular API-server architecture
  • Optional TLS encryption
  • Automated testing
  • Metrics (real-time statistics)
  • Logging (configurable)
  • Request-Reply
  • Server-side signals & subscriptions
  • Authentication & Sessions
  • Authorization & Permissions
  • Password hashing
  • Graceful shutdown
  • Custom HTTP handlers alongside webwire
  • dep for dependency management

API Server Architecture

The API server's architecture is based on a 3-stage request processing pipeline where the last 2 pipeline segments implement an abstract interface.

API server request processing pipeline stages

An incoming request is received by the network layer (implemented by webwire-go) where it's decoded, unmarshalled, associated with a client session and finally passed over to the stage 2 resolver interface. The resolver implementation validates the passed parameters and authorizes the request by checking the provided session's permissions. If the request passes the validation and authorization procedure the resolver resolves it into one or more engine calls through the stage 3 engine interface.

The resolver can be made responsible for optimizing engine calls (to reduce database load for example) by using the batching, caching and deduplication techniques, so that instead of directly performing an engine call to retrieve the data of an entity to fulfill a request for example the resolver could use a loader module and buffer multiple requests of the same type while simultaneously deduplicating similar requests to eventually perform a batched engine call when either the loader's buffer limit is exceeded or the loader's interval tick is reached.

Finally the engine calls are executed by the memeng in-memory engine implementation, which takes care of atomically mutating and/or reading the data from it's in-memory store. It is to be noted that engine calls are considered atomic and are thus performed in an all-or-nothing fashion while transactions spanning over multiple engine calls are not possible.

The goal of this architecture is to abstract away the actual implementation of the individual system modules isolating responsibilities improving both security and maintainability of the system. The engine can, for example, be re-implemented using either a different store backed by a DBMS, noSQL database, filesystem etc. or even remote microservices. Theoretically multiple implementations of the engine can co-exist, an in-memory engine could, for example, be used to quickly mockup a prototype and develop API tests before an actual, more complex, persistent database-based engine is implemented.

Scalability

While this particular example demonstrates a single-instance service only, it is possible to make it horizontally scalable using both the clustering and microservice techniques.

Clustering

To improve performance and fault-tolerance this API service can be replicated onto multiple machines, which will require a new module for the communication between the individual cluster nodes. This module would be responsible for:

  • synchronizing the nodes,
  • broadcasting (and receiving) events for the individual nodes to be able to notify their connected clients,
  • and invalidating local caches if necessary.
Microservices

This architectural approach allows to ease the process of turning an initially monolithic API service into a microservice-based distributed system by gradually reimplementing the engine to offload certain functionalities and datasets to individual microservices by redirecting the data mutation and retrieval logic onto it.

Eventually the API service will turn into a Microservice API Gateway which is then only responsible for validating, authorizing and routing requests, as well as acting as a bridge for signals notifying connected clients about server-side events. The implementation of the logic behind the engine calls in this case is offloaded to the individual remote microservices.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL