If you are still not sure about how to use Manta Style, you might want to check out Quick Start.
Contents
- Mock Simple Data Structure
- Customize each field
- Mock an array of some data structure
- Mock Success and Failure Response
- Use custom types
- Conditional Types
- Read information from URL
- Proxy to real servers
Access /getUserInfo
to get mock user info, the response JSON contains userid
, userName
, gender
.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
type UserInfo = {
userid: number;
userName: string;
gender: 'male' | 'female';
};
export type GET = {
'/getUserInfo': UserInfo;
};
{
"userid": 6.427734778350991,
"userName": "This is a string message. Customize it mock plugins. (https://github.com/Cryrivers/manta-style/blob/master/documentation/Plugins.md)",
"gender": "male"
}
Previous example can generate the data structure we want. However, some fields look not very realistic. For example, userid
is supposed to a big integer instead of a decimal. userName
should look like an internet username. So this example we will make our /getUserInfo
generates more realistic data with the help of plugins
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: @manta-style/mock-faker
type UserInfo = {
/**
* @range 10000 99999
*/
userid: number;
/**
* @faker {{internet.userName}}
*/
userName: string;
gender: 'male' | 'female';
};
export type GET = {
'/getUserInfo': UserInfo;
};
{
"userid": 84162,
"userName": "Milan_OConner15",
"gender": "male"
}
A new endpoint /getUserInfoList
is added, which returns UserInfo
of muliple users.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: @manta-style/mock-faker
type UserInfo = {
/**
* @range 10000 99999
*/
userid: number;
/**
* @faker {{internet.userName}}
*/
userName: string;
gender: 'male' | 'female';
};
export type GET = {
'/getUserInfoList': UserInfo[];
};
[
{
"userid": 16935,
"userName": "Hailee_Cremin",
"gender": "female"
},
{
"userid": 12459,
"userName": "Westley.Carter22",
"gender": "male"
},
{
"userid": 39348,
"userName": "Michel.Powlowski",
"gender": "male"
},
{
"userid": 63937,
"userName": "Salvador56",
"gender": "male"
}
]
In practice, an API endpoint does not always return a payload without error. So we also need to support to mock both success and failure conditions.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: @manta-style/mock-faker
type UserInfo = {
/**
* @range 10000 99999
*/
userid: number;
/**
* @faker {{internet.userName}}
*/
userName: string;
gender: 'male' | 'female';
};
type ResponseSuccess<T> = {
status: 'ok';
data: T;
};
type ResponseFailure = {
status: 'error';
/**
* @example Not Authorized
*/
message: string;
};
type Response<T> = ResponseSuccess<T> | ResponseFailure;
export type GET = {
'/getUserInfo': Response<UserInfo>;
};
Manta Style outputs the success or failure response and changes when you request it. To get a fixed result, simply press S to generate a snapshot.
{
"status": "ok",
"data": {
"userid": 56856,
"userName": "Whitney2",
"gender": "male"
}
}
{
"status": "error",
"message": "Not Authorized"
}
You can create your own types and share it on npm
, and can also import types from communities. In this example, we will have an API endpoint /iwantcats
, which outputs a URL to cat images on Unsplash by utilizing the custom type Unsplash
built in @manta-style/helpers
.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: (None)
Package: @manta-style/helpers
Import @manta-style/helpers
:
- TypeScript
import { Unsplash } from '@manta-style/helpers';
- Flow
import type { Unsplash } from '@manta-style/helpers';
export type GET = {
'/iwantcats': {
url: Unsplash<'cats', 1600, 900>;
};
};
{
"url": "https://source.unsplash.com/1600x900/?cats"
}
This example supports TypeScript only
Sometimes there are some constraints among several fields. Say we need to have a /names
API, which populates some names and an adjective to describe them. And we assume wgao19
is brilliant
, tanhauhau
is handsome
, jennieji
is awesome
and cryrivers
is dumb.
Builder: @manta-style/builder-typescript
Mock: (None)
/**
* @example wgao19
* @example tanhauhau
* @example jennieji
* @example cryrivers
*/
type Name = string;
type AdjectiveForPerson<T> = T extends 'wgao19'
? 'brilliant'
: T extends 'tanhauhau'
? 'handsome'
: T extends 'jennieji' ? 'awesome' : 'dumb';
type Response<T> = {
name: T;
adjective: AdjectiveForPerson<T>;
};
export type GET = {
'/names': Response<Name>;
};
It randomly generates one of following 4 responses. The adjective
will always match the name
.
{
"name": "wgao19",
"adjective": "brilliant"
}
{
"name": "tanhauhau",
"adjective": "handsome"
}
{
"name": "jennieji",
"adjective": "awesome"
}
{
"name": "cryrivers",
"adjective": "dumb"
}
Sometimes we might be interested in information in URLs. URL queries for example, say we have a request /test?country=Singapore
, we want to read the country
as a Type. Another example is URL params, say we have a request /todo/1
, we want to read the id 1
.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: (None)
Package: @manta-style/helpers
Import @manta-style/helpers
:
- TypeScript
import { Query, Param } from '@manta-style/helpers';
- Flow
import type { Query, Param } from '@manta-style/helpers';
type Country = Query<'country'>;
type TodoId = Param<'id'>;
export type GET = {
'/test': { country: Country };
'/todo/:id': { id: TodoId };
};
Result for URL /test?country=Singapore
{
"country": "Singapore"
}
Result for URL /todo/1
{
"id": "1"
}
This example supports TypeScript only
Since we read information from URL as TypeScript types, not only do they support to display, but also support conditional types.
Back to our /getUserInfo
example, say we need to have an upgraded /getInfo
endpoint, which gets a UserInfo
given URL queries type=user&userid={userid}
or gets a GroupInfo
given URL queries type=group&groupid={groupid}
.
Builder: @manta-style/builder-typescript
Mock: @manta-style/mock-faker
Package: @manta-style/helpers
import { Query } from '@manta-style/helpers';
type Type = Query<'type'>;
type UserId = Query<'userid'>;
type GroupId = Query<'groupid'>;
type UserInfo<UID> = {
userid: UID;
/**
* @faker {{internet.userName}}
*/
userName: string;
gender: 'male' | 'female';
};
type GroupInfo<GID> = {
groupid: GID;
/**
* @faker {{commerce.productAdjective}} {{commerce.productName}}
*/
groupName: string;
/**
* @faker {{address.streetAddress}}, {{address.zipCode}}
*/
address: string;
};
export type GET = {
'/getUserInfo': Type extends 'user' ? UserInfo<UserId> : GroupInfo<GroupId>;
};
Access /getUserInfo?type=user&userid=12345
:
{
"userid": "12345",
"userName": "Cletus79",
"gender": "female"
}
Access /getUserInfo?type=group&groupid=10086
:
{
"groupid": "10086",
"groupName": "Handmade Ergonomic Cotton Bike",
"address": "3202 Fabian Turnpike, 67924"
}
As you can see, the data type it returns respects the conditional type and what user inputs from URL queries.
Builder: @manta-style/builder-typescript
or @manta-style/builder-flowtype
Mock: (None)
Package: (None)
export type GET = {
/**
* @proxy https://jsonplaceholder.typicode.com
*/
'/todos/1': { message: 'This is from Manta Style' };
/**
* @proxy https://www.google.com
*/
'/errorExample': { haha: number };
};