3035 improve rest api syntax (#3047)
This commit is contained in:
@ -19,7 +19,7 @@ if needed.
|
|||||||
## Programmatic use?
|
## Programmatic use?
|
||||||
|
|
||||||
You can call the REST API in your application using this endpoint
|
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
|
You will need to provide your API key as a Bearer token in
|
||||||
your `headers.Authorization = 'Bearer <YOUR_API_KEY>'`.
|
your `headers.Authorization = 'Bearer <YOUR_API_KEY>'`.
|
||||||
|
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export const mapFieldMetadataToGraphqlQuery = (
|
|||||||
const relationMetadataItem = objectMetadataItems.find(
|
const relationMetadataItem = objectMetadataItems.find(
|
||||||
(objectMetadataItem) =>
|
(objectMetadataItem) =>
|
||||||
objectMetadataItem.id ===
|
objectMetadataItem.id ===
|
||||||
(field.toRelationMetadata as any)?.fromObjectMetadata?.id,
|
(field.toRelationMetadata as any)?.fromObjectMetadataId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return `${field.name}
|
return `${field.name}
|
||||||
@ -58,7 +58,7 @@ export const mapFieldMetadataToGraphqlQuery = (
|
|||||||
const relationMetadataItem = objectMetadataItems.find(
|
const relationMetadataItem = objectMetadataItems.find(
|
||||||
(objectMetadataItem) =>
|
(objectMetadataItem) =>
|
||||||
objectMetadataItem.id ===
|
objectMetadataItem.id ===
|
||||||
(field.fromRelationMetadata as any)?.toObjectMetadata?.id,
|
(field.fromRelationMetadata as any)?.toObjectMetadataId,
|
||||||
);
|
);
|
||||||
|
|
||||||
return `${field.name}
|
return `${field.name}
|
||||||
|
|||||||
@ -3,17 +3,7 @@ import { Controller, Delete, Get, Post, Put, Req, Res } from '@nestjs/common';
|
|||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
|
||||||
import { ApiRestService } from 'src/core/api-rest/api-rest.service';
|
import { ApiRestService } from 'src/core/api-rest/api-rest.service';
|
||||||
import { ApiRestResponse } from 'src/core/api-rest/types/api-rest-response.type';
|
import { handleResult } from 'src/core/api-rest/api-rest.controller.utils';
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@Controller('rest/*')
|
@Controller('rest/*')
|
||||||
export class ApiRestController {
|
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',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
[item.namePlural]: {
|
[item.namePlural]: {
|
||||||
type: 'object',
|
type: 'array',
|
||||||
properties: {
|
items: {
|
||||||
edges: {
|
$ref: `#/components/schemas/${capitalize(
|
||||||
type: 'array',
|
item.nameSingular,
|
||||||
items: {
|
)}`,
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
node: {
|
|
||||||
$ref: `#/components/schemas/${capitalize(
|
|
||||||
item.nameSingular,
|
|
||||||
)}`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -35,16 +25,10 @@ export const getManyResultResponse200 = (item: ObjectMetadataEntity) => {
|
|||||||
},
|
},
|
||||||
example: {
|
example: {
|
||||||
data: {
|
data: {
|
||||||
properties: {
|
[item.namePlural]: [
|
||||||
[item.namePlural]: {
|
`${capitalize(item.nameSingular)}Object`,
|
||||||
edges: [
|
'...',
|
||||||
{
|
],
|
||||||
node: `${capitalize(item.nameSingular)}Object`,
|
|
||||||
},
|
|
||||||
'...',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user