Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always express structured types as flat properties #372

Open
wants to merge 6 commits into
base: main
Choose a base branch
from

Conversation

daogrady
Copy link
Contributor

@daogrady daogrady commented Oct 22, 2024

Fixes internal issue 14369

type Point {
  x: Integer;
  y: Integer;
}

entity Thing {
  position: Point
}

shall result in

class Point {
  x: number
  y: number
}

class Thing {
  position_x: number
  position_y: number
}

instead of

class Thing {
  position: Point
}

@stockbal
Copy link
Contributor

stockbal commented Oct 26, 2024

Hi @daogrady,

I think this has to be implemented depending on two factors:

  • entity or type
  • arrayed or non-arrayed

Consider the following CDS model:

// /db/datamodel.cds
type Author {
  firstName : String(60);
  lastName  : String(60);
  address   : {
    place   : String(30);
    zip     : String(10);
  };
}

entity Books : cuid {
  title        : String;
  author       : Author;
  otherAuthors : array of Author;  
  inlineAuthor : {
    firstName : String;
    lastName : String;
  };
  inlineAuthors: array of {
    name : String;
    address : {
      place : String;
    }
  };
}

// /srv/cat-service.cds
using {my.bookshop} from '../db/data-model';

service CatalogService {
  @readonly entity Books as projection on bookshop.Books;
} 

This will result in the following OData metadata for the CatalogService:

<Schema Namespace="CatalogService" xmlns="http://docs.oasis-open.org/odata/ns/edm">
    <EntityContainer Name="EntityContainer">
        <EntityType Name="Books">
            <Property Name="title" Type="Edm.String"/>
            <Property Name="authors" Type="Collection(CatalogService.my_bookshop_Author)" Nullable="true"/>
            <Property Name="otherAuthors" Type="Collection(CatalogService.my_bookshop_Author)" Nullable="true"/>
            <Property Name="inlineAuthor_firstName" Type="Edm.String"/>
            <Property Name="inlineAuthor_lastName" Type="Edm.String"/>
            <Property Name="inlineAuthors" Type="Collection(CatalogService.Books_inlineAuthors)" Nullable="true"/>
            <Property Name="author_firstName" Type="Edm.String" MaxLength="60"/>
            <Property Name="author_lastName" Type="Edm.String" MaxLength="60"/>
            <Property Name="author_address_place" Type="Edm.String" MaxLength="30"/>
            <Property Name="author_address_zip" Type="Edm.String" MaxLength="10"/>    
        </EntityType>
        <ComplexType Name="Books_inlineAuthors">
            <Property Name="name" Type="Edm.String"/>
            <Property Name="address" Type="CatalogService.Books_inlineAuthors_address"/>
        </ComplexType>
        <ComplexType Name="Books_inlineAuthors_address">
            <Property Name="place" Type="Edm.String"/>
        </ComplexType>
        <ComplexType Name="my_bookshop_Author">
            <Property Name="firstName" Type="Edm.String" MaxLength="60"/>
            <Property Name="lastName" Type="Edm.String" MaxLength="60"/>
            <Property Name="address" Type="CatalogService.my_bookshop_Author_address"/>
        </ComplexType>
            <ComplexType Name="my_bookshop_Author_address">
            <Property Name="place" Type="Edm.String" MaxLength="30"/>
            <Property Name="zip" Type="Edm.String" MaxLength="10"/>
        </ComplexType>
    </EntityContainer>
</Schema>

According to this, entity elements that are non-arrayed and structured are flattened regardless if they are concrete types or inline. However, elements with arrayed structured types converted into collections of complex types and are therefore kept structured.

The resulting (simplified) types should therefore look something like this:

// class for type Author
class Author {
  firstName: string;
  lastName: string;
  address: {
    place: string;
    zip: string;
  }
}
// class for entity Books
class Book {
  title: string;
  inlineAuthor_firstName: string;
  inlineAuthor_lastName: string;
  inlineAuthors: Array<{
    name: string;
    address: {
      place: string;
    };
  }>;
  otherAuthors: Array<Author>;
  author_firstName: string;
  author_lastName: string;
  author_address_place: string;
  author_address_zip: string;
}

@daogrady
Copy link
Contributor Author

Hi @stockbal ,

thank you very much for weighing in on this change and pointing out this nuance! 🙂
I will actually shelve this PR for now, as the (internal) issue that prompted this change has been resolved for now, so unless other users run into this (still factually wrong) behaviour, I would like to deprioritise it for now.

Best,
Daniel

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants