2 Commits

Author SHA1 Message Date
LD50
d647bedb33 Merge pull request #60 from LD-Reborn/44-fix-controller-endpoint-naming-and-http-methods
Fixed endpoint naming and http methods
2025-12-28 17:36:17 +01:00
fe6bbfe9e5 Fixed endpoint naming and http methods 2025-12-28 17:36:01 +01:00
6 changed files with 113 additions and 67 deletions

View File

@@ -36,7 +36,7 @@ public class Client
public async Task<SearchdomainListResults> SearchdomainListAsync()
{
return await GetUrlAndProcessJson<SearchdomainListResults>(GetUrl($"{baseUri}/Searchdomain", "List", apiKey, []));
return await GetUrlAndProcessJson<SearchdomainListResults>(GetUrl($"{baseUri}", "Searchdomains", apiKey, []));
}
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync()
@@ -46,7 +46,7 @@ public class Client
public async Task<SearchdomainDeleteResults> SearchdomainDeleteAsync(string searchdomain)
{
return await GetUrlAndProcessJson<SearchdomainDeleteResults>(GetUrl($"{baseUri}/Searchdomain", "Delete", apiKey, new Dictionary<string, string>()
return await DeleteUrlAndProcessJson<SearchdomainDeleteResults>(GetUrl($"{baseUri}", "Searchdomain", apiKey, new Dictionary<string, string>()
{
{"searchdomain", searchdomain}
}));
@@ -57,12 +57,12 @@ public class Client
return await SearchdomainCreateAsync(searchdomain);
}
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync(string searchdomain)
public async Task<SearchdomainCreateResults> SearchdomainCreateAsync(string searchdomain, SearchdomainSettings searchdomainSettings = new())
{
return await GetUrlAndProcessJson<SearchdomainCreateResults>(GetUrl($"{baseUri}/Searchdomain", "Create", apiKey, new Dictionary<string, string>()
return await PostUrlAndProcessJson<SearchdomainCreateResults>(GetUrl($"{baseUri}", "Searchdomain", apiKey, new Dictionary<string, string>()
{
{"searchdomain", searchdomain}
}));
}), new StringContent(JsonSerializer.Serialize(searchdomainSettings), Encoding.UTF8, "application/json"));
}
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string newName, string settings = "{}")
@@ -72,14 +72,18 @@ public class Client
return updateResults;
}
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string searchdomain, string newName, SearchdomainSettings settings = new())
{
return await SearchdomainUpdateAsync(searchdomain, newName, JsonSerializer.Serialize(settings));
}
public async Task<SearchdomainUpdateResults> SearchdomainUpdateAsync(string searchdomain, string newName, string settings = "{}")
{
return await GetUrlAndProcessJson<SearchdomainUpdateResults>(GetUrl($"{baseUri}/Searchdomain", "Update", apiKey, new Dictionary<string, string>()
return await PutUrlAndProcessJson<SearchdomainUpdateResults>(GetUrl($"{baseUri}", "Searchdomain", apiKey, new Dictionary<string, string>()
{
{"searchdomain", searchdomain},
{"newName", newName},
{"settings", settings}
}));
{"newName", newName}
}), new StringContent(settings, Encoding.UTF8, "application/json"));
}
public async Task<EntityQueryResults> EntityQueryAsync(string query)
@@ -89,11 +93,11 @@ public class Client
public async Task<EntityQueryResults> EntityQueryAsync(string searchdomain, string query)
{
return await GetUrlAndProcessJson<EntityQueryResults>(GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, new Dictionary<string, string>()
return await PostUrlAndProcessJson<EntityQueryResults>(GetUrl($"{baseUri}/Searchdomain", "Query", apiKey, new Dictionary<string, string>()
{
{"searchdomain", searchdomain},
{"query", query}
}));
}), null);
}
public async Task<EntityIndexResult> EntityIndexAsync(List<JSONEntity> jsonEntity)
@@ -104,7 +108,7 @@ public class Client
public async Task<EntityIndexResult> EntityIndexAsync(string jsonEntity)
{
var content = new StringContent(jsonEntity, Encoding.UTF8, "application/json");
return await PostUrlAndProcessJson<EntityIndexResult>(GetUrl($"{baseUri}/Entity", "Index", apiKey, []), content);//new FormUrlEncodedContent(values));
return await PutUrlAndProcessJson<EntityIndexResult>(GetUrl($"{baseUri}", "Entity", apiKey, []), content);
}
public async Task<EntityListResults> EntityListAsync(bool returnEmbeddings = false)
@@ -114,7 +118,7 @@ public class Client
public async Task<EntityListResults> EntityListAsync(string searchdomain, bool returnEmbeddings = false)
{
var url = $"{baseUri}/Entity/List?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&returnEmbeddings={HttpUtility.UrlEncode(returnEmbeddings.ToString())}";
var url = $"{baseUri}/Entities?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&returnEmbeddings={HttpUtility.UrlEncode(returnEmbeddings.ToString())}";
return await GetUrlAndProcessJson<EntityListResults>(url);
}
@@ -125,8 +129,8 @@ public class Client
public async Task<EntityDeleteResults> EntityDeleteAsync(string searchdomain, string entityName)
{
var url = $"{baseUri}/Entity/Delete?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&entity={HttpUtility.UrlEncode(entityName)}";
return await GetUrlAndProcessJson<EntityDeleteResults>(url);
var url = $"{baseUri}/Entity?apiKey={HttpUtility.UrlEncode(apiKey)}&searchdomain={HttpUtility.UrlEncode(searchdomain)}&entity={HttpUtility.UrlEncode(entityName)}";
return await DeleteUrlAndProcessJson<EntityDeleteResults>(url);
}
private static async Task<T> GetUrlAndProcessJson<T>(string url)
@@ -138,7 +142,8 @@ public class Client
?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}");
return result;
}
private static async Task<T> PostUrlAndProcessJson<T>(string url, HttpContent content)
private static async Task<T> PostUrlAndProcessJson<T>(string url, HttpContent? content)
{
using var client = new HttpClient();
var response = await client.PostAsync(url, content);
@@ -148,6 +153,26 @@ public class Client
return result;
}
private static async Task<T> PutUrlAndProcessJson<T>(string url, HttpContent content)
{
using var client = new HttpClient();
var response = await client.PutAsync(url, content);
string responseContent = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<T>(responseContent)
?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}");
return result;
}
private static async Task<T> DeleteUrlAndProcessJson<T>(string url)
{
using var client = new HttpClient();
var response = await client.DeleteAsync(url);
string responseContent = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<T>(responseContent)
?? throw new Exception($"Failed to deserialize JSON to type {typeof(T).Name}");
return result;
}
public static string GetUrl(string baseUri, string endpoint, string apiKey, Dictionary<string, string> parameters)
{
var uriBuilder = new UriBuilder($"{baseUri}/{endpoint}");

View File

@@ -24,7 +24,7 @@ public class EntityController : ControllerBase
_databaseHelper = databaseHelper;
}
[HttpPost("Index")]
[HttpPut]
public ActionResult<EntityIndexResult> Index([FromBody] List<JSONEntity>? jsonEntities)
{
try
@@ -62,7 +62,7 @@ public class EntityController : ControllerBase
}
[HttpGet("List")]
[HttpGet("/Entities")]
public ActionResult<EntityListResults> List(string searchdomain, bool returnModels = false, bool returnEmbeddings = false)
{
if (returnEmbeddings && !returnModels)
@@ -109,7 +109,7 @@ public class EntityController : ControllerBase
return Ok(entityListResults);
}
[HttpGet("Delete")]
[HttpDelete]
public ActionResult<EntityDeleteResults> Delete(string searchdomain, string entityName)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);

View File

@@ -23,7 +23,7 @@ public class SearchdomainController : ControllerBase
_domainManager = domainManager;
}
[HttpGet("List")]
[HttpGet("/Searchdomains")]
public ActionResult<SearchdomainListResults> List()
{
List<string> results;
@@ -40,8 +40,8 @@ public class SearchdomainController : ControllerBase
return Ok(searchdomainListResults);
}
[HttpGet("Create")]
public ActionResult<SearchdomainCreateResults> Create(string searchdomain, string settings = "{}")
[HttpPost]
public ActionResult<SearchdomainCreateResults> Create(string searchdomain, [FromBody]SearchdomainSettings settings = new())
{
try
{
@@ -54,7 +54,7 @@ public class SearchdomainController : ControllerBase
}
}
[HttpGet("Delete")]
[HttpDelete]
public ActionResult<SearchdomainDeleteResults> Delete(string searchdomain)
{
bool success;
@@ -84,11 +84,21 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainDeleteResults(){Success = success, DeletedEntities = deletedEntries, Message = message});
}
[HttpGet("Update")]
public ActionResult<SearchdomainUpdateResults> Update(string searchdomain, string newName, string settings = "{}")
[HttpPut]
public ActionResult<SearchdomainUpdateResults> Update(string searchdomain, string newName, [FromBody]string? settings = "{}")
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
if (settings is null)
{
Dictionary<string, dynamic> parameters = new()
{
{"name", newName},
{"id", searchdomain_.id}
};
searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name WHERE id = @id", parameters);
} else
{
Dictionary<string, dynamic> parameters = new()
{
{"name", newName},
@@ -96,10 +106,11 @@ public class SearchdomainController : ControllerBase
{"id", searchdomain_.id}
};
searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set name = @name, settings = @settings WHERE id = @id", parameters);
}
return Ok(new SearchdomainUpdateResults(){Success = true});
}
[HttpGet("Query")]
[HttpPost("Query")]
public ActionResult<EntityQueryResults> Query(string searchdomain, string query, int? topN, bool returnAttributes = false)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
@@ -114,7 +125,7 @@ public class SearchdomainController : ControllerBase
return Ok(new EntityQueryResults(){Results = queryResults, Success = true });
}
[HttpPost("UpdateSettings")]
[HttpPut("Settings")]
public ActionResult<SearchdomainUpdateResults> UpdateSettings(string searchdomain, [FromBody] SearchdomainSettings request)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
@@ -129,8 +140,8 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainUpdateResults(){Success = true});
}
[HttpGet("GetSearches")]
public ActionResult<SearchdomainSearchesResults> GetSearches(string searchdomain)
[HttpGet("Queries")]
public ActionResult<SearchdomainSearchesResults> GetQueries(string searchdomain)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
@@ -139,8 +150,8 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainSearchesResults() { Searches = searchCache, Success = true });
}
[HttpDelete("Searches")]
public ActionResult<SearchdomainDeleteSearchResult> DeleteSearch(string searchdomain, string query)
[HttpDelete("Query")]
public ActionResult<SearchdomainDeleteSearchResult> DeleteQuery(string searchdomain, string query)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
@@ -154,8 +165,8 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainDeleteSearchResult() {Success = false, Message = "Query not found in search cache"});
}
[HttpPatch("Searches")]
public ActionResult<SearchdomainUpdateSearchResult> UpdateSearch(string searchdomain, string query, [FromBody]List<ResultItem> results)
[HttpPatch("Query")]
public ActionResult<SearchdomainUpdateSearchResult> UpdateQuery(string searchdomain, string query, [FromBody]List<ResultItem> results)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message});
@@ -171,7 +182,7 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainUpdateSearchResult() {Success = false, Message = "Query not found in search cache"});
}
[HttpGet("GetSettings")]
[HttpGet("Settings")]
public ActionResult<SearchdomainSettingsResults> GetSettings(string searchdomain)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
@@ -180,7 +191,7 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainSettingsResults() { Settings = settings, Success = true });
}
[HttpGet("GetSearchCacheSize")]
[HttpGet("SearchCache/Size")]
public ActionResult<SearchdomainSearchCacheSizeResults> GetSearchCacheSize(string searchdomain)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
@@ -196,7 +207,7 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainSearchCacheSizeResults() { SearchCacheSizeBytes = sizeInBytes, Success = true });
}
[HttpGet("ClearSearchCache")]
[HttpPost("SearchCache/Clear")]
public ActionResult<SearchdomainInvalidateCacheResults> InvalidateSearchCache(string searchdomain)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);
@@ -205,7 +216,7 @@ public class SearchdomainController : ControllerBase
return Ok(new SearchdomainInvalidateCacheResults(){Success = true});
}
[HttpGet("GetDatabaseSize")]
[HttpGet("Database/Size")]
public ActionResult<SearchdomainGetDatabaseSizeResult> GetDatabaseSize(string searchdomain)
{
(Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger);

View File

@@ -22,7 +22,7 @@ public class ServerController : ControllerBase
_aIProvider = aIProvider;
}
[HttpGet("GetModels")]
[HttpGet("Models")]
public ActionResult<ServerGetModelsResult> GetModels()
{
try

View File

@@ -4,6 +4,8 @@ using Server.Migrations;
using Server.Helper;
using Server.Exceptions;
using AdaptiveExpressions;
using Shared.Models;
using System.Text.Json;
namespace Server;
@@ -87,6 +89,10 @@ public class SearchdomainManager
}
}
public int CreateSearchdomain(string searchdomain, SearchdomainSettings settings)
{
return CreateSearchdomain(searchdomain, JsonSerializer.Serialize(settings));
}
public int CreateSearchdomain(string searchdomain, string settings = "{}")
{
if (searchdomains.TryGetValue(searchdomain, out Searchdomain? value))

View File

@@ -745,8 +745,8 @@
"datapoints": datapoints
}];
showToast("@T["Creating entity"]", "primary");
fetch(`/Entity/Index`, {
method: 'POST',
fetch(`/Entity`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
@@ -778,8 +778,12 @@
const cacheReconciliation = document.getElementById('createSearchdomainWithCacheReconciliation').checked;
const settings = { CacheReconciliation: cacheReconciliation };
// Implement create logic here
fetch(`/Searchdomain/Create?searchdomain=${encodeURIComponent(name)}&settings=${JSON.stringify(settings)}`, {
method: 'GET'
fetch(`/Searchdomain?searchdomain=${encodeURIComponent(name)}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(settings)
}).then(response => {
if (response.ok) {
showToast("@T["Searchdomain was created successfully"]", "success");
@@ -800,8 +804,8 @@
.getElementById('cacheClear')
.addEventListener('click', () => {
const domainKey = getSelectedDomainKey();
fetch(`/Searchdomain/ClearSearchCache?searchdomain=${encodeURIComponent(domains[domainKey])}`, {
method: 'GET'
fetch(`/Searchdomain/SearchCache/Clear?searchdomain=${encodeURIComponent(domains[domainKey])}`, {
method: 'POST'
}).then(response => {
if (response.ok) {
showToast("@T["Searchdomain cache was cleared successfully"]", "success");
@@ -823,8 +827,8 @@
.addEventListener('click', () => {
const domainKey = getSelectedDomainKey();
const entityName = document.getElementById('EntityConfirmDelete').getAttribute('data-name');
fetch(`/Entity/Delete?searchdomain=${encodeURIComponent(domains[domainKey])}&entityName=${entityName}`, {
method: 'GET'
fetch(`/Entity?searchdomain=${encodeURIComponent(domains[domainKey])}&entityName=${entityName}`, {
method: 'DELETE'
}).then(async response => {
let result = await response.json();
if (response.ok && result.Success) {
@@ -870,8 +874,8 @@
"datapoints": datapoints
}];
showToast("@T["Updating entity"]", "primary");
fetch(`/Entity/Index`, {
method: 'POST',
fetch(`/Entity`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
@@ -897,7 +901,7 @@
.addEventListener('click', () => {
let searchdomain = domains[getSelectedDomainKey()];
let query = document.getElementById('deleteQueryConfirmationModalName').textContent;
fetch(`/Searchdomain/Searches?searchdomain=${searchdomain}&query=${query}`, {
fetch(`/Searchdomain/Query?searchdomain=${searchdomain}&query=${query}`, {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
@@ -924,7 +928,7 @@
let query = document.getElementById('queryUpdateQueryName').textContent;
let data = getQueryUpdateTableData();
console.log()
fetch(`/Searchdomain/Searches?searchdomain=${searchdomain}&query=${query}`, {
fetch(`/Searchdomain/Query?searchdomain=${searchdomain}&query=${query}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
@@ -949,8 +953,8 @@
function deleteSearchdomain(domainKey) {
// Implement delete logic here
fetch(`/Searchdomain/Delete?searchdomain=${encodeURI(domains[domainKey])}`, {
method: 'GET'
fetch(`/Searchdomain?searchdomain=${encodeURI(domains[domainKey])}`, {
method: 'DELETE'
}).then(async response => {
var result = await response.json();;
if (response.ok && result.Success === true) {
@@ -971,8 +975,8 @@
function renameSearchdomain(domainKey, newName) {
// Implement rename logic here
fetch(`/Searchdomain/Update?searchdomain=${encodeURI(domains[domainKey])}&newName=${newName}`, {
method: 'GET'
fetch(`/Searchdomain?searchdomain=${encodeURI(domains[domainKey])}&newName=${newName}`, {
method: 'PUT'
}).then(async response => {
var result = await response.json();
if (response.ok && result.Success === true) {
@@ -996,8 +1000,8 @@
function updateSearchdomainConfig(domainKey, newSettings) {
// Implement update logic here
fetch(`/Searchdomain/UpdateSettings?searchdomain=${encodeURIComponent(domains[domainKey])}`, {
method: 'POST',
fetch(`/Searchdomain/Settings?searchdomain=${encodeURIComponent(domains[domainKey])}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
@@ -1022,17 +1026,17 @@
}
function getSearchdomainConfig(domainKey) {
return fetch(`/Searchdomain/GetSettings?searchdomain=${encodeURIComponent(domains[domainKey])}`)
return fetch(`/Searchdomain/Settings?searchdomain=${encodeURIComponent(domains[domainKey])}`)
.then(r => r.json());
}
function getSearchdomainCacheUtilization(domainKey) {
return fetch(`/Searchdomain/GetSearchCacheSize?searchdomain=${encodeURIComponent(domains[domainKey])}`)
return fetch(`/Searchdomain/SearchCache/Size?searchdomain=${encodeURIComponent(domains[domainKey])}`)
.then(r => r.json());
}
function getSearchdomainDatabaseUtilization(domainKey) {
return fetch(`/Searchdomain/GetDatabaseSize?searchdomain=${encodeURIComponent(domains[domainKey])}`)
return fetch(`/Searchdomain/Database/Size?searchdomain=${encodeURIComponent(domains[domainKey])}`)
.then(r => r.json());
}
@@ -1054,7 +1058,7 @@
let databaseUtilizationPromise = getSearchdomainDatabaseUtilization(getSelectedDomainKey());
/* ---------- ENTITIES ---------- */
let entitiesUrl = `/Entity/List?searchdomain=${encodeURIComponent(domainName)}&returnEmbeddings=false&returnModels=true`;
let entitiesUrl = `/Entities?searchdomain=${encodeURIComponent(domainName)}&returnEmbeddings=false&returnModels=true`;
let entitiesCard = document.querySelector("#entitiesTable").parentElement;
clearEntitiesTable();
showThrobber(entitiesCard);
@@ -1073,7 +1077,7 @@
});
/* ---------- QUERIES ---------- */
let queriesUrl = `/Searchdomain/GetSearches?searchdomain=${encodeURIComponent(domainName)}`;
let queriesUrl = `/Searchdomain/Queries?searchdomain=${encodeURIComponent(domainName)}`;
let queriesCard = document.querySelector("#queriesTable").parentElement;
clearQueriesTable();
showThrobber(queriesCard);