MobX RESTful

MobX RESTful

Common MobX abstract base Class & Decorator utilities for RESTful API.

Just define your Data models & Client HTTP methods, then leave rest of things to MobX!

MobX compatibility NPM Dependency CI & CD

NPM

Usage

Simple List

model/client.ts

import { HTTPClient } from 'koajax';

export const client = new HTTPClient({
baseURI: 'https://api.github.com/',
responseType: 'json'
});

model/Repository.ts

import { buildURLData } from 'web-utility';
import { Filter, ListModel } from 'mobx-restful';
import { components } from '@octokit/openapi-types';

import { client } from './client';

export type Organization = components['schemas']['organization-full'];
export type Repository = components['schemas']['minimal-repository'];

export class RepositoryModel<
D extends Repository = Repository,
F extends Filter<D> = Filter<D>
> extends ListModel<D, F> {
client = client;
baseURI = 'orgs/idea2app/repos';

async loadPage(page: number, per_page: number) {
const { body } = await this.client.get<D[]>(
`${this.baseURI}?${buildURLData({ page, per_page })}`
);
const [_, organization] = this.baseURI.split('/');
const {
body: { public_repos }
} = await this.client.get<Organization>(`orgs/${organization}`);

return { pageData: body, totalCount: public_repos };
}
}

export default new RepositoryModel();

page/Repository.tsx

Use WebCell as an Example

import { WebCell, component, observer, createCell } from 'web-cell';

import repositoryStore from '../model/Repository';

@component({
tagName: 'repository-page'
})
@observer
export class RepositoryPage extends WebCell() {
connectedCallback() {
repositoryStore.getList();
}

disconnectedCallback() {
repositoryStore.clear();
}

render() {
const { currentPage } = repositoryStore;

return (
<ul>
{currentPage.map(({ full_name, html_url }) => (
<li>
<a target="_blank" href={html_url}>
{full_name}
</a>
</li>
))}
</ul>
);
}
}

Preload List

model/PreloadRepository.ts

import { buildURLData } from 'web-utility';
import { Buffer } from 'mobx-restful';

import { client } from './client';
import { Repository, RepositoryModel } from './Repository';

export class PreloadRepositoryModel extends Buffer<Repository>(
RepositoryModel
) {
client = client;
baseURI = 'orgs/idea2app/repos';

loadPage = RepositoryModel.prototype.loadPage;
}

export default new PreloadRepositoryModel();

Multiple Source List

model/MultipleRepository.ts

import { buildURLData, mergeStream } from 'web-utility';
import { Stream } from 'mobx-restful';
import { components } from '@octokit/openapi-types';

import { client } from './client';
import { Repository, RepositoryModel } from './Repository';

export type User = components['schemas']['public-user'];

export class MultipleRepository extends Stream<Repository>(RepositoryModel) {
client = client;

async *getOrgRepos() {
const {
body: { public_repos }
} = await this.client.get<Organization>('orgs/idea2app');

this.totalCount = public_repos;

for (let i = 1; ; i++) {
const { body } = await this.client.get<Repository[]>(
'orgs/idea2app/repos?page=' + i
);
if (!body[0]) break;

yield* body;
}
}

async *getUserRepos() {
const {
body: { public_repos }
} = await this.client.get<User>('users/TechQuery');

this.totalCount = public_repos;

for (let i = 1; ; i++) {
const { body } = await this.client.get<Repository[]>(
'users/TechQuery/repos?page=' + i
);
if (!body[0]) break;

yield* body;
}
}

openStream() {
return mergeStream(
this.getOrgRepos.bind(this),
this.getUserRepos.bind(this)
);
}
}

export default new MultipleRepository();

Wrapper

  1. Strapi v4
  2. Lark/FeiShu

Component

  1. Table, List & Form suite

Scaffold

  1. Client-side Rendering (React): https://github.com/idea2app/Next-Bootstrap-ts
  2. Server-side Rendering (React): https://github.com/idea2app/React-MobX-Bootstrap-ts
  3. Cross-end App (React): https://github.com/idea2app/Taro-Vant-MobX-ts

Limitation

Generated using TypeDoc