Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at

  • Keith 74 posts 240 karma points
    Oct 14, 2021 @ 11:40

    API Controller slower than regular pages

    Hi All,

    Sorry if I am spamming the forum, but I have another issue that is causing me a lot of pain.

    When I use insomnia to query pages on my site, I get quite a fast response, as I would expect:

    enter image description here

    But take a look at this controller:

    enter image description here

    It doesn't do anything, query anything or create anything. It simply returns a response of OK to the client.

    But check this out:

    enter image description here

    I don't understand why it takes about 30 times longer to return a response from a custom API than a page on the site?

    Are there some middlewares that are doing things on these kinds of routes? If so is there a way I can turn them off or work around them? I have removed all of my own middlewares for this test, so it is not that.

    Many thanks

  • Keith 74 posts 240 karma points
    Oct 14, 2021 @ 11:51

    Ah.... ok wait.

    It if I take away the "Route" attribute and use "UmbracoApiController" instead:

    enter image description here

    I get much better performance:

    enter image description here


    Sorry for the spam. But instead of deleting the question, I'll leave it here in case anyone else has the same issue.

  • Keith 74 posts 240 karma points
    Oct 30, 2021 @ 22:06

    I have actually changed my mind on this.

    My solution above is not a solution. The documentation here states that you can use attribute routing:

    However, when I use it I get a MASSIVE degradation in performance.

    I would like to keep my API routes following a nice REST pattern, but I cant do that If I need all my routes to follow the pattern: ~/Umbraco/Api/[YourControllerName]/[YourActionName]

    Does anyone know a way around the issue described above?

    In summary, create an umbraco controller with a simple OK response and watch the timings when you hit it in a REST client. Then add a route attribute and hit it again.

    Locally here I am seeing the response times go from single digit milliseconds to hundreds of miliseconds.

    Any suggestions would be greatly appreciated.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Oct 31, 2021 @ 23:14

    Hi Keith,

    Just an observation, in your first code example you are inheriting from ControllerBase, in the second you are inheriting from UmbracoApiController. If you put the routing attribute on the second controller do you get the same slower response?



  • Keith 74 posts 240 karma points
    Oct 31, 2021 @ 23:25

    Hi Nik,

    Thanks for your response. Yes, unfortunately it is the attribute the causes the change in response time. The slower response time happens when you inherit from either controller, when you use the attribute.

    It seems to me that it is something like Umbraco performing all of its routing logic before the attributes are processed... but I have never looked at the source code for routing.

  • Thomas Rydeen Skyldahl 47 posts 229 karma points
    Nov 01, 2021 @ 12:45
    Thomas Rydeen Skyldahl

    Are you running in Debug or Release mode? .NET normally doesn't enable route caching when running in Debug so there can be a massive performance difference between the two.

  • Keith 74 posts 240 karma points
    Nov 02, 2021 @ 10:22

    Thanks Thomas,

    Ill try that suggestion and see if it helps!

  • Keith 74 posts 240 karma points
    Nov 02, 2021 @ 10:31

    No dice, unfortunately:

    With custom route attribute

    enter image description here

    Without custom route attribute enter image description here

    The controller: enter image description here

  • Thomas Rydeen Skyldahl 47 posts 229 karma points
    Nov 02, 2021 @ 10:40
    Thomas Rydeen Skyldahl

    Is that first request or after multiple?

  • Keith 74 posts 240 karma points
    Nov 02, 2021 @ 10:46

    After multiple. It starts longer, like 800ms, then goes down to about 200 to 250. I think I have found something though.

    I just turned on verbose logging in both scenarios.

    When there is no custom attribute, I see this in the logs:

    [10:42:28 VRB] Begin request [6daa40fc-f433-4238-a725-367e695d49a1]: /umbraco/api/articles/getarticles
    [10:42:28 VRB] End Request [6daa40fc-f433-4238-a725-367e695d49a1]: /umbraco/api/articles/getarticles (0.9288ms)

    But when I have a custom attribute, i see this:

    [10:37:14 VRB] Begin request [014d3d38-cf00-4b52-9aae-541194e611da]: /api/articles
    [10:37:14 VRB] Create 54fdff88 on thread 9
    [10:37:14 DBG] FindDomain: Uri=https://localhost:44376/api/articles
    [10:37:14 DBG] FindDomain: Matches no domain
    [10:37:14 DBG] FindDomain: Culture=en-US
    [10:37:14 DBG] FindPublishedContentAndTemplate: Path=/api/articles
    [10:37:14 DBG] FindPublishedContent: Begin finders [Timing d257252]
    [10:37:14 DBG] Finder Umbraco.Cms.Core.Routing.ContentFinderByPageIdQuery
    [10:37:14 DBG] Finder Umbraco.Cms.Core.Routing.ContentFinderByUrl
    [10:37:14 DBG] Test route /api/articles
    [10:37:14 DBG] No match.
    [10:37:14 DBG] Finder Umbraco.Cms.Core.Routing.ContentFinderByIdPath
    [10:37:14 DBG] Not a node id
    [10:37:14 DBG] Finder Umbraco.Cms.Core.Routing.ContentFinderByUrlAlias
    [10:37:14 DBG] Finder Umbraco.Cms.Core.Routing.ContentFinderByRedirectUrl
    [10:37:14 VRB] Create 5edc383e on thread 9
    [10:37:14 DBG] No match for route: /api/articles
    [10:37:14 DBG] Found? False, Content: NULL, Template: NULL, Domain: NULL, Culture: en-US, StatusCode: null
    [10:37:14 DBG] FindPublishedContent: End finders (268ms) [Timing d257252]
    [10:37:14 DBG] HandlePublishedContent: Loop 0
    [10:37:14 DBG] HandlePublishedContent: No document, try last chance lookup
    [10:37:14 DBG] Looking for a page to handle 404.
    [10:37:14 DBG] Got nothing.
    [10:37:14 DBG] HandlePublishedContent: Failed to find a document, give up
    [10:37:14 DBG] HandlePublishedContent: End
    [10:37:14 DBG] RewriteForPublishedContentAccessAsync: Loop 0
    [10:37:14 VRB] End Request [014d3d38-cf00-4b52-9aae-541194e611da]: /api/articles (269.3097ms)

    It looks like when it doesnt match an umbracoapi route, it goes and tries to find a matching content item before it does the attribute routing.

    This seems incorrect to me. I'd imagine if I have deliberately put a custom routing attribute on a controller, I would like that to be evaluated first.

  • Thomas Rydeen Skyldahl 47 posts 229 karma points
    Nov 02, 2021 @ 10:49
    Thomas Rydeen Skyldahl

    Try to exclude the endpoint via configuration:

    see: ReservedPaths

    you could add: "~/api/" to enclude all endpoints below /api/ from umbraco's routing Like this:

    "ReservedPaths": "~/app_plugins/,~/install/,~/mini-profiler-resources/,~/umbraco/,~/api/",
  • Keith 74 posts 240 karma points
    Nov 02, 2021 @ 11:22

    That's amazing thanks!

    Adding the path to the reserved routes gives me decent performance now!

    enter image description here

  • Markus Johansson 1909 posts 5733 karma points MVP c-trib
    Sep 08, 2022 @ 09:59
    Markus Johansson

    Hi Guys!

    Just wanted to say thank you and confirm that this issue is present in V10 as well. When ReservedPaths is not set all IContentFinder's will be triggered (and probably other stuff) hence the extra time for the response.

    In V10 (and probably 9) it looks like this:

    "Umbraco": {
      "CMS": {
          "Global": {
            "ReservedPaths": "~/api"
Please Sign in or register to post replies

Write your reply to: