Rename webhook and open api urls (#11684)

We want to have fewer base path for routing.

We will have:
- /files
- /webhooks
- /graphql
- /metadata
- /rest
- /auth
- /healthz

I'm moving /open-api under /rest, and centralizing the webhooks
(removing /stripe and /cloudflare)
This commit is contained in:
Félix Malfait
2025-04-22 22:24:26 +02:00
committed by GitHub
parent fba9ae6dfe
commit 8694840b92
9 changed files with 30 additions and 30 deletions

View File

@ -59,7 +59,7 @@ export const PlaygroundSetupForm = () => {
try { try {
// Validate by fetching the schema (but not storing it) // Validate by fetching the schema (but not storing it)
const response = await fetch( const response = await fetch(
`${REACT_APP_SERVER_BASE_URL}/open-api/${values.schema}`, `${REACT_APP_SERVER_BASE_URL}/rest/open-api/${values.schema}`,
{ {
headers: { Authorization: `Bearer ${values.apiKeyForPlayground}` }, headers: { Authorization: `Bearer ${values.apiKeyForPlayground}` },
}, },

View File

@ -68,7 +68,7 @@ export const RestPlayground = ({ onError, schema }: RestPlaygroundProps) => {
<ApiReferenceReact <ApiReferenceReact
configuration={{ configuration={{
spec: { spec: {
url: `${REACT_APP_SERVER_BASE_URL}/open-api/${schema}?token=${playgroundApiKey}`, url: `${REACT_APP_SERVER_BASE_URL}/rest/open-api/${schema}?token=${playgroundApiKey}`,
}, },
authentication: { authentication: {
http: { http: {

View File

@ -28,7 +28,7 @@ export class RestApiCoreController {
private readonly restApiCoreServiceV2: RestApiCoreServiceV2, private readonly restApiCoreServiceV2: RestApiCoreServiceV2,
) {} ) {}
@Post('/duplicates') @Post('duplicates')
@UseFilters(RestApiExceptionFilter) @UseFilters(RestApiExceptionFilter)
async handleApiFindDuplicates(@Req() request: Request, @Res() res: Response) { async handleApiFindDuplicates(@Req() request: Request, @Res() res: Response) {
const result = await this.restApiCoreService.findDuplicates(request); const result = await this.restApiCoreService.findDuplicates(request);

View File

@ -29,7 +29,7 @@ import { BillingWebhookInvoiceService } from 'src/engine/core-modules/billing/we
import { BillingWebhookPriceService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-price.service'; import { BillingWebhookPriceService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-price.service';
import { BillingWebhookProductService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-product.service'; import { BillingWebhookProductService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-product.service';
import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-subscription.service'; import { BillingWebhookSubscriptionService } from 'src/engine/core-modules/billing/webhooks/services/billing-webhook-subscription.service';
@Controller('billing') @Controller()
@UseFilters(BillingRestApiExceptionFilter) @UseFilters(BillingRestApiExceptionFilter)
export class BillingController { export class BillingController {
protected readonly logger = new Logger(BillingController.name); protected readonly logger = new Logger(BillingController.name);
@ -46,7 +46,7 @@ export class BillingController {
private readonly billingWebhookCustomerService: BillingWebhookCustomerService, private readonly billingWebhookCustomerService: BillingWebhookCustomerService,
) {} ) {}
@Post('/webhooks') @Post(['billing/webhooks', 'webhooks/stripe'])
async handleWebhooks( async handleWebhooks(
@Headers('stripe-signature') signature: string, @Headers('stripe-signature') signature: string,
@Req() req: RawBodyRequest<Request>, @Req() req: RawBodyRequest<Request>,

View File

@ -10,24 +10,24 @@ import {
} from '@nestjs/common'; } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm'; import { InjectRepository } from '@nestjs/typeorm';
import { Response, Request } from 'express'; import { Request, Response } from 'express';
import { Repository } from 'typeorm'; import { Repository } from 'typeorm';
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service';
import { CUSTOM_DOMAIN_ACTIVATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/custom-domain/custom-domain-activated';
import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter'; import { AuthRestApiExceptionFilter } from 'src/engine/core-modules/auth/filters/auth-rest-api-exception.filter';
import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { import {
DomainManagerException, DomainManagerException,
DomainManagerExceptionCode, DomainManagerExceptionCode,
} from 'src/engine/core-modules/domain-manager/domain-manager.exception'; } from 'src/engine/core-modules/domain-manager/domain-manager.exception';
import { handleException } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { CloudflareSecretMatchGuard } from 'src/engine/core-modules/domain-manager/guards/cloudflare-secret.guard'; import { CloudflareSecretMatchGuard } from 'src/engine/core-modules/domain-manager/guards/cloudflare-secret.guard';
import { CustomDomainService } from 'src/engine/core-modules/domain-manager/services/custom-domain.service'; import { CustomDomainService } from 'src/engine/core-modules/domain-manager/services/custom-domain.service';
import { AnalyticsService } from 'src/engine/core-modules/analytics/services/analytics.service'; import { DomainManagerService } from 'src/engine/core-modules/domain-manager/services/domain-manager.service';
import { CUSTOM_DOMAIN_ACTIVATED_EVENT } from 'src/engine/core-modules/analytics/utils/events/track/custom-domain/custom-domain-activated'; import { ExceptionHandlerService } from 'src/engine/core-modules/exception-handler/exception-handler.service';
import { handleException } from 'src/engine/core-modules/exception-handler/http-exception-handler.service';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
@Controller('cloudflare') @Controller()
@UseFilters(AuthRestApiExceptionFilter) @UseFilters(AuthRestApiExceptionFilter)
export class CloudflareController { export class CloudflareController {
constructor( constructor(
@ -39,7 +39,7 @@ export class CloudflareController {
private readonly analyticsService: AnalyticsService, private readonly analyticsService: AnalyticsService,
) {} ) {}
@Post('custom-hostname-webhooks') @Post(['cloudflare/custom-hostname-webhooks', 'webhooks/cloudflare'])
@UseGuards(CloudflareSecretMatchGuard) @UseGuards(CloudflareSecretMatchGuard)
async customHostnameWebhooks(@Req() req: Request, @Res() res: Response) { async customHostnameWebhooks(@Req() req: Request, @Res() res: Response) {
if (!req.body?.data?.data?.hostname) { if (!req.body?.data?.data?.hostname) {

View File

@ -24,7 +24,7 @@ export class HealthController {
return this.health.check([]); return this.health.check([]);
} }
@Get('/:indicatorId') @Get(':indicatorId')
@HealthCheck() @HealthCheck()
checkService(@Param('indicatorId') indicatorId: HealthIndicatorId) { checkService(@Param('indicatorId') indicatorId: HealthIndicatorId) {
const checks = { const checks = {

View File

@ -4,11 +4,11 @@ import { Request, Response } from 'express';
import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service'; import { OpenApiService } from 'src/engine/core-modules/open-api/open-api.service';
@Controller('open-api') @Controller()
export class OpenApiController { export class OpenApiController {
constructor(private readonly openApiService: OpenApiService) {} constructor(private readonly openApiService: OpenApiService) {}
@Get('core') @Get(['open-api/core', 'rest/open-api/core'])
async generateOpenApiSchemaCore( async generateOpenApiSchemaCore(
@Req() request: Request, @Req() request: Request,
@Res() res: Response, @Res() res: Response,
@ -18,7 +18,7 @@ export class OpenApiController {
res.send(data); res.send(data);
} }
@Get('metadata') @Get(['open-api/metadata', 'rest/open-api/metadata'])
async generateOpenApiSchemaMetaData( async generateOpenApiSchemaMetaData(
@Req() request: Request, @Req() request: Request,
@Res() res: Response, @Res() res: Response,

View File

@ -1,19 +1,19 @@
import { Controller, Get, Param, Post, Req, UseFilters } from '@nestjs/common'; import { Controller, Get, Param, Post, Req, UseFilters } from '@nestjs/common';
import { isDefined } from 'twenty-shared/utils';
import { Request } from 'express'; import { Request } from 'express';
import { isDefined } from 'twenty-shared/utils';
import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { WorkflowTriggerRestApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-rest-api-exception.filter'; import { WorkflowTriggerRestApiExceptionFilter } from 'src/engine/core-modules/workflow/filters/workflow-trigger-rest-api-exception.filter';
import { FieldActorSource } from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type';
import { TwentyORMManager } from 'src/engine/twenty-orm/twenty-orm.manager';
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
import { import {
WorkflowTriggerException, WorkflowTriggerException,
WorkflowTriggerExceptionCode, WorkflowTriggerExceptionCode,
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception'; } from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type'; import { WorkflowTriggerType } from 'src/modules/workflow/workflow-trigger/types/workflow-trigger.type';
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; import { WorkflowTriggerWorkspaceService } from 'src/modules/workflow/workflow-trigger/workspace-services/workflow-trigger.workspace-service';
@Controller('webhooks') @Controller('webhooks')
@UseFilters(WorkflowTriggerRestApiExceptionFilter) @UseFilters(WorkflowTriggerRestApiExceptionFilter)

View File

@ -18,7 +18,7 @@ describe('BillingController (integration)', () => {
}; };
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
@ -29,7 +29,7 @@ describe('BillingController (integration)', () => {
}); });
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
@ -51,7 +51,7 @@ describe('BillingController (integration)', () => {
}; };
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
@ -63,7 +63,7 @@ describe('BillingController (integration)', () => {
}); });
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
@ -83,7 +83,7 @@ describe('BillingController (integration)', () => {
}; };
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'correct-signature') .set('stripe-signature', 'correct-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')
@ -102,7 +102,7 @@ describe('BillingController (integration)', () => {
}; };
await client await client
.post('/billing/webhooks') .post('/webhooks/stripe')
.set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`) .set('Authorization', `Bearer ${ADMIN_ACCESS_TOKEN}`)
.set('stripe-signature', 'invalid-signature') .set('stripe-signature', 'invalid-signature')
.set('Content-Type', 'application/json') .set('Content-Type', 'application/json')