Api improvements
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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 };
|
||||||
|
|||||||
@@ -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 };
|
||||||
Reference in New Issue
Block a user