Use Refit for APIs, make data/API stack async

This commit is contained in:
Neil Brommer 2021-11-28 22:32:21 -08:00
parent 9c4f01ab13
commit b00158daa7
17 changed files with 196 additions and 124 deletions

View file

@ -1,6 +1,8 @@
@using Start.Shared
@using System.IO
@inject HttpClient Http
@using Start.Shared.Api
@using Refit
@inject IBookmarkContainersApi bookmarkContainersApi
<Dialog Title="Create Container" Active="this.IsOpen" OnClose="this.OnDialogClose">
<EditForm Model="this.model" OnValidSubmit="this.OnSubmit">
@ -50,16 +52,10 @@
protected async void OnSubmit()
{
HttpResponseMessage response = await Http
.PostAsJsonAsync("BookmarkContainers/Create", model.Title);
ApiResponse<BookmarkContainerDto?> apiResponse = await bookmarkContainersApi
.CreateBookmarkContainer(model.Title);
Stream stream = response.RequestMessage!.Content!.ReadAsStream();
StreamReader reader = new StreamReader(stream);
Console.WriteLine(reader.ReadToEnd());
BookmarkContainerDto? container = await response
!.Content
!.ReadFromJsonAsync<BookmarkContainerDto>();
BookmarkContainerDto? container = apiResponse.Content;
if (container == null)
{

View file

@ -1,5 +1,8 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Start.Shared.Api
@inject HttpClient Http
@inject IBookmarkContainersApi bookmarkContainersApi
@{ string title = $"Delete Container \"{this.ContainerTitle}\""; }
@ -41,8 +44,8 @@
{
try
{
HttpResponseMessage result = await Http
.DeleteAsync($"BookmarkContainers/Delete/{this.BookmarkContainerId}");
HttpResponseMessage result = await bookmarkContainersApi
.DeleteBookmarkContainer(this.BookmarkContainerId);
if (result.StatusCode == System.Net.HttpStatusCode.OK)
{

View file

@ -1,11 +1,16 @@
@page "/Start"
@using Microsoft.AspNetCore.Authorization
@using System.Collections.Generic
@using System.Linq
@using Microsoft.AspNetCore.Components.WebAssembly.Authentication
@using Start.Client.Components
@using Start.Shared
@attribute [Authorize]
@inject HttpClient Http
@using Start.Shared.Api
@using Refit
@* Distiguish from Refit.Authorize *@
@attribute [Microsoft.AspNetCore.Authorization.Authorize]
@inject Blazored.LocalStorage.ILocalStorageService localStorage
@inject IBookmarkContainersApi bookmarkContainersApi
@if (bookmarkContainers == null)
{
@ -101,9 +106,10 @@ else
{
try
{
this.bookmarkContainers = await Http
.GetFromJsonAsync<IList<BookmarkContainerDto>>(
"BookmarkContainers");
ApiResponse<IEnumerable<BookmarkContainerDto>> response = await bookmarkContainersApi
.GetAllBookmarkContainers();
this.bookmarkContainers = response.Content?.ToList();
if (this.bookmarkContainers == null || !this.bookmarkContainers.Any())
{
@ -120,13 +126,10 @@ else
protected async Task CreateDefaultContainer()
{
HttpResponseMessage response = await Http
.PostAsJsonAsync("BookmarkContainers/Create", "Default");
ApiResponse<BookmarkContainerDto?> response = await bookmarkContainersApi
.CreateBookmarkContainer("Default");
BookmarkContainerDto? container = await response
.RequestMessage
!.Content
!.ReadFromJsonAsync<BookmarkContainerDto?>();
BookmarkContainerDto? container = response.Content;
if (container != null)
await this.OnContainerSelected(container.BookmarkContainerId);
@ -139,12 +142,13 @@ else
if (!this.bookmarkContainers?.Any(bc => bc.BookmarkContainerId == bookmarkContainerId) ?? false)
bookmarkContainerId = this.bookmarkContainers?.First().BookmarkContainerId ?? bookmarkContainerId;
BookmarkContainerDto? bookmarkContainer = await Http
.GetFromJsonAsync<BookmarkContainerDto?>(
$"BookmarkContainers/{bookmarkContainerId}");
ApiResponse<BookmarkContainerDto?> response = await bookmarkContainersApi
.GetBookmarkContainer(bookmarkContainerId);
BookmarkContainerDto? container = response.Content;
await this.SetSelectedContainer(bookmarkContainerId);
this.selectedBookmarkContainer = bookmarkContainer;
this.selectedBookmarkContainer = container;
}
catch (AccessTokenNotAvailableException e)
{

View file

@ -5,6 +5,8 @@ using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Blazored.LocalStorage;
using Refit;
using Start.Shared.Api;
namespace Start.Client {
public class Program {
@ -16,12 +18,26 @@ namespace Start.Client {
client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress))
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
// Supply HttpClient instances that include access tokens when making requests to the server project
// Supply HttpClient instances that include access tokens when making requests to the
// server project
builder.Services.AddScoped(sp => sp.GetRequiredService<IHttpClientFactory>()
.CreateClient("Start.ServerAPI"));
.CreateClient("Start.ServerAPI"));
// Blazor will throw an error if a relative URI is used, so we have to get the base
// address for building the API paths
Uri baseUri = new(builder.HostEnvironment.BaseAddress);
builder.Services.AddRefitClient<IBookmarkContainersApi>()
.ConfigureHttpClient(c => {
c.BaseAddress = new Uri(baseUri, "BookmarkContainers");
})
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddRefitClient<IBookmarksApi>()
.ConfigureHttpClient(c => { c.BaseAddress = new Uri(baseUri, "Bookmarks"); })
.AddHttpMessageHandler<BaseAddressAuthorizationMessageHandler>();
builder.Services.AddApiAuthorization();
builder.Services.AddBlazoredLocalStorage();
await builder.Build().RunAsync();

View file

@ -17,6 +17,8 @@
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
<PackageReference Include="Blazored.LocalStorage" Version="4.1.5" />
<PackageReference Include="Refit" Version="6.1.15" />
<PackageReference Include="Refit.HttpClientFactory" Version="6.1.15" />
</ItemGroup>
<ItemGroup>
@ -29,6 +31,8 @@
<ItemGroup>
<None Remove="Blazored.LocalStorage" />
<None Remove="Refit" />
<None Remove="Refit.HttpClientFactory" />
</ItemGroup>
<ItemGroup>
<Content Remove="wwwroot\css\Spectre\" />

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -22,9 +23,9 @@ namespace Start.Server.Controllers {
[ProducesResponseType(StatusCodes.Status200OK,
Type = typeof(IEnumerable<BookmarkContainerDto>))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetAllBookmarkContainers() {
List<BookmarkContainerDto>? containers = this.bookmarkContainerService
.GetUserBookmarkContainers(this.GetAuthorizedUserId())
public async Task<IActionResult> GetAllBookmarkContainers() {
List<BookmarkContainerDto>? containers = (await this.bookmarkContainerService
.GetUserBookmarkContainers(this.GetAuthorizedUserId()))
.Select(bc => bc.MapToDto())
.ToList();
@ -38,9 +39,9 @@ namespace Start.Server.Controllers {
[Route("{bookmarkContainerId}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookmarkContainerDto))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetBookmarkContainer(int bookmarkContainerId) {
BookmarkContainerDto? container = this.bookmarkContainerService
.GetBookmarkContainer(this.GetAuthorizedUserId(), bookmarkContainerId, true, true)
public async Task<IActionResult> GetBookmarkContainer(int bookmarkContainerId) {
BookmarkContainerDto? container = (await this.bookmarkContainerService
.GetBookmarkContainer(this.GetAuthorizedUserId(), bookmarkContainerId, true, true))
?.MapToDto();
if (container == null)
@ -53,9 +54,9 @@ namespace Start.Server.Controllers {
[Route("Create")]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(BookmarkContainerDto))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult CreateBookmarkContainer([FromBody] string title) {
BookmarkContainerDto? container = this.bookmarkContainerService
.CreateBookmarkContainer(this.GetAuthorizedUserId(), title)
public async Task<IActionResult> CreateBookmarkContainer([FromBody] string title) {
BookmarkContainerDto? container = (await this.bookmarkContainerService
.CreateBookmarkContainer(this.GetAuthorizedUserId(), title))
?.MapToDto();
if (container == null)
@ -71,8 +72,8 @@ namespace Start.Server.Controllers {
[Route("Delete/{bookmarkContainerId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult DeleteBookmarkContainer(int bookmarkContainerId) {
bool res = this.bookmarkContainerService
public async Task<IActionResult> DeleteBookmarkContainer(int bookmarkContainerId) {
bool res = await this.bookmarkContainerService
.DeleteBookmarkContainer(this.GetAuthorizedUserId(), bookmarkContainerId);
if (!res)

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@ -25,9 +24,9 @@ namespace Start.Server.Controllers {
[Route("{bookmarkId}")]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BookmarkDto))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult GetBookmark(int bookmarkId) {
BookmarkDto? bookmark = this.bookmarkService
.GetBookmark(this.GetAuthorizedUserId(), bookmarkId)
public async Task<IActionResult> GetBookmark(int bookmarkId) {
BookmarkDto? bookmark = (await this.bookmarkService
.GetBookmark(this.GetAuthorizedUserId(), bookmarkId))
?.MapToDto();
if (bookmark == null)
@ -40,10 +39,10 @@ namespace Start.Server.Controllers {
[Route("Create")]
[ProducesResponseType(StatusCodes.Status201Created, Type = typeof(BookmarkDto))]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public IActionResult CreateBookmark(string title, string url, string? notes,
public async Task<IActionResult> CreateBookmark(string title, string url, string? notes,
int bookmarkGroupId) {
BookmarkDto? bookmark = this.bookmarkService
.CreateBookmark(this.GetAuthorizedUserId(), title, url, notes, bookmarkGroupId)
BookmarkDto? bookmark = (await this.bookmarkService
.CreateBookmark(this.GetAuthorizedUserId(), title, url, notes, bookmarkGroupId))
?.MapToDto();
if (bookmark == null)
@ -58,8 +57,9 @@ namespace Start.Server.Controllers {
[Route("Delete/{bookmarkId}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult DeleteBookmark(int bookmarkId) {
var res = this.bookmarkService.DeleteBookmark(this.GetAuthorizedUserId(), bookmarkId);
public async Task<IActionResult> DeleteBookmark(int bookmarkId) {
var res = await this.bookmarkService
.DeleteBookmark(this.GetAuthorizedUserId(), bookmarkId);
if (!res)
return NotFound();

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Start.Server.Data.Services.Interfaces;
using Start.Server.Extensions;
@ -13,15 +14,15 @@ namespace Start.Server.Data.Services {
this.db = dbContext;
}
public BookmarkContainer? GetBookmarkContainer(string userId,
public async Task<BookmarkContainer?> GetBookmarkContainer(string userId,
int bookmarkContainerId, bool includeGroups = false, bool includeBookmarks = false) {
BookmarkContainer? bookmarkContainer = this.db.BookmarkContainers
BookmarkContainer? bookmarkContainer = await this.db.BookmarkContainers
.Where(bc => bc.BookmarkContainerId == bookmarkContainerId)
.If(includeGroups, q => q.Include(bc => bc.BookmarkGroups))
.If(includeBookmarks, q => q
.Include(bc => bc.BookmarkGroups)
.ThenInclude(bg => bg.Bookmarks))
.SingleOrDefault();
.SingleOrDefaultAsync();
if (bookmarkContainer == null)
return null;
@ -33,31 +34,31 @@ namespace Start.Server.Data.Services {
return bookmarkContainer;
}
public IList<BookmarkContainer> GetUserBookmarkContainers(string userId,
public async Task<IList<BookmarkContainer>> GetUserBookmarkContainers(string userId,
bool includeGroups = false, bool includeBookmarks = false) {
return this.db.BookmarkContainers
return await this.db.BookmarkContainers
.Where(bc => bc.ApplicationUserId == userId)
.If(includeGroups, q => q.Include(bc => bc.BookmarkGroups))
.If(includeBookmarks, q => q
.Include(bc => bc.BookmarkGroups)
.ThenInclude(bg => bg.Bookmarks))
.ToList();
.ToListAsync();
}
public BookmarkContainer? CreateBookmarkContainer(string userId,
public async Task<BookmarkContainer?> CreateBookmarkContainer(string userId,
string title) {
// No need to worry about ownership here
BookmarkContainer newContainer = new(userId, title);
this.db.BookmarkContainers.Add(newContainer);
this.db.SaveChanges();
await this.db.BookmarkContainers.AddAsync(newContainer);
await this.db.SaveChangesAsync();
return newContainer;
}
public BookmarkContainer? UpdateBookmarkContainer(string userId,
public async Task<BookmarkContainer?> UpdateBookmarkContainer(string userId,
BookmarkContainer bookmarkContainer) {
BookmarkContainer? exitingBookmarkContainer = this.db.BookmarkContainers
.SingleOrDefault(bc => bc.BookmarkContainerId
BookmarkContainer? exitingBookmarkContainer = await this.db.BookmarkContainers
.SingleOrDefaultAsync(bc => bc.BookmarkContainerId
== bookmarkContainer.BookmarkContainerId);
if (exitingBookmarkContainer == null
@ -66,15 +67,15 @@ namespace Start.Server.Data.Services {
return null;
this.db.Entry(bookmarkContainer).State = EntityState.Modified;
this.db.SaveChanges();
await this.db.SaveChangesAsync();
return bookmarkContainer;
}
public bool DeleteBookmarkContainer(string userId, int bookmarkContainerId) {
BookmarkContainer? bookmarkContainer = this.db.BookmarkContainers
public async Task<bool> DeleteBookmarkContainer(string userId, int bookmarkContainerId) {
BookmarkContainer? bookmarkContainer = await this.db.BookmarkContainers
.Where(bc => bc.BookmarkContainerId == bookmarkContainerId)
.SingleOrDefault();
.SingleOrDefaultAsync();
if (bookmarkContainer == null)
return false;
@ -83,7 +84,7 @@ namespace Start.Server.Data.Services {
return false;
this.db.BookmarkContainers.Remove(bookmarkContainer);
this.db.SaveChanges();
await this.db.SaveChangesAsync();
return true;
}

View file

@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Start.Server.Data.Services.Interfaces;
using Start.Server.Extensions;
using Start.Server.Models;
using Start.Shared;
namespace Start.Server.Data.Services {
public class BookmarkGroupService : IBookmarkGroupService {
@ -15,12 +14,12 @@ namespace Start.Server.Data.Services {
this.db = dbContext;
}
public BookmarkGroup? GetBookmarkGroup(string userId, int bookmarkGroupId,
public async Task<BookmarkGroup?> GetBookmarkGroup(string userId, int bookmarkGroupId,
bool includeBookmarks = false) {
BookmarkGroup? group = db.BookmarkGroups
BookmarkGroup? group = await db.BookmarkGroups
.Where(bg => bg.BookmarkGroupId == bookmarkGroupId)
.If(includeBookmarks, q => q.Include(bg => bg.Bookmarks))
.SingleOrDefault();
.SingleOrDefaultAsync();
if (!BookmarkOwnershipTools.IsBookmarkGroupOwner(db, userId, bookmarkGroupId))
return null;
@ -28,31 +27,31 @@ namespace Start.Server.Data.Services {
return group;
}
public IList<BookmarkGroup> GetUserBookmarkGroups(string userId,
public async Task<IList<BookmarkGroup>> GetUserBookmarkGroups(string userId,
bool includeBookmarkGroups = false) {
return this.db.BookmarkGroups
return await this.db.BookmarkGroups
.Where(bg => bg.BookmarkContainer!.ApplicationUserId == userId)
.If(includeBookmarkGroups, q => q.Include(bg => bg.Bookmarks))
.ToList();
.ToListAsync();
}
public BookmarkGroup? CreateBookmarkGroup(string userId, string title,
public async Task<BookmarkGroup?> CreateBookmarkGroup(string userId, string title,
string color, int bookmarkContainerId) {
if (!BookmarkOwnershipTools
.IsBookmarkContainerOwner(this.db, userId, bookmarkContainerId))
return null;
BookmarkGroup newBookmarkGroup = new(title, color, bookmarkContainerId);
this.db.BookmarkGroups.Add(newBookmarkGroup);
this.db.SaveChanges();
await this.db.BookmarkGroups.AddAsync(newBookmarkGroup);
await this.db.SaveChangesAsync();
return newBookmarkGroup;
}
public BookmarkGroup? UpdateBookmarkGroup(string userId,
public async Task<BookmarkGroup?> UpdateBookmarkGroup(string userId,
BookmarkGroup bookmarkGroup) {
BookmarkGroup? existingGroup = this.db.BookmarkGroups
.SingleOrDefault(bg => bg.BookmarkGroupId == bookmarkGroup.BookmarkGroupId);
BookmarkGroup? existingGroup = await this.db.BookmarkGroups
.SingleOrDefaultAsync(bg => bg.BookmarkGroupId == bookmarkGroup.BookmarkGroupId);
if (existingGroup == null)
return null;
@ -66,14 +65,14 @@ namespace Start.Server.Data.Services {
return null;
this.db.Entry(bookmarkGroup).State = EntityState.Modified;
this.db.SaveChanges();
await this.db.SaveChangesAsync();
return bookmarkGroup;
}
public bool DeleteBookmarkGroup(string userId, int bookmarkGroupId) {
BookmarkGroup? bookmarkGroup = this.db.BookmarkGroups
.SingleOrDefault(bg => bg.BookmarkGroupId == bookmarkGroupId);
public async Task<bool> DeleteBookmarkGroup(string userId, int bookmarkGroupId) {
BookmarkGroup? bookmarkGroup = await this.db.BookmarkGroups
.SingleOrDefaultAsync(bg => bg.BookmarkGroupId == bookmarkGroupId);
if (bookmarkGroup == null)
return false;
@ -82,7 +81,7 @@ namespace Start.Server.Data.Services {
return false;
this.db.BookmarkGroups.Remove(bookmarkGroup);
this.db.SaveChanges();
await this.db.SaveChangesAsync();
return true;
}

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Start.Server.Data.Services.Interfaces;
using Start.Server.Models;
@ -12,29 +13,29 @@ namespace Start.Server.Data.Services {
this.db = dbContext;
}
public Bookmark? GetBookmark(string userId, int bookmarkId) {
public async Task<Bookmark?> GetBookmark(string userId, int bookmarkId) {
if (!BookmarkOwnershipTools.IsBookmarkOwner(this.db, userId, bookmarkId))
return null;
return this.db.Bookmarks
.SingleOrDefault(b => b.BookmarkId == bookmarkId);
return await this.db.Bookmarks
.SingleOrDefaultAsync(b => b.BookmarkId == bookmarkId);
}
public IList<Bookmark> GetUserBookmarks(string userId) {
return this.db.Bookmarks
public async Task<IList<Bookmark>> GetUserBookmarks(string userId) {
return await this.db.Bookmarks
.Where(b => b.BookmarkGroup!.BookmarkContainer!.ApplicationUserId == userId)
.ToList();
.ToListAsync();
}
public Bookmark? CreateBookmark(string userId, string title, string url, string? notes,
public async Task<Bookmark?> CreateBookmark(string userId, string title, string url, string? notes,
int bookmarkGroupId) {
if (!BookmarkOwnershipTools.IsBookmarkGroupOwner(this.db, userId, bookmarkGroupId))
return null;
Bookmark newBookmark = new(title, url, bookmarkGroupId);
db.Bookmarks.Add(newBookmark);
db.SaveChanges();
await db.Bookmarks.AddAsync(newBookmark);
await db.SaveChangesAsync();
if (newBookmark.BookmarkId <= 0)
return null;
@ -42,7 +43,7 @@ namespace Start.Server.Data.Services {
return newBookmark;
}
public Bookmark? UpdateBookmark(string userId, Bookmark bookmark) {
public async Task<Bookmark?> UpdateBookmark(string userId, Bookmark bookmark) {
Bookmark? existingBookmark = db.Bookmarks
.SingleOrDefault(b => b.BookmarkId == bookmark.BookmarkId);
@ -55,12 +56,12 @@ namespace Start.Server.Data.Services {
return null;
db.Entry(bookmark).State = EntityState.Modified;
db.SaveChanges();
await db.SaveChangesAsync();
return bookmark;
}
public bool DeleteBookmark(string userId, int bookmarkId) {
public async Task<bool> DeleteBookmark(string userId, int bookmarkId) {
Bookmark? bookmark = db.Bookmarks
.SingleOrDefault(b => b.BookmarkId == bookmarkId);
@ -71,7 +72,7 @@ namespace Start.Server.Data.Services {
return false;
db.Bookmarks.Remove(bookmark);
db.SaveChanges();
await db.SaveChangesAsync();
return true;
}

View file

@ -1,19 +1,18 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Start.Server.Models;
using Start.Shared;
namespace Start.Server.Data.Services.Interfaces {
public interface IBookmarkContainerService {
public BookmarkContainer? GetBookmarkContainer(string userId,
public Task<BookmarkContainer?> GetBookmarkContainer(string userId,
int bookmarkContainerId, bool includeGroups = false, bool includeBookmarks = false);
public IList<BookmarkContainer> GetUserBookmarkContainers(string userId,
public Task<IList<BookmarkContainer>> GetUserBookmarkContainers(string userId,
bool includeGroups = false, bool includeBookmarks = false);
public BookmarkContainer? CreateBookmarkContainer(string userId,
public Task<BookmarkContainer?> CreateBookmarkContainer(string userId,
string title);
public BookmarkContainer? UpdateBookmarkContainer(string userId,
public Task<BookmarkContainer?> UpdateBookmarkContainer(string userId,
BookmarkContainer bookmarkContainer);
public bool DeleteBookmarkContainer(string userId, int bookmarkContainerId);
public Task<bool> DeleteBookmarkContainer(string userId, int bookmarkContainerId);
}
}

View file

@ -1,19 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Start.Server.Models;
using Start.Shared;
namespace Start.Server.Data.Services.Interfaces {
public interface IBookmarkGroupService {
public BookmarkGroup? GetBookmarkGroup(string userId,
public Task<BookmarkGroup?> GetBookmarkGroup(string userId,
int bookmarkGroupId, bool includeBookmarks = false);
public IList<BookmarkGroup> GetUserBookmarkGroups(string userId,
public Task<IList<BookmarkGroup>> GetUserBookmarkGroups(string userId,
bool includeBookmarks = false);
public BookmarkGroup? CreateBookmarkGroup(string userId, string title,
public Task<BookmarkGroup?> CreateBookmarkGroup(string userId, string title,
string color, int bookmarkContainerId);
public BookmarkGroup? UpdateBookmarkGroup(string userId,
public Task<BookmarkGroup?> UpdateBookmarkGroup(string userId,
BookmarkGroup bookmarkGroup);
public bool DeleteBookmarkGroup(string userId, int bookmarkGroupId);
public Task<bool> DeleteBookmarkGroup(string userId, int bookmarkGroupId);
}
}

View file

@ -1,16 +1,15 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading.Tasks;
using Start.Server.Models;
using Start.Shared;
namespace Start.Server.Data.Services.Interfaces {
public interface IBookmarkService {
public Bookmark? GetBookmark(string userId, int bookmarkId);
public IList<Bookmark> GetUserBookmarks(string userId);
public Task<Bookmark?> GetBookmark(string userId, int bookmarkId);
public Task<IList<Bookmark>> GetUserBookmarks(string userId);
public Bookmark? CreateBookmark(string userId, string title, string url,
public Task<Bookmark?> CreateBookmark(string userId, string title, string url,
string? notes, int bookmarkGroupId);
public Bookmark? UpdateBookmark(string userId, Bookmark bookmark);
public bool DeleteBookmark(string userId, int bookmarkId);
public Task<Bookmark?> UpdateBookmark(string userId, Bookmark bookmark);
public Task<bool> DeleteBookmark(string userId, int bookmarkId);
}
}

View file

@ -9,6 +9,8 @@ using Start.Server.Data;
using Start.Server.Models;
using Start.Server.Data.Services;
using Start.Server.Data.Services.Interfaces;
using Refit;
using Start.Shared.Api;
namespace Start.Server {
public class Startup {

View file

@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Refit;
namespace Start.Shared.Api {
public interface IBookmarkContainersApi {
[Get("/")]
Task<ApiResponse<IEnumerable<BookmarkContainerDto>>> GetAllBookmarkContainers();
[Get("/{bookmarkContainerId}")]
Task<ApiResponse<BookmarkContainerDto?>> GetBookmarkContainer(int bookmarkContainerId);
[Post("/Create")]
Task<ApiResponse<BookmarkContainerDto?>> CreateBookmarkContainer(
[Body(BodySerializationMethod.Serialized)] string title);
[Delete("/Delete/{bookmarkContainerId}")]
Task<HttpResponseMessage> DeleteBookmarkContainer(int bookmarkContainerId);
}
}

View file

@ -0,0 +1,15 @@
using System.Threading.Tasks;
using Refit;
namespace Start.Shared.Api {
public interface IBookmarksApi {
[Get("{bookmarkId}")]
Task<BookmarkDto?> GetBookmark(int bookmarkId);
[Post("/Create")]
Task CreateBookmark(string title, string url, string? notes, int bookmarkGroupId);
[Delete("/Delete/{bookmarkId}")]
Task DeleteBookmark(int bookmarkId);
}
}

View file

@ -9,4 +9,14 @@
<ItemGroup>
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<None Remove="Refit" />
<None Remove="Api\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Api\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Refit" Version="6.1.15" />
</ItemGroup>
</Project>