Design Docs
I love writing design docs! At Beanworks, we have a habit of writing design docs whenever
- there is a significant change to the code/architecture
- it is start of the project and there are multiple, possible implementation choices
- there are code style changes/suggestions
Design Doc Format
There is a general format that we follow when we are writing a design doc:
Problem Statement
This is the problem that I'm trying to solve. This can be the feature work (ie. Implementing Tax Interface), tech debt (ie. decoupling over-used inheritance) or even code style changes (ie. JS linting rules)!
Existing Solution
This is the existing solution in the current codebase. It usually involves summary and code snippets.
Existing Solution - Problem Analysis
This is the problem with the existing solution.
Proposed Solution(s)
These are the possible solutions. These solutions should ideally be solving the problem from the existing solutions. Each solution should list pros and cons and possible dev effort.
Example of Design Docs I've Written
I'm including one simplified example of design docs that I've written for references.
Organizing GraphQL Mutations
Problem Statement
We are at the crossroads of deciding an approach for organizing GraphQL mutations: single level vs nested structure. As we have more clients relying on our GraphQL API, we need the consistency.
Existing Solution
We have a mix of single level and nested (namespaced) endpoints.
Context & Resources
There is no concept of "namespace" in GraphQL.
All types within a GraphQL schema must have unique names. No two provided types may have the same name. No provided type may have a name which conflicts with any built in types (including Scalar and Introspection types).
All directives within a GraphQL schema must have unique names.
One of the popular workaround is grouping a set of operations under an intermediate node such as this.
Existing Solution - Problem Analysis
There are known issues around race condition and inconsistency known as non-root-mutation order indeterminism1 2
Other issues are inconsistency with other endpoints, redundancy with namespaced endpoints (when accessing data from client side) and discoverability (single Mutation
file containing all endpoints).
Proposed Solution(s)
I propose that we use single level endpoints. There are only 2 intermediate nodes in production used by 1 client that can easily be refactored to single level.
I also propose that as we are going with single level approach, we keep the endpoints alphabetical order grouped by entity.
# Invoice
createInvoice
updateInvoice
# User
createUser
deleteUser
Benefits of Design Doc
- You have a history of discussion and research done for specific design decisions.
- It's a great way to get an asynchronous feedback from everyone - even the introverted who might have trouble speaking up during meetings or junior developers who need more time to digest the content
- It helps me to understand and articulate the problem better and compare the proposed solutions to existing implementation to make sure it's addressing the correct problem.