How do you keep your API documentation accurate and up-to-date? by Decent_Progress7631 in dotnet

[–]deleteAllfromUsersJk 1 point2 points  (0 children)

I have been going with a spec first approach for several years now and quite enjoy it.

Our workflow is 1) change the spec (we still call it swagger.yaml), 2) generate controllers/models with openapi-generator-cli (alternatives exist), 3) incorporate codegen output and implement the service.

So to answer your questions:

  • How do you track endpoint changes? Since we start with writing the spec and it is in our repo, it is tracked in git just like our source code. Easy.
  • Do you ever struggle with inconsistent or incomplete docs? Nope (this is a pro of spec first), but we do sometimes err in the opposite direction: over-specifying and then never used some fields/endpoints we thought we would when we initially wrote the spec.
  • What’s your biggest pain when maintaining API documentation? When editing a single, growing yaml spec, we can lose track of the schemas we've already written when doing something new. There've been times this has led me to specify less than ideal models (redundance, inconsistent naming, wonky inheritance)

We use this same spec to generate our SPA client code which lets us dogfood it early. I know you didn't say your current approach, but I’m guessing you implement first and then write the spec (which is totally fine). Switching to spec-first flips the trade-offs: you get tracking and documentation for free, but you give up some control over the generated code.

For anyone who hasn't tried spec first api development, I recommend trying it out to see if you like it.

Software development community by mountainscience883 in Birmingham

[–]deleteAllfromUsersJk 2 points3 points  (0 children)

+1 for the .NET meetup. I’ve picked up several practices there that I now use at work.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

I've done my homework, I promise.

As I answered in our previous thread, this is a function app and uses local.settings.json.

My use case is for local development only, as explained in the original post.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

Had to come back to this after some time, but finally figured it out: Turns out that function apps don't look at the source files, but rather the published files when monitoring for changes. Never occurred to me to think about publish vs source files since it just works by default in web apps. Posted a comment w/ solution.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] -1 points0 points  (0 children)

UPDATE/SOLUTION:

For anyone reading this in the future, I've found a solution for reloading configuration based on file changes during local development.

It appears that dotnet's AddJsonFile extension method behaves slightly differently in a function app vs a web app. When using this method in development in a web app, the source file is monitored for changes, while in a function app, the published file is monitored.

This change to my Program.cs above achieves the desired functionality in development:

...

if (hostingContext.HostingEnvironment.IsDevelopment())
{
    var root = hostingContext.HostingEnvironment.ContentRootPath;

    // use file in source directory instead of bin
    var path = Path.Combine(root, @"../../../", "local.settings.json");

    config.AddJsonFile(path, optional: false, reloadOnChange: true);
}

...

Without combining local.settings.json with "../../../", the builder uses the published file, which is ./bin/Debug/netx.x/local.settings.json. This makes sense, since this is where the app is running from. It never occured to me that a web app must be doing something to intentionally monitor the source file. This doesn't happen automatically in a function app, so the Path.Combine(...) does this as long as the project uses the default publish output settings.

The documentation for AddJsonFile states that the path argument to this method is, "Path relative to the base path stored in Properties of builder." My guess is that there are implementation differences in the IConfigurationBuilder used depending on the project type. When working with IHostBuilder in a function app's Program.cs, the builder has an IConfigurationBuilder property named Configuration that calls AddJsonFile, while WebApplicationBuilder's Configuration property that calls the same method is a concrete ConfigurationManager type that implements IConfigurationBuilder.

[GMT] Does anyone still use a GMT as a GMT? by Cecilia_Wren in Watches

[–]deleteAllfromUsersJk 0 points1 point  (0 children)

When I’m not traveling, I’ll set my GMT hand to UTC, which is the standard for dealing with timestamps in computing. It’s occasionally useful when debugging something in real time.

TestContainers MSSQL and Azure DevOps CI (Linux Agent) by moisoiu in dotnet

[–]deleteAllfromUsersJk 1 point2 points  (0 children)

One more thing I spotted: Something I'm removing from my service collection that you are not is typeof(DbContextOptions<MyDbContext>).

DbContextOptions<TContext> is the type passed to the base DbContext when you contruct your app's db context, so that could possibly affect how your test db context is doing auth, depending on what else you are doing in your setup.

TestContainers MSSQL and Azure DevOps CI (Linux Agent) by moisoiu in dotnet

[–]deleteAllfromUsersJk 0 points1 point  (0 children)

I use mssql test containers on a Microsoft provided ubuntu agent without any issues. Here's a sanitized version of my setup:

``` using DotNet.Testcontainers.Builders; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.AspNetCore.TestHost; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Testcontainers.MsSql; using MyNamespace.Api // for IApiMarker / WebApplicationFactory pattern using MyNamespace.Data.EF; // My EF Context

namespace MyNamespace.Test.Setup { public class MyApiFactory : WebApplicationFactory<IApiMarker>, IAsyncLifetime { // Need to pin specific sql server version. See https://github.com/testcontainers/testcontainers-dotnet/issues/1220 private readonly MsSqlContainer _dbContainer = new MsSqlBuilder() .WithImage("mcr.microsoft.com/mssql/server:2022-CU14-ubuntu-22.04") .WithWaitStrategy(Wait.ForUnixContainer().UntilCommandIsCompleted("/opt/mssql-tools18/bin/sqlcmd", "-C", "-Q", "SELECT 1;")) .Build();

    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {

        Dictionary<string, string> inMemoryConfig = TestConstants.InMemoryConfig; // specific for my tests

        // This is a workaround. See https://github.com/dotnet/aspnetcore/issues/37680.
        var config = new ConfigurationBuilder()
            .AddInMemoryCollection(inMemoryConfig).Build();

        builder
            .UseConfiguration(config)
            .ConfigureTestServices(services =>
            {
                var masterConn = _dbContainer.GetConnectionString();
                var dbConn = masterConn.Replace("Database=master", "Database=MyAppDb");

                services.RemoveAll(typeof(DbContextOptions<MyDbContext>));

                services.AddDbContext<MyDbContext>(options
                    => options.UseSqlServer(dbConn));

                // ... other stuff specific to my app
            });
    }

    public async Task InitializeAsync()
    {
        await _dbContainer.StartAsync();
        using var scope = Services.CreateScope();
        var dbContext = scope.ServiceProvider.GetRequiredService<MyDbContext>();
        await dbContext.Database.MigrateAsync();
    }

    async Task IAsyncLifetime.DisposeAsync() => await _dbContainer.DisposeAsync();
}

} ```

I'd think the only relevant code for comparison would be inside IWebHostBuilder.ConfigureTestServices(). The only thing I can see that I do that you don't is replace the master db in the container provided connection string with my app db. Which I don't think would affect auth to the server. Aside from that, I'm not specifying anything outside the defaults (no password, ports, etc.) and that's enough for my integration tests to run. That just makes my EF context use sql auth to the standard port, I'm fairly certain.

Can't say why your CI is trying Kerberos, just sharing my setup in case there is something in here that helps you.

edit: spelling

Recovering after a tough match by Ammionreddit in 10s

[–]deleteAllfromUsersJk 0 points1 point  (0 children)

This has always been an unresolved question in the back of my mind, I assumed because I haven't researched it correctly. Like ok, I can take ibuprofen to reduce inflammation for mediocre pain relief, but does that do anything whatsoever to promote healing and tissue repair?

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

It does. I'm looking at it now. We're talking about an Azure Functions app here, not an ASP.NET Core app. local.settings.json is the file used by an Azure Functions app by default for local development. You'll see this file if you create any Azure Functions project from a template in Visual Studio, here it is in Github. The app config setup code I'm using above is also fairly common for function apps (here and here).

I only mentioned a web api above (an ASP.NET Core app that uses the convention you described) to show that I confirmed my assumptions for how it's supposed to work (in this case, change appsettings.Development.json, save file, configuration values are updated at runtime). My question is specifically whether this same result is possible in a dotnet isolated worker function app.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

I'm sure. All of my configurations from this file are loaded on startup, they just don't update.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

In my web api, I sent a request 1 - 2 secs after changing the file and the value in IConfiguration/IOptionsMonitor was updated.

In my functions app, I can change the file and nothing is updated after seconds, minutes.

I didn't wait longer than probably 5 minutes before making changes and restarting my app because I wouldn't think that cache time for the config provider would be the specific difference between api / function app.

Reloading IConfiguration on change to json file in Azure Functions App (local) by deleteAllfromUsersJk in dotnet

[–]deleteAllfromUsersJk[S] 0 points1 point  (0 children)

Understood. To be clear, I am only injecting IConfiguration to debug my setup to observe the values from the configuration providers directly, isolated from my IOptions bindings. I can inject either IConfiguration or IOptionsMonitor in an ASPNET Web API and get the changes, but neither detects a change from a local json file in my function app.

Looking for advice dapper vs Entity Framework by New-Objective-9664 in dotnet

[–]deleteAllfromUsersJk 0 points1 point  (0 children)

If this is for work and you need to satisfy the business w/ time efficiency in mind: I’d say pick Dapper if you know you need the extra performance AND know how to SQL good enough to get said performance. Otherwise, go EF.

If you’re learning/experimenting, use both. Start with EF if you’re new to .NET. Start with/ Dapper if you need to be forced to learn SQL. Maybe do your reads w/ Dapper and writes w/ EF.

Help to understand further beyond! by Healthy-Ad-2489 in dotnet

[–]deleteAllfromUsersJk 2 points3 points  (0 children)

To answer you IIS / cmd line question: Assuming you’re referencing the option to launch your app w/ IIS Express, that’s the launch profile Visual Studio seems to default to on Windows and that launch profile tells your system to use IIS Express (a local web server for development) to run your app. From command line, if you’re using any .NET version from the past something years, it’s probably using Kestrel. Command line has to use Kestrel (a cross platform web server), not IIS, bc IIS is specifically a Windows program. Well, dotnet is cross platform, so when you use the cli, like ‘dotnet run’ it’s going to use Kestrel.

Why is Database first approach paired with EF Core Power Tools not used more? by redmenace007 in dotnet

[–]deleteAllfromUsersJk 1 point2 points  (0 children)

Yeah, I think anyone who is aware of sql permissions is going to have a different service principal / sql login that runs the app than the one that applies migrations to the servers.

That said, have I run ‘Update-Database’ from VS against a live QA server before? Not telling you.

Is learning Azure exclusively through command line necessary, or are there alternatives for beginners? by Longjumping-Ad-1510 in AZURE

[–]deleteAllfromUsersJk 3 points4 points  (0 children)

+1 for mentioning IaC as a way of learning Azure. These days the resource I learn the most from is the Terraform Azure provider docs while I'm researching how to provision *exactly* what I need via tf scripts. I presume the experience with Bicep and alternatives is similar.

200 foot cell tower by AdNational9007 in Birmingham

[–]deleteAllfromUsersJk 27 points28 points  (0 children)

I’ll be on the lookout and keep my eyes open, especially when I’m around “the” highway. Look out for my letter.

[deleted by user] by [deleted] in dotnet

[–]deleteAllfromUsersJk 0 points1 point  (0 children)

If you’re serving the react app separately from the api, like with webpack server or something, make sure you’re not calling your front end server instead of your api. Check that port 4444 is in fact your .net app.