microsoft/GraphEngine

[Feature Request] Ability to return a TSL service API definition as a Swagger.json file

mwherman2000 opened this issue · 2 comments

The changes would need to take place somewhere near this method in the code-generated HTTP.cs file...

        public static void ListAvailableEndpoints(HttpListenerContext ctx, IEnumerable<string> availableEndpointNames, Type serverType)
        {
            string text = ctx.Request.Url.GetLeftPart(UriPartial.Authority);
            if (typeof(CommunicationModule).IsAssignableFrom(serverType))
            {
                int num = ctx.Request.RawUrl.IndexOf('/', 1);
                if (num >= 0)
                {
                    string str = ctx.Request.RawUrl.Substring(1, num - 1);
                    text = text + "/" + str;
                }
            }

            string text2 = Serializer.ToString(GenerateDefaultHttpHandlerResponseObject(text, availableEndpointNames, serverType));
            using (StreamWriter streamWriter = new StreamWriter(ctx.Response.OutputStream))
            {
                if (ctx.Request.AcceptTypes != null && !ctx.Request.AcceptTypes.Contains("application/json"))
                {
                    ctx.Response.ContentType = "text/html";
                    using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Trinity.Network.Http.index.html"))
                    {
                        using (StreamReader streamReader = new StreamReader(stream))
                        {
                            string text3 = streamReader.ReadToEnd();
                            streamWriter.WriteLine(text3.Replace("//%AVAILABLE_ENDPOINTS%", "var available_endpoints = " + text2 + ";"));
                        }
                    }
                }
                else
                {
                    ctx.Response.ContentType = "application/json";
                    streamWriter.WriteLine(text2);
                }
            }
        }

...and/or where this method is called in the same HTTP.cs file...

        /// <summary>
        /// Processes requests on the root endpoint. By default it
        /// will list available API endpoints in html.
        /// Override this method to get custom behaviors.
        /// </summary>
        /// <param name="ctx">A <see cref="HttpListenerContext"/> object.</param>
        protected override void RootHttpHandler(HttpListenerContext ctx)
        {
            CommonHttpHandlers.ListAvailableEndpoints(ctx, s_HttpHandlerLookupTable.Keys, this.GetType());
        }

It turns out that

  1. the above RootHttpHandler() is overridable in the implementation class for your GE server, and
  2. it's actually the generic HTTP handler method that is called for every URL that you haven't defined a protocol REST endpoint for.

The implication is that by overriding RootHttpHandler(), your GE server can support any custom URLs you need (e.g. http://localhost:8081/v2/swagger.json). Here's the skeleton code you need in your GE server implementation class:

        protected override void RootHttpHandler(HttpListenerContext ctx)
        {
            Debug.WriteLine("RootHttpHandler <<<<");
            if (ctx.Request.RawUrl.ToLower() == "/v2/swagger.json")
            {
                using (StreamWriter streamWriter = new StreamWriter(ctx.Response.OutputStream))
                {
                    streamWriter.WriteLine("<html><body><h3>TODO: Generate Swagger API Definition</h3></body></html>");
                }
                ctx.Response.StatusCode = 200;
            }
            else
            {
                base.RootHttpHandler(ctx);
            }
        }

Will update this as I make progress on the actual Swagger implementation.