Skip to content

Instantly share code, notes, and snippets.

@ThatJoeMoore
Last active January 31, 2019 20:57
Show Gist options
  • Save ThatJoeMoore/e65eba99103643e4c22e4476cef8870e to your computer and use it in GitHub Desktop.
Save ThatJoeMoore/e65eba99103643e4c22e4476cef8870e to your computer and use it in GitHub Desktop.
BYU Claims API Draft

Proposal

This is a draft proposal for BYU API 'Claims'. This document is non-normative until approved and documented by whoever it is that approves and documents this kind of thing. Feedback is welcome and encouraged.

Things that need to be addressed or refined ("Yaks to shave") are denoted by a yak-like emoji: ๐Ÿƒ. The use of Yaks is blatantly stolen from inspired by SvelteJS.

Overview

Resource-based APIs, such as the University API, work well for fetching data. However, we often need to ask yes/no questions about a resource, such as "Is this person a full-time student" or "Does this person's Cougar Cash account have enough money to cover a transaction at a given location?". These questions require a great deal of domain knowledge to answer. While our consumers could answer these questions themselves using data from our resource-based APIs, this is less than ideal. It requires consumers to replicate these business rules, which makes it hard to change them and tightly couples consumers to our APIs. We would like to have a simple, standard way to ask these questions and abstract this logic away. The proposed solution to this problem has been named 'Claims'.

Claims offer a way for an API to offer a list of questions that consumers can ask. Each claim may require the consumer to send some data, and it response with a true/false answer. The request and response formats are standardized across APIs.

URI Structure

APIs which support claims should offer an endpoint called 'claims', like http://example.com/my-api/v1/claims.

An API may support one or more claim types. Consumers may evaluate a claim individually, or may request that multiple claims be evaluated together.

Claims may be addressed individually using a URL pattern like claims/{claim_type}.

Claim Evaluation

Claims are evaluated by sending a GET request to the appropriate endpoint.

Evaluating Single Claims

A single claim may be evaluated by sending a GET request to the corresponding endpoint.

If an API offers a claim called "full_time_student", the request could be evaluated with this request:

GET /claims/full_time_student

Almost all claims will need some sort of information in order to be processed. This information is called the "Claim Context." For example, the full_time_student claim needs an identifier of a potential student, which at BYU is called a "BYU ID."

Claim context values are specified using query parameters on the claim request. To specify a byu_id context value for full_time_student, the relative URL would look like /claims/full_time_student?byu_id=123456789.

Claims may allow multiple values to be specified for a claim. These should be specified in a comma-separated list.

Claims may require one or more context values to be specified. They may also define optional context values, which may have defaults. For example, the full_time_student claim could have an optional as_of_date, which would check if a person was or will be a full time student as of a specified date. This would default to the current date. Example URL: /claims/full_time_student?byu_id=123456789&as_of_date=2019-01-02.

Evaluating Multiple Claims

Multiple claims are evaluated by sending a GET request to the root /claims endpoint. There is a mandatory parameter, 'claims', which is a comma-separated list of the claims to evaluate. Claim context values can be passed two ways:

  • For a context value that has the same name and value across multiple claims, just use the name (byu_id=123456789).
  • For a context value that is specific to a claim, or that has different values for different claims, use Object Notation: full_time_student[byu_id]=123456789

Evaluation Results

Claim endpoints respond with a simple true/false answer, plus metadata about the claim.

Successful Response

If the claim is evaluated successfully, the response will look like this:

{
  "result": true, # or false
  "metadata": {
    "valid_until": "2099-01-01T01:01:01.111Z",
    "๐Ÿƒ": "Metadata format needs to be defined"
  }
}

Error Response

If the claim cannot be evaluated, such as if the caller is not authorized to view the results of the claim, an error should be returned in a standard format (๐Ÿƒ)

Multiple-claim response

When evaluating multiple claims, each claim must succeed or fail on its own. This is similar to the principles guiding the University API specification.

The response when evaluating multiple claims looks like this:

{
  "full_time_student": {
    "result": true,
    "metadata": {
    }
  },
  "some_other_claim": {
    "result": false,
    "metadata": {
    }
  },
  "metadata": {
    "๐Ÿƒ": "to shave",
    "available_claims": [
      "full_time_student",
      "some_other_claim"
    ]
  }
}

This includes objects for each requested claim, which must match result if the claim were requested individually. Each result is keyed by the name of the claim. Metadata about the entire set of claims is also returned (format: ๐Ÿƒ).

If a request is made to the /claims endpoint without any requested claims, the response should include the metadata section with a list of all available claims.

@derenhansen
Copy link

Joseph,

Here's the readme from my test_claim_engine:

domain-test-claims-engine

An API for for testing the claims engine concept.

Introduction

The Claim Adjudicator Module (CAM, aka the Claims Engine) provides a facet of the
domain contract through which other domains may verify information without having
to obtain a copy of that information. For example, in order to determine whether
a person is older than 21, many systems store that person's birth date. The CAM
enables domains to store the binary answer to the questions, "Is this person older
than 21?", instead of the more problematic date of birth.

Terminology

  • Claim - One or more tuples defining the relationship of the value of a concept to a reference value
  • Concept - A domain-specific value or state about which a claim may be validated. A concept can be anything from a single internal data element to the result of a complex internal process. That is, concepts can be more abstract than the properties associated with a domain's resources and subresources.
  • Qualifier - A verb that modifies the behavior of the claim engine. Qualifiers include ALL (the default), which requires all claims in the claim array to be true to verify the claim, and ONE, which requires only one of the claims in the claim array to be true to verify the claim.
  • Relationship - The claimed relationship between the value of the concept for the specified subject and the reference value. Relationships include "match," "greater-than-or-equal-to," and "less-than-or-equal-to."
  • Subject - A domain-specific resource identifier.

Description

More formally, the CAM determines whether a claimed relationship between the value
of the instance of a concept and a reference value can be verified.

One or more claims may be made in the context of a subject. A claim expression is
comprised of a subject identifier, a qualifier, and an array of claim tuples:

{
  "subject": "123456789",
  "qualifier": "ALL",
  "claims": [
  ]
}

The claim, "this person is older than 21," is expressed as a typed tuple:

{
  "concept": "age",
  "relationship": "greater-than-or-equal"
  "value": "21"
}

The CAM operates on domain-specific concepts. A concept may be anything from a
the value of a specific column in a row identified by the subject ID to a value
dynamically determined by a function.

In the older-than-21 example, the domain might subtract the birth date of the
subject from the current date to derive an age to compare with the reference value.

Discussion

The initial version of the CAM assumes a trusted environment. If a caller is authorized
to use the CAM API, the engine will respond. Domain implementation teams can control
the information that can be verified (and/or inferred) through the CAM by publishing
only necessary concepts.

The CAM responds only with a 200 (Verified) or a 404 (Not Verified). Aside from HTTP
connection and service errors (e.g., 403 and 500), an error of any sort results in
an unverifiable claim.

API

Note: An HTTP status code of 200 means the CAM responded, not that the claim was
verified. In order to determine whether the claim was verified, the caller must inspect

metadata.validation_response.code

  1. A validation response code of 200 indicates the claim was validated.
  2. A validation response code of 404 indicates the claim was not validated.

GET /

A GET on the CAM endpoint returns a list of the concept identifiers that can be
used in claims submitted to this domain.

{
  "metadata": {
    "validation_response": {
      "code": 200,
      "message": "Success"
    }
  },
  "values": [
    {
      "id": "age",
      "type": "integer",
      "range": "0-120"
    }
  ]
}

Note: The "type" and "range" properties are hints. The CAM will simply not
verify a claim if the reference value is nonsensical.

PUT /

A PUT on the CAM endpoint must include a claim body in the following form:

{
  "subject": "123456789",
  "qualifier": "ALL",
  "claims": [
    {
      "concept": "age",
      "relationship": "greater-than-or-equal",
      "value": "21"
    }
  ]
}

PUT / Response

The response is a UAPI standard metadata object, whose validation_response
code will be either 200 (the claim was verified) or 400 (the claim was
not verified)

{
  "metadata": {
    "validation_response": {
      "code": 200,
      "message": "Success"
    }
  }
}

PUT /batch

The /batch endpoint accepts an array of independent claims. It is a convenience
feature enabling callers that need to verify several claims do so with a
single request.

The PUT body is composed of an array of claims, to which a claim_id property
has been added.

{
  "values": [
    {
      "claim_id": "first",
      "subject": "123456789",
      "qualifier": "ALL",
      "claims": [
        {
          "concept": "age",
          "relationship": "greater-than-or-equal",
          "value": "21"
        }
      ]
    },
    {
      "claim_id": "second",
      "subject": "987654321",
      "qualifier": "ALL",
      "claims": [
        {
          "concept": "age",
          "relationship": "greater-than-or-equal",
          "value": "21"
        }
      ]
    }
  ]
}

PUT /batch Response

The response is an array of response objects composed of the claim_id and a
validation_response object

{
  "values": [
    {
      "claim_id": "1",
      "validation_response": {
        "code": 200,
        "message": "Verified"
      }
    },
    {
      "claim_id": "2",
      "validation_response": {
        "code": 404,
        "message": "Not Verified"
      }
    }
  ]
}

@derenhansen
Copy link

derenhansen commented Jan 18, 2019

[Here's a new ReadMe, updated to describe claim tuple qualifiers.]

domain-test-claims-engine

An API for testing the claims engine concept.

Introduction

The Claim Adjudicator Module (CAM, aka the Claims Engine) provides a facet of the
domain contract through which other domains may verify information without having
to obtain a copy of that information. For example, in order to determine whether
a person is older than 21, many systems store that person's birth date. The CAM
enables domains to store the binary answer to the questions, "Is this person older
than 21?", instead of the more problematic date of birth.

Terminology

  • Claim - A subject identifier and one or more tuples defining the relationship of the value of a concept associated with the subject and a reference value
  • Concept - A domain-specific value or state about which a claim may be validated. A concept can be anything from a single internal data element to the result of a complex internal process. That is, concepts can be more abstract than the properties associated with a domain's resources and subresources.
  • Mode - A verb that modifies the behavior of the claim engine. Modes include ALL (the default), which requires all claims in the claim array to be true to verify the claim, and ONE, which requires only one of the claims in the claim array to be true to verify the claim.
  • Qualifier - An optional object containing domain-specific properties that is passed to the concept resolution code to further qualify the claim.
  • Relationship - The claimed relationship between the value of the concept for the specified subject and the reference value. Relationships include "match," "greater-than-or-equal-to," and "less-than-or-equal-to."
  • Subject - A domain-specific resource identifier.

Description

More formally, the CAM determines whether a claimed relationship between the value
of the instance of a concept and a reference value can be verified.

One or more claims may be made in the context of a subject. A claim expression is
comprised of a subject identifier, a mode, and an array of claim tuples:

{
  "subject": "123456789",
  "mode": "ALL",
  "claims": [
  ]
}

The claim, "this person is older than 21," is expressed as a typed tuple:

{
  "concept": "age",
  "relationship": "greater-than-or-equal",
  "value": "21"
}

The CAM operates on domain-specific concepts. A concept may be anything from a
the value of a specific column in a row identified by the subject ID to a value
dynamically determined by a function.

In the older-than-21 example, the domain might subtract the birth date of the
subject from the current date to derive an age to compare with the reference value.

Qualifier

The claim tuple in the example above omitted the optional qualifier property.
A qualifier is an object with domain-specific properties. It is passed, along with
the subject ID to the concept resolution code to further qualify the claim.

[See PUT / below for an example.]

Discussion

The initial version of the CAM assumes a trusted environment. If a caller is authorized
to use the CAM API, the engine will respond. Domain implementation teams can control
the information that can be verified (and/or inferred) through the CAM by publishing
only necessary concepts.

The CAM responds only with a 200 (Verified) or a 404 (Not Verified). Aside from HTTP
connection and service errors (e.g., 403 and 500), an error of any sort results in
an unverifiable claim.

API

Note: An HTTP status code of 200 means the CAM responded, not that the claim was
verified. In order to determine whether the claim was verified, the caller must inspect

metadata.validation_response.code

  1. A validation response code of 200 indicates the claim was validated.
  2. A validation response code of 404 indicates the claim was not validated.

GET /

A GET on the CAM endpoint returns a list of the concept identifiers that can be
used in claims submitted to this domain.

{
  "metadata": {
    "validation_response": {
      "code": 200,
      "message": "Success"
    }
  },
  "values": [
    {
      "id": "age",
      "type": "integer",
      "range": "0-120"
    }
  ]
}

Note: The "type" and "range" properties are hints. The CAM will simply not
verify a claim if the reference value is nonsensical.

PUT /

A PUT on the CAM endpoint must include a claim body in the following form:

{
  "subject": "123456789",
  "mode": "ALL",
  "claims": [
    {
      "concept": "age",
      "relationship": "greater-than-or-equal",
      "value": "21",
      "qualifier": { ageOffset: -5 }
    }
  ]
}

PUT / Response

The response is a UAPI standard metadata object, whose validation_response
code will be either 200 (the claim was verified) or 400 (the claim was
not verified)

{
  "metadata": {
    "validation_response": {
      "code": 200,
      "message": "Success"
    }
  }
}

PUT /batch

The /batch endpoint accepts an array of independent claims. It is a convenience
feature enabling callers that need to verify several claims do so with a
single request.

The PUT body is composed of an array of claims, to which a claim_id property
has been added.

{
  "values": [
    {
      "claim_id": "first",
      "subject": "123456789",
      "mode": "ALL",
      "claims": [
        {
          "concept": "age",
          "relationship": "greater-than-or-equal",
          "value": "21"
        }
      ]
    },
    {
      "claim_id": "second",
      "subject": "987654321",
      "mode": "ALL",
      "claims": [
        {
          "concept": "age",
          "relationship": "greater-than-or-equal",
          "value": "21"
        }
      ]
    }
  ]
}

PUT /batch Response

The response is an array of response objects composed of the claim_id and a
validation_response object

{
  "values": [
    {
      "claim_id": "first",
      "validation_response": {
        "code": 200,
        "message": "Verified"
      }
    },
    {
      "claim_id": "second",
      "validation_response": {
        "code": 404,
        "message": "Not Verified"
      }
    }
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment