简体   繁体   中英

REST API Best practice for handling junction data

I am working on a service oriented architecture. I have 3 tables Meeting, Stakeholder and MeetingStakeholder (a junction table).

A simple representation of POCO classes for all 3 tables:

public class Meeting
{
    public int Id { get; set; }
    public IList<MeetingStakeholder> MeetingStakeholders { get; set; }
}

public class Stakeholder
{
    public int Id { get; set; }
}

public class MeetingStakeholder
{
    public int Id { get; set; }

    public int MeetingId { get; set; }
    public Meeting Meeting { get; set; }

    public int StakeholderId { get; set; }
    public Stakeholder Stakeholder { get; set; }
}

A simple representation of Meeting Dto:

public class MeetingDto
{
    public int Id { get; set; }
    public IList<int> StakeholderIds { get; set; }
}

In PUT action,

PUT: api/meetings/1

First I removes all existing records from MeetingStakeholder (junction table) then prepares new List<MeetingStakeholder> meetingStakeholders using meetingDto.StakeholderIds and create it.

{
   List<MeetingStakeholder> existingMeetingStakeholders = _unitOfWork.MeetingStakeholderRepository.Where(x=> x.MeetingId == meetingDto.Id);
   _unitOfWork.MeetingStakeholderRepository.RemoveRange(existingMeetingStakeholders);

   List<MeetingStakeholder> meetingStakeholders = ... ;

   _unitOfWork.MeetingRepository.Update(meeting);       
   _unitOfWork.MeetingStakeholderRepository.CreateRange(meetingStakeholders);
   _unitOfWork.SaveChanges();

   return OK(meetingDto);
}

Everything is fine to me. But my architect told me that i am doing wrong thing. He said, in PUT action (according to SRP) I should not be removing and re-creating MeetingStakeholder records, I should be responsible for updating meeting object only.

According to him, MeetingStakeholderIds (array of integers) should be send in request body to these routes.

For assigning new stakeholders to meeting.

POST:  api/meetings/1/stakeholders

For removing existing stakeholders from meeting.

Delete: api/meetings/1/stakeholders

But the problem is, In meeting edit screen my front-end developer uses multi-select for Stakeholders. He will need to maintain two Arrays of integers.

First Array for those stakeholders Ids which end-user unselect from multi-select. Second Array for new newly selected stakeholders Ids. Then he will send these two arrays to their respective routes as I mentioned above.

If my architect is right then I have no problem but how should my front-end developer handle stakeholders selection in edit screen?

One thing I want to clarify that my junction table is very simple, it does not contain additional columns other than MeetingId and StakeholderId ( a very basic junction). So in this scenario, does it make sense to create separate POST/DELETE actions on "api/meetings/1/stakeholders" that receives StakeholderIds (list of integers) instead of receiving StakeholderIds directly in MeetingDto??

First of all, if I am not mistaken:

  • you have a resource: "Meeting";
  • you want to update the said resource (using HTTP/PUT).

So updating a meeting by requesting a PUT on "/api/meetings/:id" seems fairly simple, concise, direct and clear. All good traits for designing a good interface. And it still respects the Single Responsibility Principle: You are updating a resource"

Nonetheless, I also agree with you architect in providing, in addition to the previous method, POST/Delete actions on "api/meetings/1/stakeholders" if the requisites justify so. We should be pragmatic at some level not to overengineer something that isn't required to.

Now if your architect just said that because of HOW IT IS PERSISTED, then he is wrong. Interfaces should be clear to the end user (frontend today, another service or app tomorrow ...), but most importantly, in this case, ignorant of its persistence or any implementation for that matter.

Your api should focus on your domain and your business rules, not on how you store the information.

This is just my view. If someone does not agree with me I would like to be called out and so both could grow and learn together.

:) Hope I Could be of some help. Cheers

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM