Developer forum

Forum » Development » Dynamicweb API adding Custom Api to Swagger list

Dynamicweb API adding Custom Api to Swagger list

Shiwanka Chathuranga Dynamicweb Employee
Shiwanka Chathuranga
Reply

i want to add my custom api to the yourwebsite.com/dwapi/docs   swagger doc

Done the ApiRegistrationBase

api is working fine with /dwapi/brand/.....

let me know what i missed

Thanks

 

 


Replies

 
Nicolai Pedersen
Reply

I do not think you should tap into dwapi - or that if it is even possible. You could do something with another endpoint name.

We register Swagger like below. As you can see it uses the assembly that contains our controllers to the UI discovery. OwinStartup is inside the Dynamicweb.Ecommerce.WebAPI dll.

jsonSettings.Converters.Add(new StringEnumConverter());
            builder.Map(new PathString("/dwapi"), app =>
            {
                app.UseStaticFiles();
                app.UseSwaggerUi3(typeof(OwinStartup).Assembly, settings =>
                {
                    settings.MiddlewareBasePath = "/dwapi";
                    // path to docs (ui)
                    settings.Path = "/dwapi/docs";
                    // set the path of the genereated spec file
                    settings.DocumentPath = "/dwapi/api.json";
                    // set default url template used for web api
                    settings.GeneratorSettings.DefaultUrlTemplate = "dwapi/{controller}/{action}/{id}";
                    // Make sure that we generate openapi 3.0 specs instead of old swagger specs
                    settings.GeneratorSettings.SchemaType = NJsonSchema.SchemaType.OpenApi3;
                    // Title for generated spec (displayed as title in ui)
                    settings.GeneratorSettings.Title = "Dynamicweb API";
                    // Description for generated spec (displayed as description in ui)
                    settings.GeneratorSettings.Description = "Let's build something great!";
                    // Set API version
                    settings.GeneratorSettings.Version = GetApiVersion();
                    //sets the page title
                    settings.DocumentTitle = "Dynamicweb 9 WebApi Documentation";
                    //customization of the document after processing
                    settings.PostProcess = document =>
                    {
                        // clear servers to hide servers dropdown in ui
                        document.Servers.Clear();
                    };
                    settings.GeneratorSettings.SerializerSettings = jsonSettings;
                    settings.CustomJavaScriptPath = "/admin/NSwagSetup.js";
                });
            });
            GlobalConfiguration.Configure(config =>
            {
                config.Formatters.JsonFormatter.SerializerSettings = jsonSettings;
            });

You should probably do 2 things - create your own endpoint location and ensure that URL handling does not interfer with the url.

Make a notification subscriber that listens to AuthenticateRequest notification and on the AuthenticateRequestArgs object set handled=True if that is your endpoint:

args.Handled = request.Path.StartsWith("/dwapiCustom/")

Attached find our version of the api as of today (you cannot probably not compile it as it depends on some very cutting edge DW things that is not published yet). Look into the OwinStrartup.cs for registration of the endpoints to swagger - try to modify it to your own endpoint. The rest of the code you can probably delete.

BR Nicolai

 
Shiwanka Chathuranga Dynamicweb Employee
Shiwanka Chathuranga
Reply

hey, thanks Nicolai

i will try and update you

 
Daniel Hollmann
Reply

Hi Nicolai

I also found this topic about a custom webapi: https://doc.dynamicweb.com/forum/development/development/making-a-custom-web-api-with-dynamicweb

It's seems like a nice way to implement a custom web api, but I strugle to get the Http context from the  AuthenticateRequestArgs   in 9.10.9

The context does not seems to be part of the Application interface anymore: https://doc.dynamicweb.com/api/html/76047f82-1638-f5a6-a575-4d2e8a2db61f.htm

How do I get the context, so I can read the URL?

 
Nicolai Pedersen
Reply

No - it had to be removed because it was httpcontext which we are getting rid of.

But try System.Web.HttpContext.Current

 
Daniel Hollmann
Reply

Thanks Nicolai, that worked :) 

 
Nicolai Pedersen
Reply

Great.

If you have some working code, please post it for others to use if you do not mind.

Thanks!

 
Daniel Hollmann
Reply
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dynamicweb.Extensibility.Notifications;

namespace Backend
{
	[Subscribe(Dynamicweb.Notifications.Standard.Application.AuthenticateRequest)]
	public class APIEntry : NotificationSubscriber
	{

		internal const string RoutePrefix = "myapi";
		private const bool EnableSessionState = true;

		public override void OnNotify(string notification, NotificationArgs args)
		{
			var authenticateArgs = args as Dynamicweb.Notifications.Standard.Application.AuthenticateRequestArgs;
			var request = System.Web.HttpContext.Current.Request;
			var isHandled = request.Path.StartsWith($"/{RoutePrefix}");
			if (EnableSessionState && isHandled)
			{
				//Enable session
				System.Web.HttpContext.Current.SetSessionStateBehavior(System.Web.SessionState.SessionStateBehavior.Required);
				// When this is set to true then Dynamicweb will skip the default handling of the current request
				authenticateArgs.Handled = isHandled;
			}

		}
	}
}

This is my Entry Class. And this is my Controller class:

 

 

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http;

namespace Backend
{
	[RoutePrefix(APIEntry.RoutePrefix + "/page")]
	public class MyAreaDataApiController : ApiController
	{
		[Route("create")]
		public IHttpActionResult GetList()
		{
			// TODO: Add custom logic
			var list = new string[] {"Returning JSON!" };
			return Json(list);
		}
	}
}
 
Nicolai Pedersen
Reply

Great. Thanks for sharing.

Can I ask the reason for enabling sessions?

 
Daniel Hollmann
Reply

I took a bit from this post: 

https://doc.dynamicweb.com/forum/development/development/making-a-custom-web-api-with-dynamicweb

Maybe there is no need to.

 
Daniel Hollmann
Reply

I took a bit from this post: 

https://doc.dynamicweb.com/forum/development/development/making-a-custom-web-api-with-dynamicweb

Maybe there is no need to.

 
Nicolai Pedersen
Reply

Hi Daniel

Yes - remove it to begin with, and then add it if needed. It gives you a slight performance overhead that you do not want if you can avoid it.

If it is enabled, your controller code will share sesssion with the website - i.e. Dynamicweb.Ecommerce.Common.Context.Cart is available in the endpoint.

Usually webapi endpoints should be stateless - not requiring any states. So instead of using i.e. context.cart, you would send in the cartid/secret as a parameter to the endpoint and use that instead. Or whatever kind of logic you have that could require state information.

BR Nicolai

 

You must be logged in to post in the forum