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

JSON Schema to Type mapping use cases #1266

Closed
3 tasks done
darrelmiller opened this issue Feb 25, 2022 · 3 comments
Closed
3 tasks done

JSON Schema to Type mapping use cases #1266

darrelmiller opened this issue Feb 25, 2022 · 3 comments
Assignees
Labels
enhancement New feature or request fixed generator Issues or improvements relater to generation capabilities.

Comments

@darrelmiller
Copy link
Member

darrelmiller commented Feb 25, 2022

This issue contains an example OpenAPI with a set of JSON Schema descriptions that should be supported by Kiota generators

Related issues:

openapi: 3.0.0
info:
  title: "Kiota supported Schemas"
  version: "1.0.0"
servers:
  - url: https://example.org
paths: 
  '/primativeString':
    get:
      responses:
        '200':
          description: Returns a primitive string 
          content: 
            'application/json': { schema: { type: string }}
            'text/plain': { schema: { type: string }}
      x-csharp: Task<string> GetAsync(...);

# Currently not supported as Number is not mapped to int.  
  '/primativeNumber':
    get:
      responses:
        '200':
          description: Returns a primitve number 
          content:  
            'application/json': { schema: { type: number, format: int32 }}}
            'text/plain': { schema: { type: string }}
      x-csharp: Task<int?> GetAsync(...); 
  '/primativeBool':
    get:
      responses:
        '200':
          description: Returns a primitive boolean 
          content: {'application/json': { schema: { type: boolean }}}
      x-csharp: Task<bool?> GetAsync(...);          
  '/nullablePrimativeBoolAsTextPlain':
    get:
      responses:
        '200':
          description: Returns a nullableprimitive boolean 
          content: {'text/plain': { schema: { type: boolean, nullable: true }}}
        '204':   
          description: No Content translates to a null value 
      x-csharp: Task<bool?> GetAsync(...);          
# Not supported due to type clash  
  '/stream':
    get:
      responses:
        '200':
          description: Return a stream of bytes 
          content: 
             'application/octet-stream': {}
             '*/*': {}  # Anything that is not application/json
      x-csharp: Task<Stream> GetAsync(...);          
  '/simpleObject':
    get:
      responses:
        '200':
          description: A response with an object type response
          content: { "application/json": { schema: { $ref: "#/components/schemas/simpleObject" }}}
      x-csharp: Task<SimpleObject> GetAsync(...);          
  '/derivedObject':
    get:
      responses:
        '200':
          description: A response with an derived object type response
          content: { "application/json": { schema: { $ref: "#/components/schemas/derivedObject" }}}
      x-csharp: Task<DerivedObject> GetAsync(...);
  '/collectionOfSimpleObject':
    get:
      responses:
        '200':
          description: A response with a collection of simple object type response
          content: { "application/json": { schema: { type: array, items: {$ref: "#/components/schemas/simpleObject"}}}}
      x-csharp: Task<Collection<SimpleObject>> GetAsync(...);
  '/typeOrDerivative':
    get:
      responses:
        '200':
          description: A response with an object from some inheritance hierarchy
          content: { "application/json": { schema: {$ref: "#/components/schemas/baseObject"}}}
      x-csharp: Task<BaseObject> GetAsync(...);
  '/typeOrDerivativeCollection':
    get:
      responses:
        '200':
          description: A response with a collection of objects from some inheritance hierarchy
          content: { "application/json": { schema: { type: array, items: {$ref: "#/components/schemas/baseObject"}}}}
      x-csharp: Task<Collection<BaseObject>> GetAsync(...);
  '/unionType':
    get:
      responses:
        '200':
          description: A response with two or more distinct types 
          content:
            'application/json':
              schema:
                title: unionResponse  # Workaround for issue #1270
                oneOf:
                - $ref: "#/components/schemas/simpleObject"
                - { type: number, title: numberResponse }
      x-csharp: Task<GetUnionTypeResponse> GetAsync(...);  # How do we name the properties?
  '/nullableSimpleObject':
    get:
      responses:
        '200':
          description: A response with an object type response
          content: { "application/json": { schema: { $ref: "#/components/schemas/simpleObject" }}}
        '204':
          description: A response with an object type but with null value
      x-csharp: Task<SimpleObject> GetAsync(...);          
  '/facetedObject':
    get:
      responses:
        '200':
          description: A response with an object type response
          content: 
            "application/json":
              schema: 
                title: facetedResponse # Workaround for issue #1270
                anyOf:  # properties should use title if available.  If not we should generate a name called <type>Facet
                  - type: string
                    title: stringFacet
                  - type: number
                    title: numberFacet
      x-csharp: Task<FacetedObjectResponse> GetAsync(...); 
components:
  schemas:
    simpleObject:
      type: object
      properties:
        name: { type: string }
    baseObject:
      type: object
      discriminator:
        propertyName: kind
      properties:
        name: { type: string }
        kind: { type: string }
    derivedObject:
      allOf:
      - $ref: "#/components/schemas/baseObject"
      - type: object
        title: derivedObject # Workaround for issue #1271
        properties:
          special: 
            type: string
    facetedObject:
      anyOf:
      - $ref: "#/components/schemas/facet1"
      - $ref: "#/components/schemas/facet2"
    facet1:
      type: object
      properties:
        prop1: {type: string}
    facet2:
      type: object
      properties:
        prop2: {type: string}
    collectionOf:
      type: array
      items:
        $ref: "#/components/schemas/simpleObject"

We need to have a deterministic mapping from JSON Schema to typing. There may still be some scenarios we have not yet described.

  • oneOf, anyOf, allOf * 0,1 or n.

an instance or collection of:

  • union type,
  • inheritance (all or subset)
  • exclusion type (XOR)
  • interfaces
@darrelmiller darrelmiller self-assigned this Feb 25, 2022
@baywet baywet added enhancement New feature or request generator Issues or improvements relater to generation capabilities. needs more information labels Feb 25, 2022
@baywet baywet added this to Kiota Feb 25, 2022
@baywet baywet moved this to Todo in Kiota Feb 25, 2022
@darrelmiller darrelmiller changed the title How can we detect a union vs inheritance hierarchy in a schema? JSON Schema to Type mapping use cases Feb 28, 2022
@baywet
Copy link
Member

baywet commented Mar 11, 2022

https://spec.openapis.org/registry/format/

missing:

  • int32: integer
  • int8: sbyte
  • unit8: byte
  • byte: byte
  • commonmark : string
  • html: string

@darrelmiller
Copy link
Member Author

The only thing remaining to support in the example above is using stream as the response type when the media type is unrecognized.

@baywet
Copy link
Member

baywet commented Mar 31, 2022

closing as that last aspect is already captured by #546 and handled in another PR.

@baywet baywet closed this as completed Mar 31, 2022
Repository owner moved this from Todo to Done in Kiota Mar 31, 2022
@baywet baywet added the fixed label Mar 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request fixed generator Issues or improvements relater to generation capabilities.
Projects
Archived in project
Development

No branches or pull requests

2 participants