Api improvements

This commit is contained in:
2025-09-09 21:34:06 +00:00
parent 24276ec0a7
commit 4f82fc4be3
3 changed files with 46 additions and 30 deletions

View File

@@ -5,7 +5,7 @@ import { jsonSchemaTransform, serializerCompiler, validatorCompiler } from 'fast
import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts'; import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts';
import { FastifySSEPlugin } from 'fastify-sse-v2'; import { FastifySSEPlugin } from 'fastify-sse-v2';
import { searchEndpoint } from './endpoints/endpoints.search.ts'; import { streamEndpoint } from './endpoints/endpoints.stream.ts';
import { documentsEndpoint } from './endpoints/endpoints.documents.ts'; import { documentsEndpoint } from './endpoints/endpoints.documents.ts';
type CreateApiOptions = { type CreateApiOptions = {
@@ -20,10 +20,16 @@ const createApi = async (options: CreateApiOptions) => {
app.register(fastifySwagger, { app.register(fastifySwagger, {
openapi: { openapi: {
info: { info: {
title: 'SampleApi', title: 'FluxCurrent',
description: 'Sample backend service', description: 'Sample backend service',
version: '1.0.0', version: '1.0.0',
}, },
tags: [
{
name: 'documents',
description: 'Documents',
},
],
servers: [], servers: [],
}, },
transform: jsonSchemaTransform, transform: jsonSchemaTransform,
@@ -35,7 +41,7 @@ const createApi = async (options: CreateApiOptions) => {
await app.register(FastifySSEPlugin); await app.register(FastifySSEPlugin);
await app.register(searchEndpoint, { services: options.services, prefix: '/search' }); await app.register(streamEndpoint, { services: options.services, prefix: '/streaming' });
await app.register(documentsEndpoint, { services: options.services, prefix: '/documents' }); await app.register(documentsEndpoint, { services: options.services, prefix: '/documents' });
await app.ready(); await app.ready();

View File

@@ -2,13 +2,20 @@ import type { FastifyPluginAsyncZod } from 'fastify-type-provider-zod';
import { z } from 'zod/v4'; import { z } from 'zod/v4';
import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts'; import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts';
import { DocumentsService } from '@morten-olsen/fluxcurrent-core/services/documents/documents.ts'; import { DocumentsService } from '@morten-olsen/fluxcurrent-core/services/documents/documents.ts';
import { documentUpsertSchema } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts'; import {
documentSearchResultSchema,
documentUpsertSchema,
} from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts';
import { parseDSL } from '@morten-olsen/fluxcurrent-core/services/documents/documents.dsl.ts';
const documentsEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (fastify, { services }) => { const documentsEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (fastify, { services }) => {
fastify.route({ fastify.route({
method: 'POST', method: 'POST',
url: '', url: '',
schema: { schema: {
operationId: 'post.documents',
summary: 'Upsert a document',
tags: ['documents'],
body: z.object({ body: z.object({
document: documentUpsertSchema, document: documentUpsertSchema,
}), }),
@@ -19,6 +26,28 @@ const documentsEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (
res.send(documents); res.send(documents);
}, },
}); });
fastify.route({
method: 'GET',
url: '',
schema: {
operationId: 'get.documents',
summary: 'Find documents',
tags: ['documents'],
querystring: z.object({
query: z.string().optional(),
}),
response: {
200: documentSearchResultSchema,
},
},
handler: async (req, res) => {
const query = req.query.query ? parseDSL(req.query.query) : {};
const documentsService = services.get(DocumentsService);
const documents = await documentsService.search(query);
res.send(documents);
},
});
}; };
export { documentsEndpoint }; export { documentsEndpoint };

View File

@@ -3,36 +3,17 @@ import { z } from 'zod/v4';
import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts'; import type { Services } from '@morten-olsen/fluxcurrent-core/utils/services.ts';
import { parseDSL } from '@morten-olsen/fluxcurrent-core/services/documents/documents.dsl.ts'; import { parseDSL } from '@morten-olsen/fluxcurrent-core/services/documents/documents.dsl.ts';
import { DocumentsService } from '@morten-olsen/fluxcurrent-core/services/documents/documents.ts'; import { DocumentsService } from '@morten-olsen/fluxcurrent-core/services/documents/documents.ts';
import { import { type DocumentUpsertEvent } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts';
documentSearchResultSchema,
type DocumentUpsertEvent,
} from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts';
import { filterDocument } from '@morten-olsen/fluxcurrent-core/services/documents/documents.filter.ts'; import { filterDocument } from '@morten-olsen/fluxcurrent-core/services/documents/documents.filter.ts';
const searchEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (fastify, { services }) => { const streamEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (fastify, { services }) => {
fastify.route({
method: 'POST',
url: '',
schema: {
body: z.object({
query: z.string().optional(),
}),
response: {
200: documentSearchResultSchema,
},
},
handler: async (req, res) => {
const query = req.body.query ? parseDSL(req.body.query) : {};
const documentsService = services.get(DocumentsService);
const documents = await documentsService.search(query);
res.send(documents);
},
});
fastify.route({ fastify.route({
method: 'GET', method: 'GET',
url: '/stream', url: '/documents',
schema: { schema: {
operationId: 'get.stream.documents',
summary: 'Stream documents matching a query',
tags: ['streams', 'documents'],
querystring: z.object({ querystring: z.object({
query: z.string().optional(), query: z.string().optional(),
}), }),
@@ -59,4 +40,4 @@ const searchEndpoint: FastifyPluginAsyncZod<{ services: Services }> = async (fas
}); });
}; };
export { searchEndpoint }; export { streamEndpoint };