gpt4 book ai didi

c# - 使用 REST API 的设计模式

转载 作者:行者123 更新时间:2023-12-03 23:53:05 24 4
gpt4 key购买 nike

我正在制作一个 DLL 以在 aspnetcore 中使用 REST API。

理想情况下,我希望以这种方式访问​​它:

API api = new API(clientInfo);
api.Module.Entity.Action(params);

但我正在努力让这成为现实。我无法制作任何静态内容,因为可能会同时实例化超过 1 个 session 。我不能通过引用传递 session ,否则 session 状态(cookie 等)可能会在副本中更改。有我应该使用的设计模式吗?
public class API
{
private Session _session;
public API(ClientInfo clientInfo)
{
_session = new Session(clientInfo);
}
}

session 充当客户端的中间件,存储登录数据以防客户端需要重复登录,处理一些错误/重试并公开客户端方法。
public class Session
{
private Client _client;
private string _path;
public Session(ClientInfo clientInfo)
{
_client= new Client(clientInfo);
_path = clientInfo.Path;
}
public HttpResponseMessage Get(string name, string arguments = "")
{
return _client.Get(_path, name, arguments);
}
...
}

客户端实际执行调用。
public class Client
{
public HttpResponseMessage Get(string path, string endpointName, string arguments)
{
return GetClient().GetAsync(path + endpointName + arguments).Result;
}
private HttpClient GetClient(){...}
...
}

最佳答案

就个人而言,我只是为我的 API 构建了一个简单的客户端,其方法对应于 API 具有的端点:

public class FooClient
{
private readonly HttpClient _httpClient;

public FooClient(HttpClient httpClient)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
}

public async Task<GetFooResult> Get(int id)
{
...
}

// etc
}
HttpClient通过在 Startup.cs 中注册类型化客户端来提供依赖项:
services.AddHttpClient<FooClient>(c =>
{
// configure client
});

我添加了 IServiceCollection扩展来封装这个和任何其他设置逻辑:
public static class IServiceCollectionExtensions
{
public static IServiceCollection AddFooClient(this IServiceCollection services, string uri)
{
...
}
}

然后,在我的 Startup 中,我可以简单地执行以下操作:
services.AddFooClient(Configuration.GetValue<string>("FooUri"));

这对于通过 Polly 设置自动错误处理、重试策略等非常有帮助,因为您可以在扩展程序中设置所有配置一次。

现在,解决诸如身份验证 token 之类的持久化问题,您有几种可能性。我倾向于将身份验证 token 作为声明持久化,在这种情况下,您可以简单地检索声明并将其传递给客户端上需要它的方法:
var foo = await _fooClient.Get(fooId, User.FindFirstValue("FooAuthToken"));

如果您以这种方式处理事情,您可以在任何范围内绑定(bind)您的客户端,包括单例。

另一种方法是将身份验证 token 实际保存在您的客户端中,但这必须小心。你绝对应该避免使用单例作用域,除非你使用像 ConcurrentDictionary 这样的东西。即便如此,确保始终使用正确的 token 可能有点棘手。

假设您使用的是请求范围,您可以将 token 直接存储为 ivar 或其他内容,但您仍然需要将其保存在其他地方,或者您仍然需要为每个请求重新验证。例如,如果要将其存储在 session 中,则可以执行以下操作:
services.AddScoped<FooClient>(p =>
{
var httpClientFactory = p.GetRequiredService<IHttpClientFactory>();
var httpContextAccessor = p.GetRequiredService<IHttpContextAccessor>();

var httpClient = httpClientFactory.Create("ClientName");
var session = httpContextAccessor.HttpContext.Session;

var client = new FooClient(httpClient);
client.SetAuthToken(session["FooAuthToken"]);
});

但是,即使那样,我仍然会说将身份验证 token 传递给方法比执行任何操作都更好。哪些操作需要身份验证与不需要身份验证的操作更明确,并且您始终确切知道来自哪里的内容。

关于c# - 使用 REST API 的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54577584/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com