Skip to content

Commit

Permalink
chore(): add more models and descriptions in readme
Browse files Browse the repository at this point in the history
  • Loading branch information
piyook committed May 21, 2024
1 parent a1ff05e commit 14fd7fb
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 32 deletions.
71 changes: 43 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Install dependencies.

#### Git LFS

You can use git LFS to handle large files such as the database files or image files.
You can use git LFS to handle large files such as database files or image files.

Use LFS to track large database files by running the command below

Expand Down Expand Up @@ -73,69 +73,84 @@ npm run dev

To create a new api path (E.g api/users)

1. Create a **new folder** within the api folder the api path name you want:
### 1. Create a **new folder** within the api folder the api path name you want:

```
mkdir src/api/users
```

2. Create an **api.ts** file in this new folder and add handler logic here - see https://github.com/mswjs/msw for information on writing handlers.
### 2. Create an **api.ts** file in this new folder and add handler logic here - see https://github.com/mswjs/msw for information on writing handlers.

Also take a look at the example handlers in the api folder.
Also take a look at the example handlers in the api folder.

The mock api framework uses the msw-data utility - see https://github.com/mswjs/data and a full rest or graphql api can be automatically set-up from this without having to define each handler using the format below
The mock api framework uses the msw-data utility - see https://github.com/mswjs/data and a full rest or graphql api can be automatically set-up from this without having to define each handler using the format below

```
...db.user.toHandlers('rest')
```

3. Create a database
### 3. Create a database

Database models are held in **/models** directory.
Database models are held in **/models** directory.

a. Create new models in this directory as required - see the users.ts and posts.ts examples.
a. Create new models in this directory as required - see the users.ts and posts.ts examples.

b. Import the new model into the db.ts file and add to the factory function - https://github.com/mswjs/data for more details
b. Import the new model into the db.ts file and add to the factory function - https://github.com/mswjs/data for more details

4. Seeding the database
### 4. Seeding the database

Data can be manually added to the database json file or added via POST requests to the relevant REST endpoint.
#### a. manually adding data

It is also possible to seed the database with random data using seeder functions.
Data can be manually added / amended via POST/PUT requests to the relevant REST endpoint. This data wont persist and will be lost when the server is restarted.

Database seeders are located in the seeders folder.
#### b. seed database with fake data.

**Note**: New seeders should be created here and added to the index.ts file in the same folder in order to be automatically imported and executed on server start.
It is possible to seed the database with fake data using seeder functions and faker.js. See the seeders/user-seeder.ts and models/user.ts example.

5. Making Http Requests
Database seeders are located in the seeders folder.

Given the "user" model definition above, the following request handlers are generated and connected to the respective database operations:
**Note**: New seeders should be created here and added to the index.ts file in the same folder in order to be automatically imported and executed on server start.
This data will be different each time the server is started and the seeders re-run.

#### c. populate the database with existing data

You can create a data.json file in the /data folder and import this to seed the database with data that will persist and be the same each time the server is started.

See the seeders/post-seeder.ts and models/post.ts example

### 5. Making Http Requests

Given the "user" model definition above, the following request handlers are generated and connected to the respective database operations:

GET /users/:id (where "id" is your model's primary key), returns a user by ID;
GET /users, returns all users (supports pagination);
POST /users, creates a new user;
PUT /users/:id, updates an existing user by ID;
DELETE /users/:id, deletes an existing user by ID;

The "/user" part of the route is derived from your model name. For example, if you had a "post" model defined in your factory, then the generated handlers would be /posts, /posts/:id, etc.
The "/user" part of the route is derived from your model name. For example, if you had a "post" model defined in your factory, then the generated handlers would be /posts, /posts/:id, etc.

For **custom handlers** then requests will be as defined in the individual handler.
### 6. Middleware

Url parameters can be extracted using
For **custom handlers** can contain 'middleware' code defined in an individual handler for each route and http header verb.

```
url.searchParams.get('type')
```
See the cat api for examples of custom handlers getting information from the database and bikes and trains apis for examples of simple 'middleware' added to a custom route.

where type is a url parameter (/api/bikes/?type=KawasakiNinja)
Url parameters can be extracted using

6. Available endpoints
```
url.searchParams.get('type')
```

Available endpoints are listed at the url root
where type is a url parameter (/api/bikes/?type=KawasakiNinja). This can then be used in the middleware code as required.

```
http://localhost:8000
```
### 7. Available endpoints

Available endpoints are listed at the url root

```
http://localhost:8000
```

## Customisation

Expand Down
7 changes: 4 additions & 3 deletions src/api/cars/api.ts → src/api/cats/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { http, HttpResponse } from 'msw';
import { db } from '../../models/db.js';

function handler(pathName: string) {
return [
Expand All @@ -7,9 +8,9 @@ function handler(pathName: string) {
const type = url.searchParams.get('type');
console.log(`starting ${pathName}`);
console.log('Item Type is', type);
return HttpResponse.json({
response: `this is a test response from ${pathName}`,
});

const cats = db.cat.getAll();
return HttpResponse.json(cats);
}),
];
}
Expand Down
14 changes: 14 additions & 0 deletions src/models/cat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { faker } from '@faker-js/faker';
import { primaryKey } from '@mswjs/data';

faker.seed();

export const cat = {
cat: {
// ...with these properties and value getters.
id: primaryKey(Number),
type: () => faker.animal.cat(),
description: () => faker.lorem.lines(5),
price: () => faker.commerce.price({ min: 50, max: 400 }),
},
};
3 changes: 2 additions & 1 deletion src/models/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { factory } from '@mswjs/data';
import { cat } from './cat.js';
import { user } from './user.js';
import { post } from './post.js';

// Create database model
export const db = factory({ ...user, ...post });
export const db = factory({ ...cat, ...user, ...post });
20 changes: 20 additions & 0 deletions src/seeders/cat-seeder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* eslint-disable import/order */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */

import { createRequire } from 'node:module';
import { db } from '../models/db.js';
import { type Cat } from '../types.js';

const require = createRequire(import.meta.url);
const catData: Cat[] = require('../data/data.json');

export const catSeeder = () => {
for (const cat of catData) {
db.cat.create({
id: cat.id,
type: cat.type,
description: cat.description,
price: cat.price,
});
}
};
1 change: 1 addition & 0 deletions src/seeders/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './post-seeder.js';
export * from './user-seeder.js';
export * from './cat-seeder.js';
1 change: 1 addition & 0 deletions src/seeders/post-seeder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { type Post } from '../types.js';
const require = createRequire(import.meta.url);
const postData: Post[] = require('../data/data.json');

// With this method we are seeding the database with persisted data from data/data.json rather than using faker data
export const postSeeder = () => {
for (const post of postData) {
db.post.create({
Expand Down
7 changes: 7 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,10 @@ export type Post = {
title: string;
body: string;
};

export type Cat = {
id: number;
type: string;
description: string;
price: string;
};

0 comments on commit 14fd7fb

Please sign in to comment.