JSON : Placeholder

JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站。

以下使用 RxJS6 + Vue.js 调用该网站的 REST API,获取字符串以及 JSON 数据。

  • GET /posts/1
  • GET /posts
  • POST /posts
  • PUT /posts/1
  • DELETE /posts/1

所有 GET API 都返回JSON数据,格式(JSON-Schema)如下:

{
"type":"object",
"properties": {
"userId": {"type" : "integer"},
"id": {"type" : "integer"},
"title": {"type" : "string"},
"body": {"type" : "string"}
}
}

创建工程

# 安装 Vue CLI
$ npm install --global @vue/cli
# 创建新的应用程序 RxExample
$ vue create rx-example
# 选择 Manually select features
# 选择 Babel 和 TypeScript
$ cd rx-example
$ npm run serve

打开 Intellij IDEA, File / New / Project From Existing Sources...,然后选中工程所在文件夹

在向导的第1页选择 Create project from existing sources

完成向导后在点击 Finish 创建工程。

点击 Add Configurations, 点击 +npm

Name: Vue CLI Server

Scripts: serve

点击 OK 完成配置。

点击 Vue CLI Server 启动程序。

http://localhost:8080/ 可打开网页。

Post

在 src 文件夹下添加 post.ts,内容如下

export class Post {
userId!: number;
id!: number;
title!: string;
body!: string;
toString(): string {
return `Post {userId = ${this.userId}, id = ${this.id}, title = "${this.title}", body = "${this.body.replace(/\n/g, '\\n')}"}`;
}
}

安装 vue-typescript-inject

vue-typescript-inject 是一个在 Vue.js 中实现 DI(依赖注入) 的包。

使用这个包需要安装 vue-typescript-inject 和 reflect-metadata。

$ npm i vue-typescript-inject reflect-metadata

打开 tsconfig.json 在 compilerOptions 中

添加关于 emitDecoratorMetadata 的设定。

    "emitDecoratorMetadata": true,
"experimentalDecorators": true,

打开 main.ts 将其改为

import 'reflect-metadata';
import Vue from 'vue'
import App from './App.vue'
import VueTypeScriptInject from 'vue-typescript-inject'; Vue.config.productionTip = false; Vue.use(VueTypeScriptInject); // register vue-typescript-inject new Vue({
render: h => h(App),
}).$mount('#app');

安装 Rxios

访问 API 采用将 RxJS 和 axios 合为一体的 Rxios 组件,但是该组件尚未升级到 RxJS6。

这里我们只安装 RxJS 和 axios,然后直接以源码形式引入 Rxios,并将其升级到 RxJS6。

$ npm install axios rxjs

在 src 文件夹下添加 rxios.ts,内容如下

// https://github.com/davguij/rxios/blob/master/src/index.ts
// ported to rxjs6 import axios, { AxiosInstance, AxiosRequestConfig, AxiosPromise } from 'axios';
// import { Observable } from 'rxjs/Observable';
import { Observable } from 'rxjs'; export interface rxiosConfig extends AxiosRequestConfig {
localCache?: boolean;
} class rxios {
private _httpClient: AxiosInstance; constructor(options: rxiosConfig = {}) {
this._httpClient = axios.create(options);
} private _makeRequest<T>(method: string, url: string, queryParams?: object, body?: object) {
let request: AxiosPromise<T>;
switch (method) {
case 'GET':
request = this._httpClient.get<T>(url, {params: queryParams});
break;
case 'POST':
request = this._httpClient.post<T>(url, body, {params: queryParams});
break;
case 'PUT':
request = this._httpClient.put<T>(url, body, {params: queryParams});
break;
case 'PATCH':
request = this._httpClient.patch<T>(url, body, {params: queryParams});
break;
case 'DELETE':
request = this._httpClient.delete(url, {params: queryParams});
break; default:
throw new Error('Method not supported');
}
return new Observable<T>(subscriber => {
request.then(response => {
subscriber.next(response.data);
subscriber.complete();
}).catch((err: Error) => {
subscriber.error(err);
subscriber.complete();
});
});
} public get<T>(url: string, queryParams?: object) {
return this._makeRequest<T>('GET', url, queryParams);
} public post<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('POST', url, queryParams, body);
} public put<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('PUT', url, queryParams, body);
} public patch<T>(url: string, body: object, queryParams?: object) {
return this._makeRequest<T>('PATCH', url, queryParams, body);
} public delete(url: string, queryParams?: object) {
return this._makeRequest('DELETE', url, queryParams);
}
} export {rxios, rxios as Rxios};

post 服务

在 src 文件夹下添加 post.service.ts,内容如下

import { Injectable } from 'react.di';
import { Observable, from } from 'rxjs';
import { map, mergeAll, take, tap } from 'rxjs/operators';
import { Post } from './post';
import { Rxios } from './rxios'; @Injectable
export class PostService {
private readonly http = new Rxios();
private readonly baseUrl = 'http://jsonplaceholder.typicode.com/'; constructor() {
this.getPostAsString().subscribe();
this.getPostAsJson().subscribe();
this.getPosts(2).subscribe();
this.createPost().subscribe();
this.updatePost().subscribe();
this.deletePost().subscribe();
} private getPostAsString(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return new Rxios({transformResponse: undefined}).get<string>(url)
.pipe(
tap((result: any) => console.log(result)),
);
} private getPostAsJson(): Observable<Post> {
const url = `${this.baseUrl}posts/1`;
return this.http.get<Post>(url)
.pipe(
map((result: any) => Object.assign(new Post(), result)),
tap((result: any) => console.log('' + result)),
);
} private getPosts(n: number): Observable<Post> {
const url = `${this.baseUrl}posts`;
return from(this.http.get<Post[]>(url))
.pipe(
mergeAll(),
map((result: any) => Object.assign(new Post(), result)),
take(n),
tap((result: any) => console.log('' + result)),
);
} private createPost(): Observable<string> {
const url = `${this.baseUrl}posts`;
return this.http.post(url, {
params: {
userId: 101,
title: 'test title',
body: 'test body',
}
})
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
} private updatePost(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return this.http.put(url, {
params: {
userId: 101,
title: 'test title',
body: 'test body',
}
})
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
} private deletePost(): Observable<string> {
const url = `${this.baseUrl}posts/1`;
return this.http.delete(url)
.pipe(
map((result: any) => JSON.stringify(result)),
tap((result: any) => console.log(result)),
);
}
}
  • getPostAsString 方法取出第1个Post,返回字符串
  • getPostAsJson 方法取出第1个Post,返回Post对象
  • getPosts 方法取出前n个Post,返回n个Post对象
  • createPost 方法创建1个Post,返回字符串
  • updatePost 方法更新第1个Post,返回字符串
  • deletePost 方法删除第1个Post,返回字符串

删除 HelloWorld 组件,即 src/components/HelloWorld.vue 文件。

打开 App.vue,将其改为

<template>
</template> <script lang="ts">
import { Component, Vue } from 'vue-property-decorator';
import { PostService } from './post.service';
import { inject } from 'vue-typescript-inject'; @Component({
providers: [
PostService,
],
})
export default class App extends Vue {
@inject() postService!: PostService;
}
</script> <style>
</style>

输出结果

{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
Post {userId = 1, id = 2, title = "qui est esse", body = "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"}
Post {userId = 1, id = 1, title = "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body = "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"}
{"params":{"userId":101,"title":"test title","body":"test body"},"id":101}
{"params":{"userId":101,"title":"test title","body":"test body"},"id":1}
{}

ReactiveX 学习笔记(25)使用 RxJS + Vue.js 调用 REST API的更多相关文章

  1. ReactiveX 学习笔记(26)使用 RxJS + React.js 调用 REST API

    JSON : Placeholder JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站. ...

  2. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  3. IOS学习笔记25—HTTP操作之ASIHTTPRequest

    IOS学习笔记25—HTTP操作之ASIHTTPRequest 分类: iOS2012-08-12 10:04 7734人阅读 评论(3) 收藏 举报 iosios5网络wrapper框架新浪微博 A ...

  4. vue.js 调用iOS原生方法,JavaScriptCore

    1. 2. 3. 4.vue.js调用

  5. Vue.js 2.x API 知识梳理(一) 全局配置

    Vue.js 2.x API 知识梳理(一) 全局配置 Vue.config是一个对象,包含Vue的全局配置.可以在启动应用之前修改指定属性. 这里不是指的@vue/cli的vue.config.js ...

  6. Vue.js 学习笔记之五:编译 vue 组件

    正如上一篇笔记中所说,直接使用 ES6 标准提供的模块规范来编写 Vue 组件在很多情况下可能并不是最佳实践.主要原因有两个,首先是市面上还有许多并没有对 ES6 标准提供完全支持的 Web 浏览器, ...

  7. Dynamic CRM 2013学习笔记(九)CrmFetchKit.js介绍:Fetchxml、多表联合查询, 批量更新

    CrmFetchKit.js是一个跨浏览器的一个类库,允许通过JavaScript来执行fetch xml的查询,还可以实现批量更新,分页查询等.目前已支持Chrome 25, Firefox 19 ...

  8. Nodejs学习笔记(六)--- Node.js + Express 构建网站预备知识

    目录 前言 新建express项目并自定义路由规则 如何提取页面中的公共部分? 如何提交表单并接收参数? GET 方式 POST 方式 如何字符串加密? 如何使用session? 如何使用cookie ...

  9. Nodejs学习笔记(六)—Node.js + Express 构建网站预备知识

    前言 前面经过五篇Node.js的学习,基本可以开始动手构建一个网站应用了,先用这一篇了解一些构建网站的知识! 主要是些基础的东西... 如何去创建路由规则.如何去提交表单并接收表单项的值.如何去给密 ...

随机推荐

  1. springboot2.0 springcloud 断路器仪表盘支持

    springboot 1.5 的时候  springcloud 添加 断路器仪表盘  按照网上的方法是没有问题的  但是 springboot2.0的时候一直无法连接 所以需要添加 @Beanpubl ...

  2. MySQL innobackupex全量备份恢复

    转自 http://blog.itpub.net/27099995/viewspace-1295099/ 先简单介绍一下这个工具:innobackupexinnobackupex比xtarbackup ...

  3. C# CRC - 16

    using System; static class Program { static void Main() { string input = "8000"; var bytes ...

  4. gdb问题value optimized out

    gdb正常print一个变量的值: 但如果gdb调试程序的时候打印变量值会出现<value optimized out> 情况: 可以在gcc编译的时候加上 -O0参数项,意思是不进行编译 ...

  5. 精读《C++ primer》学习笔记(第一至三章)

    第一章: 重要知识点: 类型:一种类型不仅定义了数据元素的内容,还定义了这类数据上可以进行的运算:所以说类定义,实际上就是定义了一种数据类型: >>和<<运算符返回其左侧的运算 ...

  6. kvm中重命名虚拟机

    kvm中重命名虚拟机 1.查看虚拟机 [root@linux ~]# virsh list --all Id Name State ---------------------------------- ...

  7. Sqlserver 计算两坐标距离函数

    mark if exists (select * from dbo.sysobjects where id = object_id(N'UF_ETL_GetDistance') and xtype i ...

  8. USD词汇表(USD Glossary)

    这篇文章是在学习USD的过程中龟速写成的,目的是将USD的核心设计.相关概念的说明.以及配套API整理出来,为后续进行的USD开发工作提供中文资料支持. 实际上也只有充分理解了USD设计中的每一个知识 ...

  9. 工控随笔_06_西门子_Step7归档项目无法备份的解决方法

    在一次备份Step7项目时,突然发现无法进行备份而是报错,具体的报错内容如下所示: 图 step7 归档程序时报pkzipc.exe 应用程序错误  内存不能为"read" 一.s ...

  10. 子线程更新UI界面的2种方法

    一.一般我们都会在子线程完成一些耗时的操作. 1.Android中消息机制: 2.知识点: Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队, ...