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.
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.
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}
.
Claims are evaluated by sending a GET request to the appropriate endpoint.
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
.
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
Claim endpoints respond with a simple true/false answer, plus metadata about the claim.
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"
}
}
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 (๐)
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.
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
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:
The claim, "this person is older than 21," is expressed as a typed tuple:
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
GET /
A GET on the CAM endpoint returns a list of the concept identifiers that can be
used in claims submitted to this domain.
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:
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)
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.
PUT /batch Response
The response is an array of response objects composed of the claim_id and a
validation_response object