asyncapi / saunter

Saunter is a code-first AsyncAPI documentation generator for dotnet.
https://www.asyncapi.com/
MIT License
199 stars 56 forks source link

Extract serialization from Middleware into Serializer object #89

Closed neoaisac closed 3 years ago

neoaisac commented 3 years ago

Currently the building of the document model is separated from the middleware, and rightfully so. In this way, a third-party application (not necessarily an ASP.NET application) can build the document model independently, either by creating items or by scanning assemblies.

However, the serialization parameters are still in-coded inside the Middleware, meaning that the only way to get a valid JSON output with Saunter is either inside an ASP.NET application using this middleware, or re-implementing the same lines of code elsewhere in a custom tooling.

Extracting the following lines of code into its own AsyncApiDocumentSerializer enables developers that do not wish to use the Middleware on a particular workflow (or cannot because their application is not based on ASP.NET's pipeline) to still generate documentation and serialize it in a pre-configured validatable form. Moreover it enables the ability to plug in multiple different serialization methods (e.g. YamlAsyncApiDocumentSerializer or TextJsonAsyncApiDocumentSerializer).

https://github.com/tehmantra/saunter/blob/07f310f43caba862ad638b09fc071198186bcd77/src/Saunter/AsyncApiMiddleware.cs#L38-L50

bbattah commented 3 years ago

Agreed. I have just begun playing with Saunter and ran into the same challenge.

Ideally I would like to easily include a "Swashbuckle" style endpoint with an HTML UI. However, in the mean-time I can settle for generating a static html file I can commit with the application source.

En-route to this I am writing test code that uses Saunter to scan a specific assembly for relevant message formats and plug them into a "Skeleton" AsyncApiDocument. Then the json\yaml must be serialized in order to feed the standard generator with html template.

I had to lift exactly the same code as above into my own project to get this close to working.
Additionally, the serialization needs to ensure proper lower-casing of the serialized asyncapi.json document AND ensure that the asyncapi attribute is tagged with a proper version value. Relevant code snippets here:

private static void ConvertToHtml(AsyncApiDocument doc)
        {
            string json = AsyncApiDocToString(doc);

            File.WriteAllText("asyncapi.json", json);

            using (Process compiler = new Process())
            {
                compiler.StartInfo.FileName = "ag";
                compiler.StartInfo.Arguments = $" asyncapi.json @asyncapi/html-template -o output --force-write --param singleFile=true";
                compiler.StartInfo.UseShellExecute = true;
                compiler.StartInfo.RedirectStandardOutput = false;
                compiler.Start();
                compiler.WaitForExit();
            }
        }

        private static string AsyncApiDocToString(AsyncApiDocument doc)
        {
            string docString = JsonSerializer.Serialize(
                doc,
                new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    WriteIndented = true,
                    IgnoreNullValues = true,
                    Converters =
                    {
                        new DictionaryKeyToStringConverter(),
                        new InterfaceImplementationConverter(),
                    },
                }
            );

            return docString.Replace("\"asyncApi\": 0,", "\"asyncapi\": \"2.0.0\",");
        }

Please consider this an "up-vote" for the suggested solution and related issues.