Search code examples
c#swaggerapi-designopenapi

How to add allof type in Open API Specification 3.0?


We are following a design first approach for creating API.

One of the scenarios where we want to use Inheritance I am not able to define the spec for it.

This is the C# type for it

public class PublishRequest
    {

        [JsonProperty("notificationType")]
        public string NotificationType { get; set; }

        [JsonProperty("source")]
        public string Source { get; set; }

        [JsonProperty("timestamp")]
        public string Timestamp { get; set; }

        [JsonProperty("payload")]
        public List<BaseObject> Payload { get; set; }
    }

This class has a property for the BaseObject

 public class BaseObject
    {
        [JsonProperty("Id")]
        public string Id { get; set; }
    }

All the further type is inherited from this type which looks like this:

public class Accounts:BaseObject
    {
        [JsonProperty("phone")]
        public string Phone { get; set; }
        [JsonProperty("accountid")]
        public string AccountID { get; set; }
        [JsonProperty("name")]
        public string Name { get; set; }
        [JsonProperty("legalname")]
        public string LegalName { get; set; }
        [JsonProperty("website")]
        public string Website { get; set; }
        [JsonProperty("linkedin")]
        public string LinkedIn { get; set; }
        [JsonProperty("twitter")]
        public string Twitter { get; set; }
    }

The spec where these classes are used is this :

/notification/publish:
    post:
      summary: publish notification
      tags:
        - Notification
      requestBody:
        description: publish request body
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishRequest'
      responses:
        "200":
          description: success message

the problem I am facing is in defining the Schema for it.

Schema looks like this

PublishRequest:
      required:
        - notificationType
      properties:
        notificationType:
          type: string 
          enum: [account_created, account_updated]
        source:
          type: string 
          enum: [A, B]
        timestamp:
          type: string 
          format: date-time          
        payload: 
          $ref: "#/components/schemas/NotificationPayload"

    NotificationPayload:
      type: array
      items:
        oneOf:
          - $ref: "#/components/schemas/Account"        

    BaseObject:
      properties:
        Id:
          type: string
    Account:
     allOf:    
      $ref: '#/components/schemas/BaseObject'
      type: object
      properties:
        phone:
          type: string
        accountId:
          type: string
        name:
          type: string
        legalname:
          type: string  
        website:
          type: string
        linkedin:
          type: string
        twitter:
          type: string
        facebook:
          type: string
        defaultcurrency:
          type: string 

I keep getting this error in the swagger editor

Structural error at components.schemas.Account.allOf
should be array

Solution

  • The correct syntax for allOf is as follows. allOf takes a list of subschemas, so each subschema must be prefixed with - in YAML.

        Account:
          allOf:
            - $ref: '#/components/schemas/BaseObject'
            - type: object
              properties:
                phone:
                  type: string
                ...
    

    A couple of other things:

    • In NotificationPayload, items do not need oneOf because there's only one subschema.

          NotificationPayload:
            type: array
            items:
              $ref: "#/components/schemas/Account"
      
    • Remember to add type: object to object schemas, in this example - PublishRequest and BaseObject. The properties keyword alone is not enough to indicate the object type, and schemas without type actually mean "any type".