It's sometimes useful to be able to reuse fields already defined in a new type.

This approach not only simplifies the declaration of the new type, but also ensures consistency in the declaration of commonly used fields.

Take, for example, a set of fields for tracking the creation and modification of entities.

For this purpose, we can create a Traceable type :

type Traceable{
    createdBy:String
    createdDate:Date
    updatedBy:String
    updatedDate:Date
}

Fields of this type can then be reused in any other type, via the using instruction.:

type Address{
    using Traceable
    street : String
    zipCode:String !
    city:String !
    country:String
}

The metadata of imported fields can be enriched or overloaded in the type they are imported in.
Only the type of the field cannot be changed (for example, a String cannot be changed to an Integer).

If we re-specify the type (necessarily the same) the properties of the original field are not transferred to the new one and you can redefine it completely.

If we open the braces directly after the field name, the original properties are preserved and you can override them or add new ones.

In this example, we add a label to the imported fields createdDate (existing properties are transferred to the new field) and redefine updatedDate (properties defined on the imported field are ignored) and add a label property.

type Address{
    using Traceable
    createdDate{
        label:"Address creation date"
    }
    updatedDate:Date{
        label:"Address updated date"
    }
    street : String
    zipCode:String !
    city:String !
    country:String
}

Multiple using statements can be used in the same type to import fields from several other types.

 

Abstract types with the Extends keyword can also be used to reuse existing types, but it's better to use them to manage polymorphism.