Skip to content

Commit 5b58fb4

Browse files
author
Umed Khudoiberdiev
committed
initial commit
0 parents  commit 5b58fb4

14 files changed

+251
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules
2+
src/**/*.js
3+
src/**/*.js.map

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Example how to use Express and TypeORM with TypeScript
2+
3+
1. clone repository
4+
2. run `npm i`
5+
3. edit `ormconfig.json` and change your database configuration (you can also change a database type, but don't forget to install specific database drivers)
6+
4. run `npm start`
7+
5. open `http://localhost:3000/posts` and you'll empty array
8+
6. use curl, postman or other tools to send http requests to test your typeorm-based API
9+
10+
## How to use CLI?
11+
12+
1. install `typeorm` globally: `npm i -g typeorm`
13+
2. run `typeorm -h` to show list of available commands

ormconfig.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
[
2+
{
3+
"name": "default",
4+
"driver": {
5+
"type": "mysql",
6+
"host": "localhost",
7+
"port": 3306,
8+
"username": "test",
9+
"password": "test",
10+
"database": "test"
11+
},
12+
"autoSchemaSync": true,
13+
"entities": [
14+
"src/entity/*.js"
15+
],
16+
"subscribers": [
17+
"src/subscriber/*.js,"
18+
],
19+
"migrations": [
20+
"src/migration/*.js"
21+
],
22+
"cli": {
23+
"entitiesDir": "src/entity",
24+
"migrationsDir": "src/migration",
25+
"subscribersDir": "src/subscriber"
26+
}
27+
}
28+
]

package.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "typeorm-typescript-express-example",
3+
"version": "0.0.1",
4+
"description": "Example how to use Express and TypeORM with TypeScript.",
5+
"license": "MIT",
6+
"readmeFilename": "README.md",
7+
"author": {
8+
"name": "Umed Khudoiberdiev",
9+
"email": "pleerock.me@gmail.com"
10+
},
11+
"repository": {
12+
"type": "git",
13+
"url": "https://github.com/typeorm/typescript-express-example.git"
14+
},
15+
"bugs": {
16+
"url": "https://github.com/typeorm/typescript-express-example/issues"
17+
},
18+
"tags": [
19+
"orm",
20+
"typescript",
21+
"typescript-orm",
22+
"typeorm-sample",
23+
"typeorm-example",
24+
"typeorm-express-example"
25+
],
26+
"devDependencies": {
27+
"@types/body-parser": "^1.16.0",
28+
"express": "^4.15.2",
29+
"typescript": "^2.1.5"
30+
},
31+
"dependencies": {
32+
"@types/express": "^4.0.35",
33+
"@types/node": "^7.0.4",
34+
"body-parser": "^1.17.1",
35+
"mysql": "^2.12.0",
36+
"reflect-metadata": "^0.1.9",
37+
"typeorm": "0.0.9"
38+
},
39+
"scripts": {
40+
"start": "tsc && node src/index.js"
41+
}
42+
}

src/controller/PostGetAllAction.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {Request, Response} from "express";
2+
import {getEntityManager} from "typeorm";
3+
import {Post} from "../entity/Post";
4+
5+
/**
6+
* Loads all posts from the database.
7+
*/
8+
export async function postGetAllAction(request: Request, response: Response) {
9+
10+
// get a post repository to perform operations with post
11+
const postRepository = getEntityManager().getRepository(Post);
12+
13+
// load a post by a given post id
14+
const posts = await postRepository.find();
15+
16+
// return loaded posts
17+
response.send(posts);
18+
}

src/controller/PostGetByIdAction.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {Request, Response} from "express";
2+
import {getEntityManager} from "typeorm";
3+
import {Post} from "../entity/Post";
4+
5+
/**
6+
* Loads post by a given id.
7+
*/
8+
export async function postGetByIdAction(request: Request, response: Response) {
9+
10+
// get a post repository to perform operations with post
11+
const postRepository = getEntityManager().getRepository(Post);
12+
13+
// load a post by a given post id
14+
const post = await postRepository.findOneById(request.params.id);
15+
16+
// if post was not found return 404 to the client
17+
if (!post) {
18+
response.status(404);
19+
response.end();
20+
}
21+
22+
// return loaded post
23+
response.send(post);
24+
}

src/controller/PostSaveAction.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {Request, Response} from "express";
2+
import {getEntityManager} from "typeorm";
3+
import {Post} from "../entity/Post";
4+
5+
/**
6+
* Saves given post.
7+
*/
8+
export async function postSaveAction(request: Request, response: Response) {
9+
10+
// get a post repository to perform operations with post
11+
const postRepository = getEntityManager().getRepository(Post);
12+
13+
// create a real post object from post json object sent over http
14+
const newPost = postRepository.create(request.body);
15+
16+
// save received post
17+
await postRepository.persist(newPost);
18+
19+
// return saved post back
20+
response.send(newPost);
21+
}

src/entity/Category.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import {Table, PrimaryColumn, Column} from "typeorm";
2+
3+
@Table()
4+
export class Category {
5+
6+
@PrimaryColumn("int", { generated: true })
7+
id: number;
8+
9+
@Column()
10+
name: string;
11+
12+
}

src/entity/Post.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import {Table, PrimaryColumn, Column, ManyToMany, JoinTable} from "typeorm";
2+
import {Category} from "./Category";
3+
4+
@Table()
5+
export class Post {
6+
7+
@PrimaryColumn("int", { generated: true })
8+
id: number;
9+
10+
@Column()
11+
title: string;
12+
13+
@Column("text")
14+
text: string;
15+
16+
@ManyToMany(type => Category, {
17+
cascadeInsert: true
18+
})
19+
@JoinTable()
20+
categories: Category[];
21+
22+
}

src/index.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import "reflect-metadata";
2+
import {createConnection} from "typeorm";
3+
import {Request, Response} from "express";
4+
import * as express from "express";
5+
import * as bodyParser from "body-parser";
6+
import {ROUTES} from "./routes";
7+
8+
// create connection with database
9+
// note that its not active database connection
10+
// TypeORM creates you connection pull to uses connections from pull on your requests
11+
createConnection().then(async connection => {
12+
13+
// create express app
14+
const app = express();
15+
app.use(bodyParser.json());
16+
17+
// register all routes
18+
ROUTES.forEach(route => {
19+
app[route.method](route.path, (request: Request, response: Response, next: Function) => {
20+
route.action(request, response)
21+
.then(() => next)
22+
.catch(err => next(err));
23+
});
24+
});
25+
26+
// run app
27+
app.listen(3000);
28+
29+
}).catch(error => console.log("Error: ", error));

src/migration/.gitkeep

Whitespace-only changes.

src/routes.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {postGetAllAction} from "./controller/PostGetAllAction";
2+
import {postGetByIdAction} from "./controller/PostGetByIdAction";
3+
import {postSaveAction} from "./controller/PostSaveAction";
4+
5+
/**
6+
* All application routes.
7+
*/
8+
export const ROUTES = [
9+
{
10+
path: "/posts",
11+
method: "get",
12+
action: postGetAllAction
13+
},
14+
{
15+
path: "/posts/:id",
16+
method: "get",
17+
action: postGetByIdAction
18+
},
19+
{
20+
path: "/posts",
21+
method: "post",
22+
action: postSaveAction
23+
}
24+
];

src/subscriber/.gitkeep

Whitespace-only changes.

tsconfig.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"version": "2.0.2",
3+
"compilerOptions": {
4+
"lib": ["es5", "es6"],
5+
"target": "es6",
6+
"module": "commonjs",
7+
"moduleResolution": "node",
8+
"emitDecoratorMetadata": true,
9+
"experimentalDecorators": true,
10+
"sourceMap": true
11+
},
12+
"exclude": [
13+
"node_modules"
14+
]
15+
}

0 commit comments

Comments
 (0)