📌 Important note :

Abstract types should be used when several objects share the same functional meaning (for example: Thirdparty -> LegalPerson, NaturalPerson) and you want to have fields like shareholder:Thirdparty that can be either a LegalPerson or a NaturalPerson.

This approach makes it possible to implement what is known as polymorphism, but introduces additional complexity into the model.

💡  For issues such as sharing fields définition between a large number of types (id, updatedDate... for example) we strongly recommend to :

 

Abstract types :

In modeling, it is sometimes useful to indicate that a field can be of more than one type.

Let's take for example the management of means of payment

An invoice can have a mean of payment which can be, for example, either a check, credit card or bank transfer.

So we need to have a field in the invoice that points to any means of payment.

To do this, akwatype allows to define abstract types. In the case of MeanOfPayment, for example, this abstract type will make it possible to describe what the different payment methods have in common and to create a common root for them.

The different means of payment will then extend this abstract type to indicate that they share this same common root.

example :

type Customer{
   name:String
   invoices:[invoice]  
}

type invoice{
   num:String
   amount:Decimal
   meanOfPaiement:MeanOfPayment
}
abstract MeanOfPayment{ name:String bank:String type:String } type CreditCard extends MeanOfPayment{ cardNumer:String expirationDate:Date securityCode:String } type Check extends MeanOfPayment{ checkNumber:String }
type bankTransfert extends MeanOfPayment{ eban:String }

 

 

CreditCard, Check and bankTransfer are all means of payment and inherit the name, bank and type fields in addition to their own fields


It may also be necessary to describe that a field only points to a subset of the objects that extend an abstract type.

For example, the type model defined that a MeanOfPayment could be a CreditCard, a Check or bankTransfer but we want to limit the possible MeanOfPayment for an invoice to CreditCard and Check.

Akwatype allows this by following the abstract type with :: followed by the list of possible types in brackets.

type invoice{
   num:String
   amount:Decimal
   meanOfPaiement:MeanOfPayment::(CreditCard,Check)
}

 

Definition of the field to determine which type is an abstract type object

When interpreting the content of a data exchange, it is necessary to know the type of the object being processed. In the case of an abstract type field, the type of the object can be variable, this is called polymorphism. It is then necessary to indicate which field will be used to determine the real type of the object according to its value.

Akwatype has the discriminator  { ... } declaration to give this information. In particular, discriminator will be used to set the discriminator property of openAPI descriptions.

type Check extends MeanOfPayment{
    checkNumber:String
    checkingAccountNumber:String
    discriminator{
      type:"01"
   }
}

type BankTransfert extends MeanOfPayment{
   eban:String
   creditTransfertType:String
   creditTransferObject:String
   discriminator{
      type:"02"
   }
}