7 ms·
Maybe you can tell me if there's a better solution. I'm open to hearing any options because I'm at a loss of how to do this otherwise: Say we have a schema whi
by sebmellen 5y ago
Maybe you can tell me if there's a better solution. I'm open to hearing any options because I'm at a loss of how to do this otherwise:
Say we have a schema which defines certain data. Let's say it's a "credential" which is a "COVID-19 Back to Work Credential." The credential is valid in the case that someone either 1) has a COVID vaccination or 2) has a negative COVID test in the past 72 hours. That data might look like this:
{
"credentialName": "COVID-19 Back to Work Credential",
"credentialIssuer": "Acme Labs Inc.",
"credentialData": {
"rapidSarsCov2PCRTest": {
"hasTestResult": true,
"testResult": "negative",
"testTime": 1622145851
},
"covid19Vaccination": {
"hasVaccination": false
}
}
}
Now, say I want to define the conditions under which this "credential" is valid or invalid, but I want to include this "matrix" within the schema (not any business logic, just matrix logic that pertains to the data within the schema itself).
Optimally, I'd be able to do this within the same schema or file.
With JsonLogic, that might look like this (probably flawed logic, just a demo, not using this in production, may cause your computer to go up in flames, etc.):
{
...
"parsingMatrix": {
"if": [
{
"or": [
{
"===": [
{ "var": "credentialData.rapidSarsCov2PCRTest.testResult" },
"negative"
]
},
{
"===": [
{ "var": "credentialData.covid19Vaccination.hasVaccination" },
true
]
}
]
},
"valid",
"invalid"
]
}
}
Can you think of another way to do this that doesn't rely on using JsonLogic or something like it (or a cleaner method for doing it in JSON)?
- asah 5y agoI'm not sure how to express how much I loathe everything about this "solution." To answer your question, what you have is (effectively) code, and just use a programming language for this, call it a function, give it a name, arguments, test suite and register it as a plugin to your platform. Oh, and documentation, change history, etc. Seriously - the "overhead" more than pays for itself when 100 other yahoos do this nonsense and you end up with data files containing untestable code that breaks when combined with other code, breaks when the platform is changed, etc etc
- sebmellen 5y agoOk, I take your point, but let's say we need to share these credential objects between different systems that do not have prior knowledge of how to evaluate the credential data. Also, let's say we constrain the logic to only allow for evaluation of any given part of the credential data against a binary "pass | fail" matrix. What is a better way to share this important part of the schema (the matrix) without resorting to letting the "business logic" perform the evaluation? Optimally, any matrix should be able to run against the same business logic for evaluation. Also, though I understand why you say that, we won't have "100 other yahoos doing this nonsense," and each schema would go through a pretty thorough review process.
- omegaworks 5y agoIf your business logic doesn't meet the needs of your business without the schema, the schema is a part of your business logic, that should be subjected to a suite of automated tests. If your concern is the sharability, consider making a library or service that provides the business logic.
- sebmellen 5y agoWe'd like to be able to include evaluation matrices within credentials as an extension to the Verifiable Credentials standard (see https://www.w3.org/TR/vc-data-model/ https://www.w3.org/TR/vc-data-model/). Optimally, different libraries and different services will be able to evaluate a credential using the credential's included matrix (i.e. the evaluation matrix should not be reliant on any business logic from any particular party). I can't get too deep into the use-case but having these parts bundled together is important for what we're working on.
- deleted 5y ago[deleted]
- valenterry 5y ago> but let's say we need to share these credential objects between different systems that do not have prior knowledge of how to evaluate the credential data Well, they _must_ have prior knowledge about it, because they must have to understand the concept of JsonLogic beforehand. So instead, you can just make these systems understand a proper programming language that can produce outputs. Something like https://github.com/dhall-lang/dhall-lang https://github.com/dhall-lang/dhall-lang would probably be a much better option for this usecase.
- goto11 5y agoHow about representing the logic as a JavaScript expression: (credentialData.rapidSarsCov2PCRTest.testResult==='negative') || credentialData.covid19Vaccination.hasVaccination) ? 'valid' : 'invalid' Seem easier to read and maintain to me.
- sebmellen 5y agoI'd love to do this, the only problem there is we're sharing this data between systems which use different runtimes. A client who runs a Python environment might not easily be able to make use of that logic. With JsonLogic, that would theoretically be possible.
- goto11 5y agoYou can easily write a parser for this in Python. As long as you only support expressions it should be pretty straightforward.
- sebmellen 5y agoI see your angle. I'll consider this. Thanks for the ideas!
- adamkl 5y agoI posted this in another thread, but it seems relevant to what you are looking for: https://stopa.io/post/265 https://stopa.io/post/265 It walks through the process of building a Lisp in JSON and the associated parser in JavaScript. It could be a good starting point to build out a cross-platform approach to sending logic over the wire.
- sebmellen 5y agoNice, looks quite neat. I'll dive into it a bit deeper!
- chousuke 5y ago
- 0xFACEFEED 5y agoStraw man. With all due respect, you're making a classic mistake: presenting the solution to a problem without tracing the problem back to the use case. Why do you need to include the logic matrix in the schema? I can promise you that the real world use cases where you'd need to this are virtually non-existent. You wouldn't even do this for some extreme case like Mars rover software. Your business logic should have a single source of truth. The vast majority of the time you can just write an API for other software to synchronize with. Otherwise just ship new builds of your software package to the client instead of a new schema. If you need to be modular then use modular primitives such as shared libraries. Again, there's virtually no real world scenario where you need to ship a logic schema (in any format) to a client. You might as well ship a shared library, importable module, a completely new binary, etc, etc.
- sebmellen 5y agoInteroperability is the main reason. We need this data and the evaluation matrix to be portable across different "credential wallets" as part of a standard model for matrix evaluation of Verifiable Credentials (as an extension that we're working on to the existing data model https://www.w3.org/TR/vc-data-model/ https://www.w3.org/TR/vc-data-model/).
- 0xFACEFEED 5y agoYou didn't state the use case initially. The context of the discussion is evaluating the value of the approach. What I'm saying is that you can't make that evaluation without stating the use case. Obviously one can think up a scenario where JsonLogic can be useful - that doesn't mean anything. > Interoperability is the main reason. We need this data and the evaluation matrix to be portable across different "credential wallets" as part of a standard model for matrix evaluation of Verifiable Credentials (see also https://www.w3.org/TR/vc-data-model/ https://www.w3.org/TR/vc-data-model/). Representing verification logic in the schema flawed. Just because the W3C publishes a spec doesn't make it good. So I guess one of the few valid use cases for JsonLogic (or similar) is if your company makes a bad technical decision and you're forced to implement something?
- contravariant 5y agoWhat about: ["if", ["or", ["===", ["var", "credentialData.rapidSarsCov2PCRTest.testResult" ], "negative"], ["===", ["var", "credentialData.covid19Vaccination.hasVaccination"], true ] ], "valid", "invalid"] ?
- sebmellen 5y agoThat's nice, I like it! We don't really need anything more than this. It's hard to gauge whether or not it's better to go with an existing, possibly inferior standard, or to create a new one, like this... https://xkcd.com/927/ https://xkcd.com/927/
- contravariant 5y agoI mean it is just lisp denoted in javascript lists, but sure we can call it a new standard if you like.
- sebmellen 5y agoIf this works out we'll either be adopting a previous standard or defining a new one for these evaluation matrices! But yes, does look like other people have grazed this idea as well: https://www.i-programmer.info/programming/javascript/2380-javascript-data-structures-a-lisp-like-list.html https://www.i-programmer.info/programming/javascript/2380-ja....
- mmcdermott 5y agoClojure Spec works really well for this sort of thing. It doesn't serialize to JSON, but it would be able to check for it. You could also think about Dhall as a front-end. You could represent the whole credential as a union type. This isn't deeply thought out, but this should give an idea as to how this would look: let TestResult = < Positive | Negative > let ScreeningTestDetails = { hasTestResult : Bool, testResult : TestResult, testTime : Natural } let CredentialData = < Vaccinated | RapidSarsCov2PCRTest : ScreeningTestDetails > let Credential = { credentialName : Text , credentialIssuer : Text , credentialData : CredentialData } let result : Credential = { credentialName = "COVID-19 Back to Work Credential" , credentialIssuer = "Acme Labs Inc." , credentialData = CredentialData.Vaccinated } let result2 : Credential = { credentialName = "COVID-19 Back to Work Credential" , credentialIssuer = "Acme Labs Inc." , credentialData = CredentialData.RapidSarsCov2PCRTest { hasTestResult = True , testResult = TestResult.Negative , testTime = 1622145851 } } let prop0 = λ(x : ScreeningTestDetails) → assert : greaterThan x.testTime 1522145851 ≡ True in result2 Notice here that the type for credential data can only be vaccinated or a test result. It can't even represent unvaccinated. You could probably take it farther with dependent types and assertions. Edit: added an assertion to model the 72 hour requirement.
- shaunxcode 5y agoI cant help but imagine what it would like like in EDN: {... parsingMatrix (if (or (=== (var "credentialData.rapidSarsCov2PCRTest.testresult") "negative") (=== (var "credentialData.covid19Vaccination.hasVaccination") true)) "valid" "invalid")}
- sebmellen 5y agoI presume jsedn is your library [0]? I was heretofore unaware of EDN, but it looks like a very clean fit for our needs. I will examine this more in depth, thank you. [0]: https://github.com/shaunxcode/jsedn https://github.com/shaunxcode/jsedn
- shaunxcode 5y agoIt is, but to be clear it is out-moded by the fact that cljs exists now!
- rauhl 5y ago> Can you think of another way to do this that doesn't rely on using JsonLogic or something like it (or a cleaner method for doing it in JSON)? This strikes me as nice: (parsing-matrix (if (or (= (var "credentialData" "rapidSarsCov2PCRTest" "testResult") "negative") (= (var "credentialData" "covid19Vaccination" "hasVaccination") "negative")) "valid" "invalid"))
- nanis 5y ago> With JsonLogic, that might look like this Here is the thing...There is already a crappy way to describe JSON Schemas[1,2]. It is hard to grok by visual inspection and expressing conditions like "this element can either be a list containing a subset of these values or a hash with keys that belong to the same set" etc make it unwieldy. The schema ends up being really brittle and hard to modify. 100% green-lit test coverage don't mean a thing when it is soooo easy to end up with a false negative. Now take that and add logic to it? One has to question the existence of all the programming languages in use if we are going to end up subjecting ourselves to that torture. [1]: https://json-schema.org/ https://json-schema.org/ [2]: https://json-schema.org/draft/2020-12/json-schema-core.html https://json-schema.org/draft/2020-12/json-schema-core.html
- Seb-C 5y agoJson schema is very useful and is not the same thing as this. Json schema validates the data structure, while this seems to be more about writing algorithms in json