Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7f5f395

Browse files
committed
update typescript example project
1 parent 6de2529 commit 7f5f395

File tree

9 files changed

+117
-99
lines changed

9 files changed

+117
-99
lines changed

examples/express-ts/example-requests.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ curl -H "Content-Type: application/json" -d '{"firstName":"Jennifer", "lastName"
1111
curl -H "Content-Type: application/json" -d '{"firstName":"Bradley", "lastName":"Cooper", "age":40}' http://localhost:8641/persons
1212
curl -H "Content-Type: application/json" -d '{"firstName":"Sylvester", "lastName":"Stallone", "age":68}' http://localhost:8641/persons
1313

14+
# Relations can be sent along with the people.
15+
curl -H "Content-Type: application/json" -d '{"firstName":"Matt", "lastName":"Damon", "age":42, "parent": {"firstName": "Kent", "lastName": "Damon", "age": 70}}' http://localhost:8641/persons
16+
1417
# Add a child for Sylvester.
1518
curl -H "Content-Type: application/json" -d '{"firstName":"Sage", "lastName":"Stallone", "age":36}' http://localhost:8641/persons/3/children
1619

examples/express-ts/knexfile.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
module.exports = {
2-
32
development: {
43
client: 'sqlite3',
54
useNullAsDefault: true,
@@ -18,5 +17,4 @@ module.exports = {
1817
max: 10
1918
}
2019
}
21-
2220
};

examples/express-ts/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "objection-example-express-ts",
3-
"version": "0.6.1",
3+
"version": "0.7.0",
44
"description": "Objection.js express TypeScript example",
55
"main": "app.js",
66
"scripts": {
@@ -16,10 +16,11 @@
1616
"dependencies": {
1717
"body-parser": "^1.16.1",
1818
"express": "^4.14.1",
19+
"express-promise-router": "^1.1.1",
1920
"knex": "^0.12.7",
2021
"lodash": "^4.17.4",
2122
"morgan": "^1.8.1",
22-
"objection": "../..",
23+
"objection": "^0.7.0",
2324
"sqlite3": "^3.1.8"
2425
},
2526
"devDependencies": {

examples/express-ts/src/api.ts

Lines changed: 68 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -4,170 +4,168 @@ import * as express from 'express';
44
import Person from './models/Person';
55
import Movie from './models/Movie';
66

7-
export default function (app: express.Application) {
7+
export default function (router: express.Router) {
88

99
// Create a new Person.
10-
app.post('/persons', function (req, res, next) {
11-
return Person
10+
router.post('/persons', async (req, res) => {
11+
const person = await Person
1212
.query()
13-
.insert(req.body)
14-
.then(person => res.send(person))
15-
.catch(next);
13+
.allowInsert('[pets, children.[pets, movies], movies, parent]')
14+
.insertGraph(req.body);
15+
16+
res.send(person);
1617
});
1718

1819
// Patch a Person.
19-
app.patch('/persons/:id', function (req, res, next) {
20-
return Person
20+
router.patch('/persons/:id', async (req, res) => {
21+
const person = await Person
2122
.query()
22-
.patchAndFetchById(req.params.id, req.body)
23-
.then(person => res.send(person))
24-
.catch(next);
23+
.patchAndFetchById(req.params.id, req.body);
24+
25+
res.send(person);
2526
});
2627

2728
// Get all Persons. The result can be filtered using query parameters
2829
// `minAge`, `maxAge` and `firstName`. Relations can be fetched eagerly
2930
// by giving a relation expression as the `eager` query parameter.
30-
app.get('/persons', function (req, res, next) {
31+
router.get('/persons', async (req, res) => {
3132
// We don't need to check for the existence of the query parameters because
3233
// we call the `skipUndefined` method. It causes the query builder methods
3334
// to do nothing if one of the values is undefined.
34-
return Person
35+
const persons = await Person
3536
.query()
3637
.allowEager('[pets, children.[pets, movies], movies]')
3738
.eager(req.query.eager)
3839
.skipUndefined()
3940
.where('age', '>=', req.query.minAge)
4041
.where('age', '<', req.query.maxAge)
41-
.where('firstName', 'like', req.query.firstName)
42-
.then(persons => res.send(persons))
43-
.catch(next);
42+
.where('firstName', 'like', req.query.firstName);
43+
44+
res.send(persons);
4445
});
4546

4647
// Delete a person.
47-
app.delete('/persons/:id', function (req, res, next) {
48-
return Person
48+
router.delete('/persons/:id', async (req, res) => {
49+
await Person
4950
.query()
5051
.delete()
51-
.where('id', req.params.id)
52-
.then(() => res.send({}))
53-
.catch(next);
52+
.where('id', req.params.id);
53+
54+
res.send({});
5455
});
5556

5657
// Add a child for a Person.
57-
app.post('/persons/:id/children', async function (req, res, next) {
58+
router.post('/persons/:id/children', async (req, res) => {
5859
const person = await Person
5960
.query()
60-
.findById(req.params.id)
61-
.catch(next);
61+
.findById(req.params.id);
6262

6363
if (!person) {
64-
res.sendStatus(404);
64+
throwNotFound();
6565
} else {
66-
await person
66+
const child = await person
6767
.$relatedQuery('children')
68-
.insert(req.body)
69-
.then(child => res.send(child))
70-
.catch(next);
68+
.insert(req.body);
69+
70+
res.send(child);
7171
}
7272
});
7373

7474
// Add a pet for a Person.
75-
app.post('/persons/:id/pets', async function (req, res, next) {
75+
router.post('/persons/:id/pets', async (req, res) => {
7676
const person = await Person
7777
.query()
78-
.findById(req.params.id)
79-
.catch(next);
78+
.findById(req.params.id);
8079

8180
if (!person) {
82-
res.sendStatus(404);
81+
throwNotFound();
8382
} else {
84-
await person
83+
const pet = await person
8584
.$relatedQuery('pets')
86-
.insert(req.body)
87-
.then(pet => res.send(pet))
88-
.catch(next);
85+
.insert(req.body);
86+
87+
res.send(pet);
8988
}
9089
});
9190

9291
// Get a Person's pets. The result can be filtered using query parameters
9392
// `name` and `species`.
94-
app.get('/persons/:id/pets', async function (req, res, next) {
93+
router.get('/persons/:id/pets', async (req, res) => {
9594
const person = await Person
9695
.query()
97-
.findById(req.params.id)
98-
.catch(next);
96+
.findById(req.params.id);
9997

10098
if (!person) {
101-
res.sendStatus(404);
99+
throwNotFound();
102100
} else {
103-
104101
// We don't need to check for the existence of the query parameters because
105102
// we call the `skipUndefined` method. It causes the query builder methods
106103
// to do nothing if one of the values is undefined.
107-
return person
104+
const pets = await person
108105
.$relatedQuery('pets')
109106
.skipUndefined()
110107
.where('name', 'like', req.query.name)
111-
.where('species', req.query.species)
112-
.then(pets => res.send(pets))
113-
.catch(next);
108+
.where('species', req.query.species);
109+
110+
res.send(pets);
114111
}
115112
});
116113

117114
// Add a movie for a Person.
118-
app.post('/persons/:id/movies', function (req, res, next) {
115+
router.post('/persons/:id/movies', async (req, res) => {
119116
// Inserting a movie for a person creates two queries: the movie insert query
120117
// and the join table row insert query. It is wise to use a transaction here.
121-
return objection.transaction(Person, async (Person) => {
118+
const movie = await objection.transaction(Person, async (Person) => {
122119
const person = await Person
123120
.query()
124-
.findById(req.params.id)
125-
.catch(next);
121+
.findById(req.params.id);
126122

127123
if (!person) {
128-
res.sendStatus(404);
124+
return throwNotFound();
129125
} else {
130-
await person
126+
return person
131127
.$relatedQuery('movies')
132-
.insert(req.body)
133-
.then(movie => res.send(movie))
134-
.catch(next);
128+
.insert(req.body);
135129
}
136130
});
131+
132+
res.send(movie);
137133
});
138134

139135
// Add existing Person as an actor to a movie.
140-
app.post('/movies/:id/actors', async function (req, res, next) {
136+
router.post('/movies/:id/actors', async (req, res) => {
141137
const movie = await Movie
142138
.query()
143-
.findById(req.params.id)
144-
.catch(next);
139+
.findById(req.params.id);
145140

146141
if (!movie) {
147-
res.sendStatus(404);
142+
throwNotFound();
148143
} else {
149144
await movie
150145
.$relatedQuery('actors')
151-
.relate(req.body.id)
152-
.then(() => res.send(req.body))
153-
.catch(next);
146+
.relate(req.body.id);
147+
148+
res.send(req.body);
154149
}
155150
});
156151

157152
// Get Movie's actors.
158-
app.get('/movies/:id/actors', async function (req, res, next) {
153+
router.get('/movies/:id/actors', async (req, res) => {
159154
const movie = await Movie
160155
.query()
161-
.findById(req.params.id)
162-
.catch(next);
156+
.findById(req.params.id);
163157

164158
if (!movie) {
165-
res.sendStatus(404);
159+
throwNotFound();
166160
} else {
167-
await movie
168-
.$relatedQuery('actors')
169-
.then(movie => res.send(movie))
170-
.catch(next);
161+
const actors = await movie.$relatedQuery('actors');
162+
res.send(actors);
171163
}
172164
});
173165
};
166+
167+
function throwNotFound() {
168+
const err: any = new Error();
169+
err.statusCode = 404;
170+
throw err;
171+
}

examples/express-ts/src/app.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import registerApi from './api';
77
import { Model } from 'objection';
88

99
const knexConfig = require('../knexfile');
10+
const promiseRouter = require('express-promise-router');
1011

1112
// Initialize knex.
1213
export const knex = Knex(knexConfig.development);
@@ -19,13 +20,15 @@ knex.migrate.latest();
1920
// the Model.bindKnex method.
2021
Model.knex(knex);
2122

23+
const router: express.Router = promiseRouter();
2224
const app: express.Application = express()
2325
.use(bodyParser.json())
2426
.use(morgan('dev'))
27+
.use(router)
2528
.set('json spaces', 2);
2629

2730
// Register our REST API.
28-
registerApi(app);
31+
registerApi(router);
2932

3033
// Error handling. The `ValidationError` instances thrown by objection.js have a `statusCode`
3134
// property that is sent as the status code of the response.

examples/express-ts/src/models/Animal.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ import Person from './Person';
33
import { join } from 'path';
44

55
export default class Animal extends Model {
6+
readonly id: number;
7+
owner: Person;
8+
name: string;
9+
species: string;
10+
611
// Table name is the only required property.
712
static tableName = 'Animal';
813

@@ -35,9 +40,4 @@ export default class Animal extends Model {
3540
}
3641
}
3742
};
38-
39-
readonly id: number;
40-
owner: Person;
41-
name: string;
42-
species: string;
4343
}

examples/express-ts/src/models/Movie.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import Person from './Person';
33
import { join } from 'path';
44

55
export default class Movie extends Model {
6+
readonly id: number;
7+
name: string;
8+
actors: Person[];
9+
610
// Table name is the only required property.
711
static tableName = 'Movie';
812

@@ -25,7 +29,7 @@ export default class Movie extends Model {
2529
// The related model. This can be either a Model subclass constructor or an
2630
// absolute file path to a module that exports one. We use the file path version
2731
// here to prevent require loops.
28-
modelClass: join(__dirname, 'Person'),
32+
modelClass: Person,
2933
join: {
3034
from: 'Movie.id',
3135
// ManyToMany relation needs the `through` object to describe the join table.
@@ -37,8 +41,4 @@ export default class Movie extends Model {
3741
}
3842
}
3943
};
40-
41-
readonly id: number;
42-
name: string;
43-
actors: Person[];
4444
}

0 commit comments

Comments
 (0)