Swagger for EPiServer Content API

Vote:
 

Wondering how can we get the swagger to set it up in Azure API Mangement Tool for EPiServer Content API?

https://world.episerver.com/documentation/developer-guides/CMS/Content/content-delivery-api/

#194264
Jun 18, 2018 13:17
Vote:
 

I can see some magic has been applied at https://sdk.episerver.com/ContentDeliveryAPI/ by https://github.com/twskj/pretty-swag, my bad, had to dig further how to get swagger back

#194266
Jun 18, 2018 14:11
Vote:
 

Have you tried Swashbuckle https://github.com/domaindrivendev/Swashbuckle?

#194282
Jun 18, 2018 18:50
Vote:
 

Yep, this was the first thing, I installed this but getting 404 for /swagger and /swagger/docs/v1

#194283
Jun 18, 2018 19:58
Vote:
 

@Johan, I dropped you a message on emvp yammer.

#194284
Jun 18, 2018 20:01
Vote:
 

K Khan, have you got this to work?

I just tried it out with version 2 of the Content Api and it works perfectly

#197558
Oct 07, 2018 20:54
Vote:
 

Thanks for chasing, Yep, I managed that, but there was a lot of (EPiFind) fuss that I had to manage to get a correct swagger.

/K

#197648
Oct 09, 2018 14:03
Vote:
 

I managed with swashbuckle.

/K

#197649
Oct 09, 2018 14:05
Vote:
 

Yes, a lot to filter away...

private class EPiServerDocumentFilter : IDocumentFilter
        {
            private readonly string[] assembliesToExclude = new string[]
            {
                "EPiServer",
                "EPiServer.ApplicationModules",
                "EPiServer.BaseLibrary",
                "EPiServer.Configuration",
                "EPiServer.Data.Cache",
                "EPiServer.Data",
                "EPiServer.Enterprise",
                "EPiServer.Events",
                "EPiServer.Find.Cms",
                "EPiServer.Find",
                "EPiServer.Find.Framework",
                "EPiServer.Find.Optimizations",
                "EPiServer.Find.Statistics",
                "EPiServer.Find.UI",
                "EPiServer.Find",
                "EPiServer.Framework",
                "EPiServer.ImageLibrary",
                "EPiServer.Implementation",
                "EPiServer.Licensing",
                "EPiServer.LinkAnalyzer",
                "EPiServer.Logging.Log4Net",
                "EPiServer.Shell",
                "EPiServer.Web.WebControls",
                "EPiServer.WorkflowFoundation",
                "EPiServer.XForms"
            };

            public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
            {
                foreach (var description in apiExplorer.ApiDescriptions)
                {
                    if (description.ActionDescriptor == null)
                    {
                        continue;
                    }

                    if (description.ActionDescriptor.ControllerDescriptor == null)
                    {
                        continue;
                    }

                    if (description.ActionDescriptor.ControllerDescriptor.ControllerType == null)
                    {
                        continue;
                    }

                    if (description.RelativePath.StartsWith("episerver"))
                    {
                        var apiPath = description.RelativePathSansQueryString();

                        swaggerDoc.paths.Remove("/" + apiPath);

                        continue;
                    }

                    var assemblyName = description.ActionDescriptor.ControllerDescriptor.ControllerType.Assembly.GetName();

                    if (this.assembliesToExclude.Contains(assemblyName.Name, StringComparer.InvariantCultureIgnoreCase))
                    {
                        var apiPath = description.RelativePathSansQueryString();

                        swaggerDoc.paths.Remove("/" + apiPath);
                    }
                }
            }
        }
#197650
Oct 09, 2018 14:28
Vote:
 

true, still, final swagger didn't work with Azure api management, dont remember exactly what was message, I have to rely on this swagger by changing end points that we got on yammer

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "Episerver Content Api"
  },
  "basePath": "/",
  "tags": [
    {
      "name": "Content Api",
      "description": "Load IContent via IContentLoader"
    },
    {
      "name": "Content Search Api",
      "description": "Search for IContent via Episerver Find"
    },
    {
      "name": "Site Definition Api",
      "description": "Access site information, languages, and content roots"
    }
  ],
  "schemes": [
    "https"
  ],
  "paths": {
    "/api/episerver/search/content": {
      "get": {
        "tags": [
          "Content Search Api"
        ],
        "summary": "Search for content",
        "description": "",
        "operationId": "contentSearch",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "filter",
            "type": "string",
            "in": "query",
            "description": "Specify a filter string to be applied to the search. Filter strings utilize OData v4 filter syntax"
          },
          {
            "name": "orderby",
            "type": "string",
            "in": "query",
            "description": "Specify an orderby string to be applied to the search. Orderby strings utilize OData v4 sort syntax"
          },
          {
            "name": "query",
            "type": "string",
            "in": "query",
            "description": "Free text search to filter content. Supports query string syntax for searching in individual fields"
          },
          {
            "name": "skip",
            "type": "integer",
            "in": "query",
            "description": "Specify number of items to skip in returned search results (used for pagination)"
          },
          {
            "name": "top",
            "type": "integer",
            "in": "query",
            "description": "Specify number of items to return in search results (used for pagination)"
          },
          {
            "name": "personalize",
            "type": "boolean",
            "in": "query",
            "description": "Determines if returned content will be personalized (via the Visitor Group system) when returned. By default, content will be fetched in the context of an anonymous user."
          },
          {
            "name": "expand",
            "type": "string",
            "in": "query",
            "description": "Comma-separated list of reference properties (Content References, Content Areas) which should have their content fetched in the response. Passing \"*\" will load content in all reference properties in the return."
          },
          {
            "name": "Accept-Language",
            "type": "string",
            "in": "header",
            "description": "Determines in which languages content should be retrieved. Example - en-US,sv"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/SearchResponse"
              }
            }
          }
        }
      }
    },
    "/api/episerver/content": {
      "get": {
        "tags": [
          "Content Api"
        ],
        "summary": "Retrieve multiple content items",
        "description": "",
        "operationId": "getContents",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "references",
            "type": "array",
            "items": {
              "type": "string"
            },
            "in": "query",
            "description": "List of content reference to load content"
          },
          {
            "name": "guids",
            "type": "array",
            "items": {
              "type": "string"
            },
            "in": "query",
            "description": "List of content guids to use to load content"
          },
          {
            "name": "expand",
            "type": "string",
            "in": "query",
            "description": "Comma-separated list of reference properties (Content References, Content Areas) which should have their content fetched in the response. Passing \"*\" will load content in all reference properties in the returned response."
          },
          {
            "name": "Accept-Language",
            "type": "string",
            "in": "header",
            "description": "Determines in which language the content should be retrieved. Example - en-US"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/ExpandedContentApiModel"
              }
            }
          }
        }
      }
    },
    "/api/episerver/content/{referenceORguid}": {
      "get": {
        "tags": [
          "Content Api"
        ],
        "summary": "Retrieve content by content reference or content guid",
        "description": "",
        "operationId": "getContent",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "referenceORguid",
            "in": "path",
            "description": "Content Reference or Guid to be loaded. Supports all reference formats (including work and provider IDs)",
            "required": true,
            "type": "string"
          },
          {
            "name": "expand",
            "type": "string",
            "in": "query",
            "description": "Comma-separated list of reference properties (Content References, Content Areas) which should have their content fetched in the response. Passing \"*\" will load content in all reference properties in the return."
          },
          {
            "name": "Accept-Language",
            "type": "string",
            "in": "header",
            "description": "Determines in which language the content should be retrieved. Example - en-US"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "$ref": "#/definitions/ExpandedContentApiModel"
            }
          }
        }
      }
    },
    "/api/episerver/content/{reference}/children": {
      "get": {
        "tags": [
          "Content Api"
        ],
        "summary": "Retrieve child content of a content reference",
        "description": "",
        "operationId": "getChildren",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "description": "Content Reference for which to retrieve child content. Supports all reference formats (including work and provider IDs)",
            "required": true,
            "type": "string"
          },
          {
            "name": "expand",
            "type": "string",
            "in": "query",
            "description": "Comma-separated list of reference properties (Content References, Content Areas) which should have their content fetched in the response. Passing \"*\" will load content in all reference properties in the return."
          },
          {
            "name": "Accept-Language",
            "type": "string",
            "in": "header",
            "description": "Determines in which language the content should be retrieved. Example - en-US"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/ExpandedContentApiModel"
              }
            }
          }
        }
      }
    },
    "/api/episerver/content/{reference}/ancestors": {
      "get": {
        "tags": [
          "Content Api"
        ],
        "summary": "Retrieve ancestor content for a content reference",
        "description": "",
        "operationId": "getAncestors",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "description": "Content Reference for which to retrieve ancestor content. Supports all reference formats (including work and provider IDs)",
            "required": true,
            "type": "string"
          },
          {
            "name": "expand",
            "type": "string",
            "in": "query",
            "description": "Comma-separated list of reference properties (Content References, Content Areas) which should have their content fetched in the response. Passing \"*\" will load content in all reference properties in the return."
          },
          {
            "name": "Accept-Language",
            "type": "string",
            "in": "header",
            "description": "Determines in which language the content should be retrieved. Example - en-US"
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/ExpandedContentApiModel"
              }
            }
          }
        }
      }
    },
    "/api/episerver/site": {
      "get": {
        "tags": [
          "Site Definition Api"
        ],
        "summary": "Retrieve a list of sites in the system and their associated properties. By default, only the current site will be returned, unless the multi-site configuration flag is enabled in Configuration",
        "description": "",
        "operationId": "getSites",
        "consumes": [
          "application/json"
        ],
        "produces": [
          "application/json"
        ],
        "responses": {
          "200": {
            "description": "Success",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Site"
              }
            }
          }
        }
      }
    }
  },
  "definitions": {
    "ContentApiModel": {
      "type": "object",
      "properties": {
        "ContentLink": {
          "$ref": "#/definitions/ContentModelReference"
        },
        "Name": {
          "type": "string",
          "example": "Start Page"
        },
        "Language": {
          "$ref": "#/definitions/LanguageModel"
        },
        "ExistingLanguages": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/LanguageModel"
          }
        },
        "MasterLanguage": {
          "$ref": "#/definitions/LanguageModel"
        },
        "ContentType": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "example": [
            "Page",
            "StartPage"
          ]
        },
        "ParentLink": {
          "$ref": "#/definitions/ContentModelReference"
        },
        "RouteSegment": {
          "type": "string",
          "example": "content-page"
        },
        "Url": {
          "type": "string",
          "example": "http://episerver.local/content-page/"
        },
        "Changed": {
          "type": "string",
          "format": "date-time"
        },
        "Created": {
          "type": "string",
          "format": "date-time"
        },
        "StartPublish": {
          "type": "string",
          "format": "date-time"
        },
        "StopPublish": {
          "type": "string",
          "format": "date-time",
          "example": null
        },
        "Saved": {
          "type": "string",
          "format": "date-time"
        },
        "Status": {
          "type": "string",
          "example": "Published"
        },
        "Title": {
          "type": "object",
          "properties": {
            "Value": {
              "type": "string",
              "example": "This is the Hello World Page"
            },
            "PropertyDataType": {
              "type": "string",
              "example": "PropertyString"
            }
          }
        },
        "MainBody": {
          "type": "object",
          "properties": {
            "Value": {
              "type": "string",
              "example": "<p>Hello, World!"
            },
            "PropertyDataType": {
              "type": "string",
              "example": "PropertyXhtmlString"
            }
          }
        },
        "ReferencedContent": {
          "type": "object",
          "properties": {
            "Value": {
              "$ref": "#/definitions/ContentModelReference"
            },
            "PropertyDataType": {
              "type": "string",
              "example": "PropertyContentReference"
            }
          }
        }
      }
    },
    "ExpandedContentApiModel": {
      "allOf": [
        {
          "$ref": "#/definitions/ContentApiModel"
        },
        {
          "properties": {
            "ReferencedContent": {
              "type": "object",
              "properties": {
                "Value": {
                  "$ref": "#/definitions/ContentModelReference"
                },
                "ExpandedValue": {
                  "$ref": "#/definitions/ContentApiModel"
                },
                "PropertyDataType": {
                  "type": "string",
                  "example": "PropertyContentReference"
                }
              }
            }
          }
        }
      ]
    },
    "ContentModelReference": {
      "type": "object",
      "properties": {
        "Id": {
          "type": "integer",
          "format": "int32",
          "example": 234
        },
        "WorkId": {
          "type": "number",
          "format": "int32"
        },
        "Guid": {
          "type": "string",
          "format": "guid",
          "example": "2775f9ba-8a2b-46c8-b279-19764318cb48"
        },
        "ProviderName": {
          "type": "string",
          "format": "guid"
        }
      }
    },
    "SearchResponse": {
      "type": "object",
      "properties": {
        "TotalMatching": {
          "type": "number"
        },
        "Results": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/ExpandedContentApiModel"
          }
        }
      }
    },
    "Site": {
      "type": "object",
      "properties": {
        "Name": {
          "type": "string",
          "example": "Quicksilver"
        },
        "Id": {
          "type": "string",
          "format": "guid",
          "example": "2775f9ba-8a2b-46c8-b279-19764318cb48"
        },
        "ContentRoots": {
          "type": "object",
          "properties": {
            "ContentAssetsRoot": {
              "$ref": "#/definitions/ContentModelReference"
            },
            "GlobalAssetsRoot": {
              "$ref": "#/definitions/ContentModelReference"
            },
            "RootPage": {
              "$ref": "#/definitions/ContentModelReference"
            },
            "WasteBasket": {
              "$ref": "#/definitions/ContentModelReference"
            },
            "StartPage": {
              "$ref": "#/definitions/ContentModelReference"
            }
          }
        },
        "Languages": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/SiteDefinitionLanguageModel"
          }
        }
      }
    },
    "LanguageModel": {
      "type": "object",
      "properties": {
        "DisplayName": {
          "type": "string",
          "example": "English"
        },
        "Name": {
          "type": "string",
          "example": "en"
        }
      }
    },
    "SiteDefinitionLanguageModel": {
      "type": "object",
      "properties": {
        "DisplayName": {
          "type": "string",
          "example": "English"
        },
        "Name": {
          "type": "string",
          "example": "en"
        },
        "IsMasterLanguage": {
          "type": "boolean",
          "example": true
        }
      }
    }
  }
}
#197651
Oct 09, 2018 14:36
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.