正确的 API 调用和服务器端数据存储 - Blazor
我试图学习大餐的同时,将我的一些想法带来生活,因为我认为最好的学习方法是练习。我想为CCG(收藏纸牌游戏)构建一张纸牌查看器,并且我偶然发现了一个障碍,希望有人可以帮助我:),
因为我不想自己存储卡数据库,我正在使用第三方来源下载所需的信息 - 我之后的存储空间有问题。 我制作了一个服务器端控制器,以获取上述DB(在与我自己的类分类以过滤一些未经书面的数据之后)。我想实现的是所有卡的列表和onclick,以获取有关特定信息的信息。
我的控制器看起来像这样:
[Route("[controller]")]
[ApiController]
public class CardController : ControllerBase
{
private List<Card> Cards = new();
[HttpGet("{id}")]
public ActionResult Get(int id)
{
var card = Cards.Find(o => o.Id == id);
if (card != null)
{
return Ok(card);
}
return NotFound("Card not found");
}
[HttpGet("List")]
public ActionResult List()
{
return Ok(Cards);
}
[HttpGet("GetAllCards")]
public async Task<List<Card>> GetAllCards()
{
if (Cards.Count() == 0)
{
Cards = await GetAllCardsPro();
}
return Cards;
}
public async Task<List<Card>> GetAllCardsPro()
{
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://db.ygoprodeck.com/api/v7/cardinfo.php");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
YgoProMap.Rootobject obj = JsonConvert.DeserializeObject<YgoProMap.Rootobject>(responseBody);
if (obj != null)
{
foreach (var card in obj.data)
{
Cards.Add(new Card
{
Id = card.id,
Name = card.name,
Type = card.type,
Desc = card.desc,
Atk = card.atk,
Def = card.def,
Level = card.level,
Race = card.race,
Attribute = card.attribute,
Archetype = card.archetype,
Linkval = card.linkval,
Scale = card.scale,
Images = new string[] { card.card_images.First().image_url, card.card_images.First().image_url_small }
});
}
}
return Cards;
}
}
当我尝试致电 get(id)获取该特定卡的信息时,就会发生问题,并且总是返回404。如果我用手动填充卡列表。新卡(某些数据)我能够获取一张特定卡的信息。因此,我假设在致电该第三方API卡后,它只会将值传递给客户端,一旦服务器上的null剩余空。
因此,我的第一个问题是如何存储从第三方API获取的数据以使其之后可以访问?应该在服务器启动中使用每日刷新吗?例如,是否可以像JSON文件一样存储它?
我的第二个问题是关于最佳实践性能明智之举,因为目前我将整个卡列表传递给客户端(约有10,000个对象)。最好通过一个只存储 card的单独数组。名称 and card.id 将其绑定到UI list/table,之后onclick onclick fet fetch提取该特定的特定卡的完整数据?还是有10,000个对象并不是什么大不了的,我应该通过整个列表并执行所有特定的卡操作客户端?
很抱歉完成这么长时间,但我试图尽可能具体:D
I'm trying to learn Blazor while bringing some of my ideas to live as I think that the best way to learn is by practice. I want to build a card viewer for CCG (collectible card game) and I've stumbled upon a roadblock which I hope someone can help me with :)
As I don't want to store the card database myself, I'm using a 3rd party source to download the required information - and I have a problem with it's storage afterwards.
I made a server-side controller that fetches the mentioned DB (after some sorting with my own class to filter some unnecesarry data). What I wanted to achieve is a list of all the cards and onClick to fetch the info about the specific one by ID.
My controller looks like this:
[Route("[controller]")]
[ApiController]
public class CardController : ControllerBase
{
private List<Card> Cards = new();
[HttpGet("{id}")]
public ActionResult Get(int id)
{
var card = Cards.Find(o => o.Id == id);
if (card != null)
{
return Ok(card);
}
return NotFound("Card not found");
}
[HttpGet("List")]
public ActionResult List()
{
return Ok(Cards);
}
[HttpGet("GetAllCards")]
public async Task<List<Card>> GetAllCards()
{
if (Cards.Count() == 0)
{
Cards = await GetAllCardsPro();
}
return Cards;
}
public async Task<List<Card>> GetAllCardsPro()
{
var client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://db.ygoprodeck.com/api/v7/cardinfo.php");
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
YgoProMap.Rootobject obj = JsonConvert.DeserializeObject<YgoProMap.Rootobject>(responseBody);
if (obj != null)
{
foreach (var card in obj.data)
{
Cards.Add(new Card
{
Id = card.id,
Name = card.name,
Type = card.type,
Desc = card.desc,
Atk = card.atk,
Def = card.def,
Level = card.level,
Race = card.race,
Attribute = card.attribute,
Archetype = card.archetype,
Linkval = card.linkval,
Scale = card.scale,
Images = new string[] { card.card_images.First().image_url, card.card_images.First().image_url_small }
});
}
}
return Cards;
}
}
The problem occurs when I try to call Get(ID) to get info of that specific card and it always return 404. If I manualy populate the Cards list with a new Card(some data) I'm able to get that one specific card's information. So I would assume that after the call to that 3rd party API Cards it just passes the value to client once remaining null on the server.
So my 1st question here is how should I store that data that is fetched from the 3rd party API to make it accessable afterwards? Should it be somewhere in the server startup with a daily refresh? Is it even possible to store it like a JSON file for example?
My 2nd question is about best practices performance wise as at the moment I'm passing the whole List of Cards to the client (~10 thousand objects). Would it be better to pass a separate array that only stores card.Name and card.Id for it to be bound to a UI list/table and afterwards onClick fetch that specific card's full data? Or 10 thousand objects isn't a huge deal and I should just pass the whole List and do all the specific card operation client side?
Sorry for making it so long but I've tried to be as specific as I can :D
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论