RESOStandards / transport

RESO Transport Workgroup - Specifications and Change Proposals
https://transport.reso.org
Other
18 stars 15 forks source link

Data Shapes and Context in DD JSON Payloads #62

Closed darnjo closed 1 year ago

darnjo commented 1 year ago

Discussed in https://github.com/RESOStandards/transport/discussions/58

The goal of this issue is to incorporate the following changes into RCP-025.

Originally posted by **darnjo** October 29, 2022 # Summary In the Data Dictionary JSON Payloads Proposal (RCP-025), there are a couple of things that might be nice to address in order to generalize it to any JSON Web API or use case: * The ability to include a single value or an array of values in the response * A request context so the data consumer or producer can indicate the Data Dictionary model and version See the [Data Dictionary JSON Payloads specification (RCP-025)](https://github.com/RESOStandards/transport/blob/44-migrate-rcp-025-from-confluence/dd-json-payloads.md) for more information. # Single- vs. Multi-Valued Payloads In the original RCP-025 proposal, payloads were single-valued, meaning that the requested entity would show up at the top level of the response. For example, if a payload had a single record from the Property Resource (say with ListPrice), then the response would be similar to the following: **Request** ``` GET https://api.service.com/ ``` **Response** ``` { "ListPrice": 12345 } ``` While this is more transport-agnostic, OData offers the ability to return multiple records using a `value` array. Is this something we'd also want to support in Data Dictionary JSON Payloads? It seems like it is. For example, in the case of an assessor payload, the URL might return a collection of records rather than having the consumer request each record separately. To make this compatible with existing RESO Web API implementations, the payload might look something like this: **Request** ``` GET https://api.service.com/ ``` **Response** ``` { "value": [{ "ParcelNumber": "ABC123", "TaxAssessedValue": 342555.33 }, { "ParcelNumber": "DEF456", "TaxAssessedValue": 1942556.00 }] } ``` I think it's possible to support both shapes. One question would be whether it's necessary to indicate whether something is a single record or a collection. Since the collections always have a `value` property, that gives producers and consumers a way to know whether something consists of one or many items. # Context Another consideration with Data Dictionary JSON Payloads is that they should support any model provided by the RESO Data Dictionary, which also includes versioning since schema can change significantly between versions. Since there's no guarantee that the URL indicates which resource the data came from as there is in OData and current RESO Web API conventions (e.g. `/Property`), additional information is needed to make that determination. As such, it seems like a good idea to add a non-breaking property to the payload to indicate which RESO context the response is in. RESO has a URN namespace: https://www.iana.org/assignments/urn-formal/reso In section 3.4.1 (a), there's an example of a versioned resource element: ``` 3.4.1 RESO Data Dictionary Metadata Elements (a) Versioned Metadata Resource Element Format: urn:reso:metadata:{version}:resource:{resource-name} where "version" MAY have values such as "1.6" or "1.7", and "resource-name¨ is one of "Property", "Member", "Office", or other resource definitions RESO provides (see references). Example: urn:reso:metadata:1.7:resource:property ``` If the content of the Data Dictionary JSON Payload referred to data from a Data Dictionary 1.7 Property Resource, the response might contain the following: ``` { "@reso.context": "urn:reso:metadata:1.7:resource:property", "value": [ { "ParcelNumber": "ABC123", "TaxAssessedValue": 342555.33 }, { "ParcelNumber": "DEF456", "TaxAssessedValue": 1942556.0 } ] } ``` The example above shows the case where the keys are not yet known. For example, the record has not been created yet. In cases where the external URL only refers to a single record, the response might be as follows: ``` { "@reso.context": "urn:reso:metadata:1.7:resource:property", "ListingKey": "a1", ... } ``` This allows the consumer of a given external payload to know which resource or record it's targeting. If the data does not contain a key, the consumer of the Data Dictionary JSON Payload would know that one needs to be created. If it does, then they'd know which existing record to associate it with. Since any related expansions like Rooms and Media are already part of the Property model, the Data Dictionary JSON Payload would automatically include those as well.
darnjo commented 1 year ago

Information in the specification updated. See: https://github.com/RESOStandards/transport/blob/44-migrate-rcp-025-from-confluence/dd-json-payloads.md