-
Notifications
You must be signed in to change notification settings - Fork 1
03 API Structure
JP Barbosa edited this page Apr 15, 2023
·
1 revision
code .env.example
PORT=3333
VITE_API_URL=http://localhost:3333
NEO4J_URL=bolt://localhost:7687
NEO4J_DATABASE=neo4j
NEO4J_USERNAME=
NEO4J_PASSWORD=
echo ".env" >> .gitignore
cp .env.example .env
code ./packages/shared/src/types/ApiError.ts
import { AxiosError } from 'axios';
export type ApiError = {
error: string;
};
export type AxiosCustomError = AxiosError<ApiError>;
code ./packages/shared/src/types/AppResponse.ts
import { Response } from 'express';
import { ApiError } from './ApiError';
type ResponseBody<T> = ApiError | T;
export type AppResponse<T> = Response<ResponseBody<T>>;
code ./packages/shared/src/types/index.ts
...
export * from './ApiError';
export * from './AppResponse';
code ./packages/api/src/global.d.ts
declare global {
namespace Express {
interface Request {
neo4jSession?: import('neo4j-driver').Session;
}
}
}
export {};
code ./packages/api/src/config/index.ts
import dotenv from 'dotenv';
dotenv.config();
const { NEO4J_URL, NEO4J_USERNAME, NEO4J_PASSWORD, NEO4J_DATABASE } =
process.env;
export const config = {
neo4j: {
url: NEO4J_URL,
username: NEO4J_USERNAME,
password: NEO4J_PASSWORD,
database: NEO4J_DATABASE,
},
};
code ./packages/api/src/middleware/errorHandler.ts
import { NextFunction, Request } from 'express';
import { Neo4jError } from 'neo4j-driver';
import { AppResponse } from '@neo4j-crud/shared';
export const errorHandler = (
err: Neo4jError,
req: Request,
res: AppResponse<any>,
next: NextFunction
) => {
console.error(err);
res.status(500).send({ error: err.code });
};
code ./packages/api/src/middleware/neo4jSession.ts
import { Request, Response, NextFunction } from 'express';
import neo4j from 'neo4j-driver';
import { config } from '../config';
export const neo4jSession = (
req: Request,
res: Response,
next: NextFunction
) => {
const { url, username, password, database } = config.neo4j;
const auth = neo4j.auth.basic(username, password);
const driver = neo4j.driver(url, auth, {
disableLosslessIntegers: true,
});
const session = driver.session({
database,
});
req.neo4jSession = session;
res.on('finish', () => {
session.close();
});
next();
};
code ./packages/api/src/middleware/index.ts
export * from './errorHandler';
export * from './neo4jSession';
code ./packages/api/src/controllers/movies.ts
import { NextFunction } from 'express';
import { AppResponse, Movie } from '@neo4j-crud/shared';
import * as graph from '@neo4j-crud/graph';
export const moviesController = {
getAll: async (req, res: AppResponse<Movie[]>, next: NextFunction) => {
try {
const movies = await graph.movies(req.neo4jSession).getAll();
res.send(movies);
} catch (err) {
next(err);
}
},
getById: async (req, res: AppResponse<string>, next: NextFunction) => {
res.send('To be implemented');
},
create: async (req, res: AppResponse<string>, next: NextFunction) => {
res.send('To be implemented');
},
update: async (req, res: AppResponse<string>, next: NextFunction) => {
res.send('To be implemented');
},
remove: async (req, res: AppResponse<string>, next: NextFunction) => {
res.send('To be implemented');
},
};
code ./packages/api/src/controllers/index.ts
export * from './movies';
code ./packages/api/src/routes/movies.ts
import { Router } from 'express';
import { moviesController } from '../controllers';
const router = Router();
router.get('/', moviesController.getAll);
router.get('/:id', moviesController.getById);
router.post('/', moviesController.create);
router.put('/:id', moviesController.update);
router.delete('/:id', moviesController.remove);
export default router;
code ./packages/api/src/routes/index.ts
import { Router } from 'express';
import moviesRouter from './movies';
const routers = Router();
routers.use('/movies', moviesRouter);
export default routers;
code ./packages/api/src/main.ts
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import routers from './routes';
import { errorHandler, neo4jSession } from './middleware';
const app = express();
app.use(bodyParser.json());
app.use(cors());
app.use(neo4jSession);
app.use(routers);
app.use(errorHandler);
const port = process.env.PORT || 3333;
const server = app.listen(port, () => {
console.log(`Listening at http://localhost:${port}`);
});
server.on('error', console.error);
nx run-many --target=serve --all
open http://localhost:3333/movies
[
{
"tagline": "In the heart of the nation's capital, in a courthouse of the U.S. government...",
"id": 198,
"title": "A Few Good Men",
"released": 1992,
},
...
]
git add .
git commit -m "API Structure"