I have an ASP .Net Core 1.1 Web Api, which serves requests from a front end web app and phone app. The app is for real estate agents to perform inspections on properties. The system therefore has entities such as inspections, properties, users, agencies, etc. Users (i.e. real estate agents) and properties belong to agencies. So an estate agency can have one or more users and one or more properties.
As an example, a user might want to view a list of all properties inspected by anyone in his estate agency. In this case, he clicks somewhere in the web/phone app, and the app sends off an HTTP GET request to the API to retrieve the list of properties. The Web API, upon receiving this request, first checks which user is requesting this, and then checks which agency this user belongs to, and then returns all the properties that belong to this agency. So... these are the [simplified] models that I have:
[Table("agency")] public class Agency { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Column("agency_id")] public int? Id { get; set; } [Column("name")] public string Name { get; set; } } [Table("user")] public class User { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Column("user_id")] public int? Id { get; set; } [Column("username")] public string Username { get; set; } [Column("agency_id")] public int AgencyId { get; set; } [ForeignKey("AgencyId")] public Agency Agency { get; set; } } [Table("property")] public class Property { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Column("property_id")] public int? Id { get; set; } [Column("address")] public string Address { get; set; } [Column("agency_id")] public int AgencyId { get; set; } [ForeignKey("AgencyId")] public Agency Agency { get; set; } }
The controller action on the Web API that handles the aforementioned request looks like this:
[Authorize] [HttpGet] public async Task<IActionResult> GetProperties() { // Get Auth0 identifier for the user performing the request string nameIdentifier = User.Claims.FirstOrDefault(c => c.Type == System.Security.Claims.ClaimTypes.NameIdentifier)?.Value; // Retrieve this user from the database User user = await _context.User.SingleOrDefaultAsync(u => u.Username == nameIdentifier); // Return a list of properties that belong to the user's agency return Ok(_context.Properties .Where(p.AgencyId == user.AgencyId)); }
Now, all GET requests to the API are filtered like this - where the API returns records that pertain to the logged in user's agency. Whether the user requests a list of inspections, or landlords, or tenants, the API always returns only records that belong to the user's agency.
Now I know ASP .Net Core is stateless, so I can't save the user object on the server when the user logs in, and have it in memory ready to be called in each controller action. But I feel like this round trip to the database EVERY time the API receives any GET request to find out which agency this user belongs to is wasteful. Is there a better way to do this? I'm fairly new to ASP and web development in general. Any ideas/hints/pointers would be greatly appreciated. And sorry for the very long post!
Thanks...