首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >回顾基本API

回顾基本API
EN

Code Review用户
提问于 2020-10-21 22:31:43
回答 1查看 120关注 0票数 2

我正在学习ASP.NET,我已经创建了一些简单的API,所以我可以认为自己可能是一个中级初学者。

我决定创建一个用于两个目的的教程:巩固我所学到的知识,并满足对我的语言初学者教程的需求。

我刚刚创建了一个带有CRUD功能的非常简单的API,我想让您回顾一下它。我故意不使用存储库模式和DTO,因为它们可能会让刚刚起步的人感到困惑(至少这是我的经验)。但我确实计划在下一阶段添加这些内容,以及验证和错误处理。

请拆开所有的东西,我需要所有可能的反馈,因为我需要理解我所写的代码的每一行。

主计长:

代码语言:javascript
复制
    [ApiController]
    [Route("api/records")]
    public class RecordsController : ControllerBase
    {
        private readonly DataContext _context;

        public RecordsController(DataContext context)
        {
            _context = context;
        }
        
        [HttpGet]
        public ActionResult<IEnumerable<Record>> GetRecords()
        {
            return _context.Records.ToList();
        }

        [HttpGet("{id}")]
        public ActionResult<Record> GetRecordById(int id)
        {
            return _context.Records.Find(id);
        }

        [HttpPost]
        public ActionResult<Record> AddRecord([FromBody] Record record)
        {
            _context.Records.Add(record);
            _context.SaveChanges();

            return Ok();
        }

        [HttpDelete("{id}")]
        public ActionResult<Record> DeleteRecord(int id)
        {
            var recordForDeletion = _context.Records.FirstOrDefault(r => r.Id == id);
            _context.Records.Remove(recordForDeletion);
            _context.SaveChanges();
            return Ok();
        }

        [HttpPut("{id}")]
        public ActionResult<Record> UpdateRecord(int id, [FromBody] Record record)
        {
            var recordForUpdate = _context.Records.FirstOrDefault(r => r.Id == id);
            
            recordForUpdate.Date = record.Date; 
            recordForUpdate.Name = record.Name; 
            recordForUpdate.Value = record.Value;
            recordForUpdate.Category = record.Category; 
            recordForUpdate.Type = record.Date; 

            _context.SaveChanges();

            return Ok();
        }
    }
}

DataContext

代码语言:javascript
复制
public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options) { }

        public DbSet<Record> Records { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            //seed database with dummy data
            modelBuilder.Entity<Record>().HasData(
                new Record()
                {
                    Id = 1,
                    Date = "2020-09-30T00:00:01",
                    Name = "Coles",
                    Value = 20,
                    Category = "Groceries",
                    Type = "Expense"                   
                },

                new Record()
                {
                    Id = 2,
                    Date = "2020-10-01T00:00:01",
                    Name = "Traslink",
                    Value = 30,
                    Category = "Transportation",
                    Type = "Expense"                   
                },

                new Record()
                {
                    Id = 3,
                    Date = "2020-10-02T00:00:01",
                    Name = "Cafe 63",
                    Value = 22,
                    Category = "Eating Out",
                    Type = "Expense"                   
                }
            );
        }
    }
}

启动:

代码语言:javascript
复制
  public class Startup
    {
        private readonly IConfiguration _config;
        public Startup(IConfiguration config)
        {
            _config = config;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddDbContext<DataContext>(x =>
                x.UseSqlite(_config.GetConnectionString("DefaultConnection")));
```
代码语言:javascript
复制
EN

回答 1

Code Review用户

发布于 2020-10-22 15:36:17

此实现与可生产的CRUD API相差甚远.我只想列举一些缺失的东西:

  • 表示和持久层分离
    • 控制器应该处理HTTP相关的内容,而不是数据库

  • 正确的状态代码处理
    • (详见下一节)

  • 模型验证
  • 错误处理
    • 例如:如果数据库没有响应,怎么办?

  • 分页
  • 利用异步I/O操作
    • 它可以提高可伸缩性。

  • API版本化
  • API 文档
    • 例如,通过OpenAPI

  • 认证与授权
  • 对修改的审计
  • 等。

更好地利用状态代码

  • POST
    • 如果Id来自用户,并且应该是唯一的(为了能够进行查找),那么如果提供的Id已经存储在数据库中呢?
    • 顺便说一下,Id不应该来自用户。这就是为什么分离数据库模型和API模型是一个很好的实践。
    • 如果成功,201是建议的状态代码。持久化资源可以发送回响应体内的用户,或者位置标头应该指向新资源。

  • 获取
    • 如果提供的Id没有记录怎么办?

  • 删除
    • 204或404通常用于指示资源已消失。
    • 如果尝试删除不存在的记录,则当前实现将失败。
    • 根据您的需求,您可能会或不区分删除现有和不存在的资源。

在这里你可以找到一张海报,它可以帮助您决定何时使用哪个http状态代码。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/250987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档