The Secret HttpClient Feature You Need To Use in .NET

Sdílet
Vložit
  • čas přidán 12. 06. 2024
  • Use code DDD20 and get 20% off the brand new Domain-Driven Design course on Dometrain: dometrain.com/course/getting-...
    Become a Patreon and get source code access: / nickchapsas
    Hello, everybody, I'm Nick, and in this video, I will show you how you can use one of the most underrated features of the HttpClient in .NET, called the DelegatingHandler.
    Subscribe to Amichai: @amantinband
    Workshops: bit.ly/nickworkshops
    Don't forget to comment, like and subscribe :)
    Social Media:
    Follow me on GitHub: bit.ly/ChapsasGitHub
    Follow me on Twitter: bit.ly/ChapsasTwitter
    Connect on LinkedIn: bit.ly/ChapsasLinkedIn
    Keep coding merch: keepcoding.shop
    #csharp #dotnet

Komentáře • 150

  • @nickchapsas
    @nickchapsas  Před 9 měsíci +284

    I accidentally cut the part where I show the HttpClient and DelegatingHandler association! To associate the handler to the client all you need to do is chain an AddHttpMessageHandler call to the AddHttpClient call like this: builder.Services.AddHttpClient("weather").AddHttpMessageHandler();

    • @seantech5358
      @seantech5358 Před 9 měsíci +14

      Sweet! That makes more sense. Looks sweet too! 😁

    • @TonyBastonHall
      @TonyBastonHall Před 9 měsíci +12

      Thanks! I thought I'd blinked and missed it!

    • @alexclark6777
      @alexclark6777 Před 9 měsíci +13

      I was about to replay the video on 0.75x speed to see where I'd missed it, so I'm glad I read the comments first haha.

    • @baetz2
      @baetz2 Před 9 měsíci +6

      That's the most interesting part

    • @gordug
      @gordug Před 9 měsíci

      You would think they could register the handler when you map it to the client 😢

  • @ElOroDelTigre
    @ElOroDelTigre Před 9 měsíci +73

    If the user requests the weather for London you can just return a constant response "The weather is crap" and no need to cache.

    • @Sanabalis
      @Sanabalis Před 9 měsíci +3

      That's what the real services do anyway.

  • @doublebass120
    @doublebass120 Před 9 měsíci +42

    For me, I used this to check if I had a bearer token cached for a 3rd party API. If it was cached and not expired, set the authorization header. Otherwise, authenticate with the API and then add the header.

    • @Punkologist
      @Punkologist Před 9 měsíci +2

      yep this is exactly what we use it for

    • @Workshopshed
      @Workshopshed Před 9 měsíci +1

      Same here. Checking a token for expiry and call refresh endpoint if expired

    • @yazidarezki3757
      @yazidarezki3757 Před 6 měsíci

      I do the same with tokens, I have scenario where I am using the _httpClientFactory.CreateClient("MyService") and then I add the Authorization token to the header and If two separate threads are calling _httpClientFactory.CreateClient("MyService") and the fact it will return the same instance. There could issues with this!. To overcome the problem I am using SemaphoreSlim(1,1). My question do I need to make use of SemaphoreSlim.? Thanks

  • @sentenza5497
    @sentenza5497 Před 9 měsíci +12

    I use those handlers for example to put the bearer token on the Authorization header of the request. A provider injected into the handler takes care of the caching and refreshing process of the token.

  • @askids
    @askids Před 9 měsíci +12

    If you are using service repository pattern, you would typically do this kind of caching at the service level. That way, if your underlying API provider changes, format changes OR you have a backup API provider for weather, caching still happens at the service level. Caching it at the httpclient's message handler level does not look like an optimal choice for caching. We use message handlers all the time, for injecting tracking headers, missing authorization headers, add client certificates etc. Those are your typical use cases of using custom message handlers.

    • @sentenza5497
      @sentenza5497 Před 9 měsíci +1

      I feel the same. But if you want to throttle due to the licensing model of the underlying api, it seems legit to me. Nothing domain specific at this point.

    • @okmarshall
      @okmarshall Před 9 měsíci +1

      @@sentenza5497this is the important point for me, the reason for caching. In this case it's because of cost per request so it makes sense to do a quick caching implementation at the level that's going to hurt.
      As the app grows I'd agree with caching at a higher level, but maybe not as a first pass where you want to get the MVP working and you don't want to hammer the API during dev testing.

  • @rogeriobarretto
    @rogeriobarretto Před 9 měsíci +9

    Very useful content. Being dealing with DelegateHandlers lately and they are very flexible.
    This is a neat approach most notably to Mock you responses for UnitTesting.
    Delegating the Caching strategy to the Client seems to be a nice example like you said with minimum code base changes. The beauty of this is that it also helps any fallback logic that relies in your API response error avoiding going to other API if the current API is down or throttled

  • @emerynoel567
    @emerynoel567 Před 9 měsíci +4

    I did actually know about it! I used it to create a "mock" for use on certain environments, to prevent actually making http calls to any kind of 3rd party api. Very useful for testing and "mirror" environments!

  • @ThomasHaxley
    @ThomasHaxley Před 9 měsíci +2

    I've used this in the past to manage rate limits on API's. One we used only allowed a request every 1 second. So I used a delegate handler to check when the previous request was sent and wait on the next one if required. Worked perfectly.

  • @SvdSinner
    @SvdSinner Před 9 měsíci +14

    I have to say your timing on this is so perfect for me. I was literally sitting down to start working through how I was going to improve performance on several API calls using caching when I saw this!

  • @kennethswan7853
    @kennethswan7853 Před 9 měsíci +3

    I’ve used this a ton for getting an auth token (or using a cached/unexpired token) to append to the request authorization header before sending

  • @Lammot
    @Lammot Před 9 měsíci +5

    The feature itself is useful, but generally, for a more simple shared concerns: logging, header injection, stuff like that. Not caching.
    As you've shown, generally you want to cache only successful responses. This and having cache in the handler forces you to:
    - duplicate response validation logic inside the handler and will need to recreate the response with enough information, which is a bloat.
    - wrapping the cached payload in pointless objects which increases the bloat.
    - if you want to cache only certain endpoints, you'll need to add branching logic in that handler. Bloat.
    - won't be able to add typed caching, since it'll force you to add add an extra serialization-deserialision step (to and from content) which is, again, an overhead.
    tldr: better to add cache before the client, for example, as a decorator to a service that handles calling an API.

  • @RickMcDee
    @RickMcDee Před 9 měsíci +13

    Maybe I missed something, but since you registered the CachedWeatherHandler with the default DI method, does this mean it is used by all HttpClients in this project?
    Also, if I register multiple handlers, are they used in the same order as I registered them in the Program.cs?

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +1

      Since the only thing that will instantiate the handlers is the NAMED http client, specific to the weather, it will only be used by the weather client. Regarding handlers, order matters in how they are added to the client, not registered in DI.

    • @krzysztofmilewski9516
      @krzysztofmilewski9516 Před 9 měsíci

      You can also explicity configure which handlers are used with which clients when registering clients in the DI. Not sure about named clients, but it works for typed clients.

    • @RickMcDee
      @RickMcDee Před 9 měsíci

      @@nickchapsas Thank you, your pinned comment explained the part that confused me.

  • @Punkologist
    @Punkologist Před 9 měsíci

    This is how I get and add the access token to the requests when using an nswag generated client, but I hadn't thought of doing other stuff with it. Never thought of caching at the webclient level. Great video.

  • @Fred-yq3fs
    @Fred-yq3fs Před 9 měsíci +9

    The components of the key might depend on the end-point, so the handler is not quite the right place for the extraction of the components of the caching key. I prefer to use a typed IClient and decorate it. I use delegating handlers for concerns which don't depend on the end-point, such as header manipulations (as you said at the end)

    • @kipsate
      @kipsate Před 9 měsíci +3

      this pretty much, def not the place for caching

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +2

      The handler is only used by that specific endpoint so there is no problem with the implementation at all. Nothing else can instantiate it and no other endpoint can be used

  • @malcolmchambers4934
    @malcolmchambers4934 Před 9 měsíci

    I can see this as being useful for a wide range of testing needs

  • @javiergarciadelanoceda7708
    @javiergarciadelanoceda7708 Před 9 měsíci +4

    I use it with Refit passing an object that represents the amount of time for each request. Also for body content with a simple interface you could cache it by sending the body as a Option in the HttpRequest

    • @ShahidKhan-vs8bb
      @ShahidKhan-vs8bb Před 9 měsíci

      I am using refit in a project that i am starting. Could you please share your solution?

    • @javiergarciadelanoceda7708
      @javiergarciadelanoceda7708 Před 9 měsíci

      @@ShahidKhan-vs8bb I do not have it right here. What I did was that all the request which has a body and I wanted to cache I put the [Body, Property] attributes, and named all the objects body. Example Task GetResponse([Body, Property] Request body, [Property] int cacheTime). The Request object inherits from an interface that has a Method string GetKey().
      With the URL+RequestObject you form the key and with the cacheTime you form the ExpirationTime.
      In the HttpRequest object you can access to both variables ( They are both in the Properties, which is deprecated, and in the Options)

  • @evobenim
    @evobenim Před 9 měsíci +2

    You didn't check api call is success before adding it to cache. I mostly use messagehandlers for logging, security and injecting parameters into the request if it is needed.

  • @W1ese1
    @W1ese1 Před 9 měsíci +5

    That means that the handler is registered for every HttpClient that will be created so we actually would need a check for the uri so that it's only executed when necessary. At least in your current implementation.
    I guess it would have been good to also showcase the ability to register a handler for a specific HttpClient so that this uri check is not necessary.

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +1

      That's not correct. The HttpClient is named so only the weather httpclient will have this ability. The handler won't exist for other clients

    • @332glenn
      @332glenn Před 9 měsíci +11

      @@nickchapsas You register the handler to the application, not directly to the named HttpClient. How does it know that it should only be attached to the named Weather HttpClient.

    • @332glenn
      @332glenn Před 9 měsíci

      Hmm my last message might've been removed as I added a link to the Microsoft docs,
      You can use the following to add a handler to a specific HttpClient
      builder.Services.AddTransient();
      builder.Services.AddHttpClient("HttpMessageHandler")
      .AddHttpMessageHandler();

    • @PankajNikam
      @PankajNikam Před 9 měsíci

      +1@@332glenn

    • @seantech5358
      @seantech5358 Před 9 měsíci

      @@nickchapsas @332glenn and @W1ese1 are right. You do not register the handles specifically for the named instance. Or not that we can spot anyway!

  • @luisbernalcespedes
    @luisbernalcespedes Před 9 měsíci

    Thank you Nick for sharing the usage of DelegatingHandlers with this particular example. IMHO and in this particular usage, I want to share another approach that I have used before: for caching purposes, I have used a typed HttpClient (instead of a named one) for the API I'm consuming, so that the lookup and write into the cache are both done in such typed client instead - I presume I could have used a HttpClient decorator as well, just like cached repositories are usually implemented. In that way we wouldn't be required to parse the query string or build the HttpMessageResponse and only use any of the corresponding DTO classes instead.

  • @user-cj3hw1bf5o
    @user-cj3hw1bf5o Před 9 měsíci

    I’ve used this a lot for mocking out requests in unit tests. Helpful if you are calling a third party api and just want to check success or specific errors

  • @leonardomoreno23
    @leonardomoreno23 Před 9 měsíci

    This handler was extremely helpful for me to implement Auth elegantly before to call an API.

  • @athanasmb
    @athanasmb Před 9 měsíci

    thanks Nick!

  • @IvanAndreev91
    @IvanAndreev91 Před 9 měsíci

    thanks for video! I enjoed with it!

  • @krzysztofmilewski9516
    @krzysztofmilewski9516 Před 9 měsíci +5

    I've been using this feature for a while now, a very elegant way to manage HTTP requests without bloating your logic with repeating code. I just have one questuion - can you elaborate on why did you register your handler with a scoped lifetime? Examples in MS documentation use transient scope with the following explanation:
    "When IHttpClientFactory creates a new delegating handler, it uses DI to fulfill the handler's constructor parameters. IHttpClientFactory creates a separate DI scope for each handler, which can lead to surprising behavior when a handler consumes a scoped service."

    • @Mig440
      @Mig440 Před 9 měsíci

      If you read the documentation carefully it talks about the using a scoped service inside the handler not the scope of the handler itself 😊

    • @ShawnHepworth
      @ShawnHepworth Před 9 měsíci

      You must register the handler as transient. It should be registered as transient primarily because it is not thread-safe. If it were registered as scoped, the same instance could be reused across multiple HTTP requests within the same scope, which could lead to unintended side effects, race conditions, or other threading issues.

  • @chrisvandewouw
    @chrisvandewouw Před 9 měsíci

    Very interesting indeed. I'm at the start of a project for implementing a kind of proxy/anti-corruption layer providing a well-structured api and with dependencies to several other webapplications. Preferable I would like to have these webapplications available in a container so I can write integration tests as we do for code that only requires a database, but that is not the case. Using this feature is as close as the next best thing I can imagine. It's basically the same as regular mocking.

  • @KillerMindawg
    @KillerMindawg Před 9 měsíci

    I use it for http logging.
    I've also used it for load testing where you want to load test services in isolation mode. It can help simulate latencies from different services very easily.

  • @paul99782
    @paul99782 Před 9 měsíci +2

    Hey Nick! Love your content, especially about Web API. I was wondering if you'd ever do videos on authentication between clients and .Net 6+ Web API? Specifically, authentication using a token rather than using user credentials. I find that most of the apps I see created internally for businesses don't warrant the use of full-fledged user credential authentication. Didn't know if you had suggestions for this route or even videos out/in the pipeline?

    • @vacc1001
      @vacc1001 Před 9 měsíci

      I just created a bare bones JWT token generator and verification library that's shared between projects. Barely a handful number of simple methods. Has been running smoothly for 5 years and counting. Might want to go down that route.

  • @MrIsrael3000
    @MrIsrael3000 Před 9 měsíci +3

    Nice, I’m surprised Polly don’t include client caching, two points I believe could improve the solution:
    - implementation as a generic cache handler, means not specific to this controller.
    - having an status code or out header that indicates the result is from cache for troubleshooting.
    - having a header the cache handler read to avoid the cache.
    What do you think?

    • @aluced
      @aluced Před 9 měsíci

      A generic cache handler might be tricky to pull off because of the cache key unicity which holds some business logic

    • @Workshopshed
      @Workshopshed Před 9 měsíci

      Polly can do caching, supports in memory, distributed or redis

  • @MatthewCrawford
    @MatthewCrawford Před 9 měsíci

    I keep an extension class on hand for that, generic lazy loading cache helper (AddOrGetExistingCacheEntry) to use as localized cache for several internal processes.
    Have they added something like that to the basic system memorycache?

  • @KasperDahlTangen
    @KasperDahlTangen Před 9 měsíci

    Works nice for ratelimiting as well

  • @kevinlloyd9507
    @kevinlloyd9507 Před 9 měsíci

    I've used this with Polly for retries on http calls. But I think, since then there's probably something that does this automatically.
    Also for global exception handling. I do custom parsing of the response, then throw an application exception that my app can handle.

  • @RamonDeKlein
    @RamonDeKlein Před 9 měsíci +1

    It’s also very useful to inject a handler that stubs responses for testing. Implement your own caching is typically a bad idea (especially with HTTP). You should properly deal with caching headers and that’s not trivial. Please use a solid existing caching handler instead of wrapping your own.

  • @jackp3303
    @jackp3303 Před 9 měsíci +1

    May I ask one thing - what's are advantages of this way of caching in comparison with standard (let's say use some service with the same InMemoryCache)?
    For me HttpClient should do 1 thing - send requests and receive response, that's it's responsibility and it doing it well, but changing it's pipeline, adding some caching possible may produce some "hard to debug" \ "understand the code" issues, especially for beginners.
    I also don't see any perf advantages, similar thing.
    + More difficult configuration - so if we have many APIs in our microservice, each service need specific configuration of HttpClient. Having specific MyServiceNameCache service, injecting it into MyServiceName and just before the call of httpClient check the cache is much easy to read and debug.
    Or I lost the idea?

  • @br3nto
    @br3nto Před 9 měsíci

    5:56 using underscores for fields is like using capitalisation for public/private

  • @KirillKrylovTo
    @KirillKrylovTo Před 9 měsíci

    This is my default way to
    - mock external responses,
    - add auth token and trigger refresh

  • @Meir017
    @Meir017 Před 7 měsíci

    Isn't there an issue where you can read the response.Content only once or does that happen only if you wrap the content in a using block?

  • @neralem
    @neralem Před 8 měsíci

    I think for london you can statically return "Rainy".

  • @joelhodes1619
    @joelhodes1619 Před 9 měsíci +1

    I remember I used this ages ago to inject custom headers to pretend I was behind a reverse proxy and so the server would authenticate me. I’m sure there are utilities out there now that will do the same without any scripting. Maybe fiddler.

  • @sospam3417
    @sospam3417 Před 9 měsíci

    Mentioning ValueTask when using a cache would have been nice. Otherwise great video!

  • @adityadesai7263
    @adityadesai7263 Před 2 měsíci

    every time I make a HTTPS post call with httpclient class, Httpclient response is very slow. any way to speed it up. Mean while post request to http is fast, its https that is causing issue

  • @teisdraiby9386
    @teisdraiby9386 Před 9 měsíci

    Is there any way the handle could pass custom information to the caller? For example whether the response comes from cache or the the actual api?

    • @krb3d
      @krb3d Před 9 měsíci

      Just add custom header for cached cases or something like this - you are in full control there.

  • @majidmajid2192
    @majidmajid2192 Před 9 měsíci

    Why we need to use this methods and classes and not cache in our service layer?

  • @hakienet3897
    @hakienet3897 Před 9 měsíci +1

    Why would you make a custom handler instead of just caching the response from the api?

    • @jamesreynolds3167
      @jamesreynolds3167 Před 9 měsíci

      Maybe you might have 2 different sets of business logic that do different things, but still depend on the same api.

    • @nickchapsas
      @nickchapsas  Před 9 měsíci

      What James said. Because it's a differnet layer of caching specific to the single API. You might not want that for the complete API response especially for things like auth

  • @Autystyczny
    @Autystyczny Před 9 měsíci +1

    Isn't this an overengineering? You can add caching to the method that make the call to the API and that does the same thing without adding extra layer of classes

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +8

      Does that class need to know about the caching? I would argue it doesn't. Same with something like adding retry policies or fallbacks. It's not the responsibility of that class to know that IMO but it heavily depends on context as well

    • @marcusvmgg
      @marcusvmgg Před 9 měsíci

      great point. That's the usual implementation we do, usually we create a class responsible for dealing with weather data (CacheWeather), and that class would be the one with the logic for caching or httping it and later return to the service class

    • @JerryFederspiel
      @JerryFederspiel Před 9 měsíci

      I can't help but feel like all of this could've been made simpler if some of the types related to HttpClient used interfaces so we could transparently decorate them with caches/retries if we wanted to.

  • @Paps526
    @Paps526 Před 9 měsíci +2

    I think you missed the part where you should wrap your handler over defaultHttpHandler of HttpClient

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +1

      There is no wrapping. I accidentally cut the registration part. Check the pinned comment

    • @Paps526
      @Paps526 Před 9 měsíci

      @@nickchapsas Yea that's right, but in a nutshell it's like wrapping, your handler wraps around inner one

  • @terjes64
    @terjes64 Před 9 měsíci

    If this vid came out one week earlier I would implement this, and not make a manual cache... Oh well there is always next time..

  • @DanielAWhite27
    @DanielAWhite27 Před 9 měsíci

    I did the same thing for bearer token management.

  • @jeremybray8050
    @jeremybray8050 Před 9 měsíci +1

    Not sure if its a big deal to you but you showed your API Key at 2:10.

    • @maskettaman1488
      @maskettaman1488 Před 9 měsíci +1

      If the past is any indicator, that API key will be deactivated before the video goes live

  • @DaminGamerMC
    @DaminGamerMC Před 9 měsíci

    Do the courses give certificates?

  • @ttolst
    @ttolst Před 9 měsíci

    I really wish we would stop adding so much hidden indirection, making reading and debugging the code much harder than it need to be.
    In so many places, proper seperation of logic and IO will make things like DI and mocs not needed, but if i could choose to kill just one thing, it would be automapper - the destroyer of code navigation and turning compile errors into runtime errors.

  • @timmkrause6684
    @timmkrause6684 Před 9 měsíci

    Anyone knows the screen magnyfier Amichai is using?

    • @birolaydin4731
      @birolaydin4731 Před 9 měsíci

      ZoomIt

    • @timmkrause6684
      @timmkrause6684 Před 9 měsíci

      @@birolaydin4731 ZoomIt does not support these rainbow colors. He‘s using macOS with Presentify in that case.

  • @ShawnHepworth
    @ShawnHepworth Před 9 měsíci

    The delegating handler has to be registered as transient. Not scoped. Look into it a bit more. It should be registered as transient primarily because it is not thread-safe. If it were registered as scoped, the same instance could be reused across multiple HTTP requests within the same scope, which could lead to unintended side effects, race conditions, or other threading issues.

    • @BlTemplar
      @BlTemplar Před 9 měsíci

      It can be registered as a singleton if the code you put in it is thread-safe.

    • @nickchapsas
      @nickchapsas  Před 9 měsíci

      Transient is the general recommendation by Microsoft because it’s the safest option but it’s not a "has to" thing. In this case for example there will be no scenario where scoped causes unexpected behaviour

  • @parlor3115
    @parlor3115 Před 9 měsíci

    Caching should be done at the service level not the http client level. Like this, you're caching any request (weather API or not) plus other issues too.

    • @nickchapsas
      @nickchapsas  Před 9 měsíci

      No you’re not. This handler is only used by the weather api and only caches for the weather api

    • @parlor3115
      @parlor3115 Před 9 měsíci

      @@nickchapsas You're right. I missed the named client part, but still, you don't control what the handler caches unless you write code that checks the content of the request and it can even run on non GET requests.

    • @skwas6012
      @skwas6012 Před 9 měsíci

      @@parlor3115 I agree with you. Caching of HTTP content should be based on HTTP cache control, etag, last modified and so on. This is what could be handled at the HTTP client side in a DelegatingHandler (or a reverse proxy cache). If an upstream service however does not provide HTTP level caching, and/or you do not have a reverse proxy cache, by all means introduce cache in your application if you need to have this data frequently, but keep it in the domain/service using a service decorator pattern or something alike.

  • @margosdesarian
    @margosdesarian Před 9 měsíci

    Ha ha ha ha ha ... "In London, a lot" ..

  • @mwzndev
    @mwzndev Před 8 měsíci

    That's Refit, with extra steps and less features.

  • @angrycoder
    @angrycoder Před 9 měsíci

    Or you can just create an extension method so that future developers don't have to go through all the documentation to understand this hidden functionality. xD Nice video tho!

  • @nataliasikorka4825
    @nataliasikorka4825 Před 9 měsíci

    Just a friendly reminder that IMemoryCache is not thread safe, and could be choke point if impelemted the way Nick showed in this video.
    Nick has even video about that 😄:
    czcams.com/video/Q3KzZeUudsg/video.htmlsi=4HhjlX6bUbEHfV2R

  • @slipoch6635
    @slipoch6635 Před 9 měsíci

    you flash your API key

    • @nickchapsas
      @nickchapsas  Před 9 měsíci +1

      Go on, use it

    • @slipoch6635
      @slipoch6635 Před 9 měsíci

      laughed my arse off when I saw this comment ;) @@nickchapsas

  • @sergeitishkov2385
    @sergeitishkov2385 Před 9 měsíci

    The approach looks clever but I don't like it. It increases the amount of magic in the app. A new dev who comes there after 3 years might be killed by this clever stuff when the app behaves not as expected. It would be much better to implement such a feature even with an abstract class despite the fact that abstract classes rarely a good solution. But here even an abstract class would be much better.

  • @MatinDevs
    @MatinDevs Před 6 měsíci

    Imagine using it in a company's project 😂

  • @Pleviwow
    @Pleviwow Před 9 měsíci

    calling http handlers a secret feature is a bit of an overstatement

  • @noijze
    @noijze Před 9 měsíci

    If it is "secret" it is poorly documented bij MS

  • @boogyman2501
    @boogyman2501 Před 9 měsíci +4

    Love your videos, have been a big fan for a while now but profanity is not cool my dude

  • @sanampakuwal
    @sanampakuwal Před 9 měsíci +1

    First

  • @user-cv5fd3ym7y
    @user-cv5fd3ym7y Před 9 měsíci

    Those click-bait titles Nick uses are really frustrating.
    I understand why they are used, but anyway

  • @dewaldabrie
    @dewaldabrie Před 9 měsíci +1

    Interesting topic, but no need to take the name of Jesus Christ in vain (around 3:25).

  • @johnny-vz
    @johnny-vz Před 9 měsíci

    Man, I was left with a bad taste in my mouth when I started watching this. You don't even have the guts to own your slip of tongue. Sorry if it was intentional, You lost me.

  • @bd73ne
    @bd73ne Před 9 měsíci

    Love your videos but please don’t use profanity.

  • @pramod.kulkarni9607
    @pramod.kulkarni9607 Před 9 měsíci

    Can i use this iin tge multi tenent architecture

  • @4arliEdinorog
    @4arliEdinorog Před 8 měsíci

    Охуенно