# Introduction

Conditional logic is inevitable when it comes to building applications for business. While it is easy to wrap certain parts of the implementation in conditional IF-ELSE constructs eventually you discover a few unpleasant facts:

  • As the codebase evolves, it starts to look more like a spaghetti
  • Lost domain knowledge, as you can't recall or figure out why a specific condition exists
  • The unit testing becomes a nightmare especially when you rewrite it every time conditions change by the business
  • Number of production bugs grows as more conditions are introduced into the codebase

I've been professionally occupied in the tech industry since 2003 and personally experienced many times when business conditions changed a few times before even the first official alpha release to production. Every time it was forcing my team to either do substantial code refactoring to avoid many nested IF-ELSE statements or, due to limited time constraints, bite my lips and "cook some spaghetti" code.

Partially out of frustration and mostly because of a strong desire for development excellence, I've designed the new domain-specific language to decouple conditional logic from the application. This way, you can focus on implementing clean, maintainable, and reusable code, while defining conditional logic as a separate artifact in form of JSON policies.

If any business-related conditions change, you no longer need to modify the code. Simply adjust respective policies, and you good to go.

# Core Concept

A typical application works with at least one resource. It can be anything - user record, todo task, article, physical file, etc.

A typical application also is invoked by somebody or something. It can a real human selecting a button on a website page, a scheduled cronjob triggered by an operating system or a programmatic RESTful API request. So the application executes when some authenticated or unauthenticated identity invokes it.

Finally, last but not least, a typical application may perform one or a few (A) actions upon any given (R) resource based on (I) identity's request.

JSON Policy Relationships

Now, when the identity invokes an application, it typically wants the application to work with some resources to fulfill the request. It is the time when things get (C) conditional.

It can be as simple as an anonymous user requests to update an existing user record or view premium content that is available only for paid members. It can be a very complex business condition as screening a specific category of articles until the end of a year for members under the age of 21 that live in New Jersey state.

Disregarding how simple or complex the requirements are, it is apparent that each condition branches your codebase. The side effect of this is less maintainable application and way more unit testing.

The core idea behind JSON policy is to define the collection of resources and parameters and under which circumstances they can be invoked.

{
    "Statement": {
        "Effect": "deny",
        "Resource": "Car",
        "Action": [
            "view",
            "purchase"
        ]
    }
}
((car) => {
    const manager = new JsonPolicyManager({...});

    if (manager.isAllowedTo(car, 'purchase', false)) {
        console.log(`Sorry, you are not allowed to purchase ${car.model}`);
    }
})(new Car({
    model: "BMW 428i"
}));

Any statement or param can be conditional. It is where the true power of policies come into play.

{
    "Statement": {
        "Effect": "restrict",
        "Resource": "Category:science:articles",
        "Action": "read",
        "Condition": {
            "NotEquals": {
                "${USER.location.city}": "San Francisco"
            }
        }
    },
    "Param": [
        {
            "Key": "api:endpoint",
            "Value": "https://my-app-api.com",
            "Condition": {
                "Equals": {
                    "${ENV.environment}": "production"
                }
            }
        },
        {
            "Key": "api:endpoint",
            "Value": "https://staging.my-app-api.com",
            "Condition": {
                "Equals": {
                    "${ENV.environment}": "staging"
                }
            }
        }
    ]
}

# Real-Life Use Case

The first and so far the only known application that uses the JSON policy framework is the top 1% of the most popular WordPress plugins Advanced Access Manager(opens new window) . It is installed and actively used on over 100,000 websites around the world.

Advanced Access Manager

Many WordPress developers that I've personally worked with, find JSON policies very useful and fascinating. This is what inspired me to offer the JSON policy framework as a stand-alone library.

# How to Start

The JSON policy framework currently is available for a limited number of languages. More supported languages will be added soon and depend on the popularity of this project. So, if you find this project interesting or useful, please don't be shy to share it with your audience and give a star on the Github repo(opens new window) .

You can find detailed installation instructions for each supported language on its respective reference page. Just follow one of the following available links: