mirror of
https://github.com/twentyhq/twenty.git
synced 2024-11-23 22:12:24 +03:00
3035 improve rest api syntax (#3047)
This commit is contained in:
parent
b36d86e52c
commit
576492f3c0
@ -19,7 +19,7 @@ if needed.
|
||||
## Programmatic use?
|
||||
|
||||
You can call the REST API in your application using this endpoint
|
||||
[https://api.twenty.com](https://api.twenty.com).
|
||||
[https://api.twenty.com/rest](https://api.twenty.com/rest).
|
||||
You will need to provide your API key as a Bearer token in
|
||||
your `headers.Authorization = 'Bearer <YOUR_API_KEY>'`.
|
||||
|
||||
|
@ -33,7 +33,7 @@ export const mapFieldMetadataToGraphqlQuery = (
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id ===
|
||||
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
||||
(field.toRelationMetadata as any)?.fromObjectMetadataId,
|
||||
);
|
||||
|
||||
return `${field.name}
|
||||
@ -58,7 +58,7 @@ export const mapFieldMetadataToGraphqlQuery = (
|
||||
const relationMetadataItem = objectMetadataItems.find(
|
||||
(objectMetadataItem) =>
|
||||
objectMetadataItem.id ===
|
||||
(field.fromRelationMetadata as any)?.toObjectMetadata?.id,
|
||||
(field.fromRelationMetadata as any)?.toObjectMetadataId,
|
||||
);
|
||||
|
||||
return `${field.name}
|
||||
|
@ -3,17 +3,7 @@ import { Controller, Delete, Get, Post, Put, Req, Res } from '@nestjs/common';
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
import { ApiRestService } from 'src/core/api-rest/api-rest.service';
|
||||
import { ApiRestResponse } from 'src/core/api-rest/types/api-rest-response.type';
|
||||
|
||||
const handleResult = (res: Response, result: ApiRestResponse) => {
|
||||
if (result.data.error) {
|
||||
res
|
||||
.status(result.data.status || 400)
|
||||
.send({ error: `${result.data.error}` });
|
||||
} else {
|
||||
res.send(result.data);
|
||||
}
|
||||
};
|
||||
import { handleResult } from 'src/core/api-rest/api-rest.controller.utils';
|
||||
|
||||
@Controller('rest/*')
|
||||
export class ApiRestController {
|
||||
|
@ -0,0 +1,53 @@
|
||||
import { cleanGraphQLResponse } from 'src/core/api-rest/api-rest.controller.utils';
|
||||
|
||||
describe('cleanGraphQLResponse', () => {
|
||||
it('should remove edges/node from results', () => {
|
||||
const data = {
|
||||
companies: {
|
||||
edges: [
|
||||
{
|
||||
node: { id: 'id', createdAt: '2023-01-01' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const expectedResult = {
|
||||
companies: [{ id: 'id', createdAt: '2023-01-01' }],
|
||||
};
|
||||
|
||||
expect(cleanGraphQLResponse(data)).toEqual(expectedResult);
|
||||
});
|
||||
it('should remove nested edges/node from results', () => {
|
||||
const data = {
|
||||
companies: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'id',
|
||||
createdAt: '2023-01-01',
|
||||
people: {
|
||||
edges: [{ node: { id: 'id1' } }, { node: { id: 'id2' } }],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const expectedResult = {
|
||||
companies: [
|
||||
{
|
||||
id: 'id',
|
||||
createdAt: '2023-01-01',
|
||||
people: [{ id: 'id1' }, { id: 'id2' }],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
expect(cleanGraphQLResponse(data)).toEqual(expectedResult);
|
||||
});
|
||||
it('should not format when no list returned', () => {
|
||||
const data = { company: { id: 'id' } };
|
||||
|
||||
expect(cleanGraphQLResponse(data)).toEqual(data);
|
||||
});
|
||||
});
|
@ -0,0 +1,36 @@
|
||||
import { Response } from 'express';
|
||||
|
||||
import { ApiRestResponse } from 'src/core/api-rest/types/api-rest-response.type';
|
||||
|
||||
// https://gist.github.com/ManUtopiK/469aec75b655d6a4d912aeb3b75af3c9
|
||||
export const cleanGraphQLResponse = (input) => {
|
||||
if (!input) return null;
|
||||
const output = {};
|
||||
const isObject = (obj) => {
|
||||
return obj !== null && typeof obj === 'object' && !Array.isArray(obj);
|
||||
};
|
||||
|
||||
Object.keys(input).forEach((key) => {
|
||||
if (input[key] && input[key].edges) {
|
||||
output[key] = input[key].edges.map((edge) =>
|
||||
cleanGraphQLResponse(edge.node),
|
||||
);
|
||||
} else if (isObject(input[key])) {
|
||||
output[key] = cleanGraphQLResponse(input[key]);
|
||||
} else if (key !== '__typename') {
|
||||
output[key] = input[key];
|
||||
}
|
||||
});
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
export const handleResult = (res: Response, result: ApiRestResponse) => {
|
||||
if (result.data.error) {
|
||||
res
|
||||
.status(result.data.status || 400)
|
||||
.send({ error: `${result.data.error}` });
|
||||
} else {
|
||||
res.send(cleanGraphQLResponse(result.data));
|
||||
}
|
||||
};
|
@ -13,21 +13,11 @@ export const getManyResultResponse200 = (item: ObjectMetadataEntity) => {
|
||||
type: 'object',
|
||||
properties: {
|
||||
[item.namePlural]: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
edges: {
|
||||
type: 'array',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
node: {
|
||||
$ref: `#/components/schemas/${capitalize(
|
||||
item.nameSingular,
|
||||
)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
type: 'array',
|
||||
items: {
|
||||
$ref: `#/components/schemas/${capitalize(
|
||||
item.nameSingular,
|
||||
)}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -35,16 +25,10 @@ export const getManyResultResponse200 = (item: ObjectMetadataEntity) => {
|
||||
},
|
||||
example: {
|
||||
data: {
|
||||
properties: {
|
||||
[item.namePlural]: {
|
||||
edges: [
|
||||
{
|
||||
node: `${capitalize(item.nameSingular)}Object`,
|
||||
},
|
||||
'...',
|
||||
],
|
||||
},
|
||||
},
|
||||
[item.namePlural]: [
|
||||
`${capitalize(item.nameSingular)}Object`,
|
||||
'...',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user