Skip to content

Commit

Permalink
chore(api): documente l'API avec OpenApi
Browse files Browse the repository at this point in the history
  • Loading branch information
vmaubert committed Dec 16, 2024
1 parent fffc37c commit 88aeeef
Show file tree
Hide file tree
Showing 8 changed files with 711 additions and 14 deletions.
594 changes: 581 additions & 13 deletions frontend/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"i18next": "^23.10.0",
"lodash": "^4.17.21",
"maplibre-gl": "^4.1.2",
"openapi-explorer": "^2.2.732",
"react": "^18.2.0",
"react-app-alias-ex": "^2.1.0",
"react-dom": "^18.2.0",
Expand Down
9 changes: 8 additions & 1 deletion frontend/src/hooks/useAuthentication.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import HomeView from 'src/views/HomeView/HomeView';
import PrescriptionListView from 'src/views/PrescriptionListView/PrescriptionListView';
import SampleListView from 'src/views/SampleListView/SampleListView';
import SampleView from 'src/views/SampleView/SampleView';
import { OpenApiExplorerView } from 'src/views/OpenApiExplorer/OpenApiExplorer';

export const useAuthentication = () => {
const { authUser } = useAppSelector((state) => state.auth);
Expand Down Expand Up @@ -130,7 +131,13 @@ export const useAuthentication = () => {
label: 'Documents ressources',
key: 'documents_route',
component: DocumentListView
}
},
{
path:'/apiDocs',
label: 'API Docs',
key:'api_docs',
component: OpenApiExplorerView
}
]
: [
{
Expand Down
36 changes: 36 additions & 0 deletions frontend/src/views/OpenApiExplorer/OpenApiExplorer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'openapi-explorer';
import React, { useEffect } from 'react';
// @ts-expect-error TS7016
import {reactEventListener} from 'openapi-explorer/dist/es/react'
import { authParams } from 'src/services/auth-headers';
import config from 'src/utils/config';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace JSX {
interface IntrinsicElements {
'openapi-explorer': React.DetailedHTMLProps<
React.HTMLAttributes<HTMLElement>,
HTMLElement
>;
}
}
}
export const OpenApiExplorerView = () => {


const onRequestFunction = (data: {detail: { request: {headers: Record<string, string>}}}) => {
data.detail.request.headers = { ...data.detail.request.headers, ...authParams()}
};

// Necessary because react by default does not know how to listen to HTML5 events
reactEventListener({ useEffect }, 'request', onRequestFunction);
return (
<openapi-explorer
hide-server-selection={true}
hide-authentication={true}
spec-url={`${config.apiEndpoint}/api/api-docs`}
server-url={`${config.apiEndpoint}/api`}
/>
);
};
35 changes: 35 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"npm": "10"
},
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.0",
"@aws-sdk/client-s3": "^3.624.0",
"@aws-sdk/s3-request-presigner": "^3.624.0",
"@faker-js/faker": "^8.2.0",
Expand Down Expand Up @@ -63,6 +64,7 @@
"lodash": "^4.17.21",
"node-fetch": "^2.6.7",
"nodemailer": "^6.9.13",
"openapi3-ts": "^4.4.0",
"pg": "^8.13.1",
"puppeteer": "^22.11.2",
"randomstring": "^1.2.1",
Expand Down
42 changes: 42 additions & 0 deletions server/apidoc/openapi-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { OpenApiBuilder, OpenAPIObject } from 'openapi3-ts/oas31';
import { extendZodWithOpenApi, OpenApiGeneratorV31, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
import { UserInfos } from '../../shared/schema/User/User';
import { z } from 'zod';
extendZodWithOpenApi(z);
export const getOpenApiSchema = (): OpenAPIObject =>{
const registry = new OpenAPIRegistry();

registry.register('User', UserInfos)

//FIXME utiliser le register ?!
//FIXME supprimer OpenApiBuilder ?!
const openApiGenerator = new OpenApiGeneratorV31(registry.definitions)
const compo = openApiGenerator.generateComponents()

const builder = OpenApiBuilder.create().addOpenApiVersion('3.1.0')
.addTitle('Maestro API')
.addPath('/users/{userId}/infos', {
get: {
summary: "Trouve un utilisateur par son id",
operationId: "getUserById" ,
parameters:[
{
"name": "userId",
"in": "path",
"required": true,
"description": "L'identifiant de l'utilisateur",
"schema": {
"type": "string"
}
}
],
}
})
.getSpec()




return {...builder, ...compo}

}
6 changes: 6 additions & 0 deletions server/routers/unprotected.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,17 @@ import { SignIn } from '../../shared/schema/SignIn';
import accountController from '../controllers/accountController';
import { jwtCheck, userCheck } from '../middlewares/checks/authCheck';
import validator, { body } from '../middlewares/validator';
import { getOpenApiSchema } from '../apidoc/openapi-schema';

const router = express.Router();
router.use(jwtCheck(false));
router.use(userCheck(false));

router.get('/api-docs', (_req, res) => {
res.setHeader('Content-Type', 'application/json');
res.json(getOpenApiSchema())
})

router.post(
'/accounts/sign-in',
validator.validate(body(SignIn)),
Expand Down

0 comments on commit 88aeeef

Please sign in to comment.