belgif / rest-guide

REST Guidelines of Belgian government institutions
https://www.belgif.be/specification/rest/api-guide/
Apache License 2.0
24 stars 4 forks source link

Naming of properties and types for codes #94

Closed pvdbosch closed 1 year ago

pvdbosch commented 2 years ago

When interpreting the current guidelines strictly, code porperties and types should be named "id". This seems to be weird for readers, as "code" is more meaningful in these cases. Should we allow "code" in the naming convention as well?

Example:

    CivilStateId:
      description: The civil state of a person, represented by a code assigned by the National Register
      type: integer
      minimum: 1
      maximum: 99
"civilState": {
   "id": 3,
   "description": "married"
}

This naming follows from the naming convention of identifiers, and that codes are a special type of identifiers.

"The identifier should be named `id` unless there already exists another standardized name for the business identifier."

In a JSON representation, it SHOULD NOT be prefixed unless the identifier is not of the resource on which the operation applies and there’s ambiguity.

If the identifier is used as path parameter, it should be prefixed by the resource type.
A code is a special type of identifier:
* it has an exhaustive list of possible values that doesn’t change frequently over time
* each value identifies a concept (examples: a country, a gender, …​).
pvdbosch commented 2 years ago

WG is OK with proposed change, I'll work on a PR.

pvdbosch commented 2 years ago

While working on a PR, I think we need to refine the rule a bit. If we apply the same rule of "id" to "code", the code suffix would also need to be added to these examples:

"state": "processing" #from LongRunningTaskStatus => stateCode?

"pensionType": "survivalPension"  # example from the guide => pensionTypeCode?

PensionType:
  type: string
  enum:
  - retirementPension
  - survivalPension
  - guaranteedIncomeElderly
pvdbosch commented 2 years ago

Discussion was reopened.

To recap:

Goal: naming guidelines for properties and types for codes

Semantic standards (RDF, Skos etc):

There may be multiple alternative ConceptSchemes for a single property e.g. NIS code and an ISO alpha2/alpha3/num3 for a country

Examples:

pseudo-rdf:

<CountryIsoAlpha2> is a ConceptScheme
<BE> is a Concept
<BE> is part of scheme <CountryIsoAlpha2>

<country> is a property of <Address>
<country> can be represented with a concept in <CountryIsoAlpha2>

<nationality> is a property of <Person>
<nationality> can be represented with a concept in <CountryIsoAlpha2>

REST/OpenAPI:

Examples of possible JSON:

{
  "ssin": "00000000196",
  "gender": 1,
  "nationality": "BE",
  "address": {
     "street": "Willebroekkaai",
     "municipality": "Brussels",
     "country" : "BE"
 }

{
  "ssin": "00000000196",
  "gender": {
       "code": 1,
       "description": "female"
   }
  "nationality": {
       "code": "BE",
       "description": {
           "nl": "België",
           "fr": "Belgique"
       }
    "address": {
        "street": "Willebroekkaai",
         "municipality": "Brussels",
         "code": "BE",
         "description": {
            "nl": "België",
            "fr": "Belgique"
         }
    }
}

types:


#alternative A - without labels/descriptions

CountryIsoCode:
    description: Country represented by an ISO 3166-1 alpha-2 code
    type: string
    pattern: "^[A-Z]{2}$"

GenderCode:
   type: integer
   enum:
     - 0 
     - 1
     - 2

Person:
  type: object
  properties:
     nationality: {"$ref":  "../belgif-openapi-location-v1#/CountryIsoCode"}
     gender: {"$ref":  "../belgif-openapi-person-v2#/GenderCode"}
      # ... 

# alternatives with description included

Person: 
  type: object
  properties:
     nationality: {"$ref":  "CountryWithDescription"}
     gender: {"$ref":  "GenderWithDescription"}
      # ...

CountryWithDescription:
  type: object
  properties:
     code: {"$ref":  "../belgif-openapi-location-v1#/CountryIsoCode"}
     description: {"$ref":  "../belgif-openapi-common-v1#LocalizedString"}

GenderWithDescription:
  type: object
  properties:
     code:  {"$ref":  "../belgif-openapi-person-v2#/GenderCode"}
     description: {"$ref":  "../belgif-openapi-common-v1#LocalizedString"}
pvdbosch commented 1 year ago

My proposition:

Give name to ConceptScheme and OpenAPI types: trade-off between

E.g.

JSON property names should correspond to fedvoc, but their value may be, dependent on the specifications of a specific REST API, either:

Impact: location codes, gender code, ... ???

pvdbosch commented 1 year ago

addendum: if "code" is part of the business name of a ConceptScheme, it can be kept (e.g. postCode)

proposition OK for functional WG; to be validated yet by technical REST WG

To be decided for existing definitions: change them or leave them?

pvdbosch commented 1 year ago

discussed on REST design WG:

For properties, multiple codes could be included in a single object value, e.g.

"country": {
  "nisCode": 150,
  "isoCode": "BE",
  "description": "Belgium"
}

But when evolving APIs it could be necessary to deviate from the guideline in order to ensure backwards compatibility.

There was a discussion on guidelines whether to include descriptions of codes in each message, or only in refData resources with href; this is split to separate issue #101

Next actions:

pvdbosch commented 1 year ago

after discussion in WG, aligned and merged the rules on codes and identifiers.

Rationale for current draft:

New draft rule (also in PR #109)


Following naming guidelines should be applied when designating an identifier of code within a REST API:

As an exception, when a standardized name for the business identifier already exists, its use is always preferred over id or code.

If multiple identifiers or coding schemes may be used within a context, a suffix can be added to the name to disambiguate.


Also updated JSON property naming rule:

"the name should refer to the business meaning of its value in relation to the object in which it is specified, rather than how it is defined"

I added a lot of examples (they'll need to be cleaned up). Some of them:

GET /persons/{ssin}

{
  "ssin": "12345678901",
  "partner": "2345678902", # value is of type Ssin
  "civilState": 1
}

GET /refData/deliveryMethods/{code}

{
  "code": "deliveredAtHome",
  "description": {
     "nl": "Geleverd aan huis",
     "en": "Delivered at home",
     "fr": "Livré à domicile"
  }
}
pvdbosch commented 1 year ago

rest guide WG:

pvdbosch commented 1 year ago

PR for suffix "Code" or "Id" to type names (will have to be validated by functional WG as well): https://github.com/belgif/rest-guide/pull/119

Impact on https://github.com/belgif/openapi-person/issues/2 , new names are:

For these, they need to end with TypeCode to distinguish with other definitions (not part of the person-openapi file), e.g.:

Related question: should we standardize on name of types for partial resource representations? => https://github.com/belgif/rest-guide/issues/120

pvdbosch commented 1 year ago

openapi-money is impacted by decision to suffix types with "Code" or "Id":