DevUI is a team with both design and engineering perspectives, serving huawei DevCloud platform and huawei internal background systems, as well as designers and front-end engineers. Add devui Helper (Devui-Official) DevUIHelper plugin: Devuihelper-lsp (welcome Star)

preface

I have previously posted a boiling point, talking about the front-end in order to improve the efficiency of business delivery, it is necessary to remove the dependence on upstream, this time I would like to share with you my own practice in going to the background dependency, welcome everyone to discuss!

Boiling point portal: Juejin. Im/PIN /6862313…

What does the front end depend on the back end?

In the whole r&d link, the positioning of the background is to provide efficient and stable API interfaces for the front end, through which the front end obtains the required data and presents it to the user.

So to remove the dependence on the background, the front end needs to simulate these interfaces and construct the corresponding test data.

How to simulate the background interface?

In order to simulate the background interface in the front end, I give you the first artifact: JSON Server.

JSON Server’s official position is as follows:

Get a full FAKE REST API with zero coding in less than 30 seconds (seriously)

For example, in the DevCloud business I am currently in charge of — XBoard Kanban project — there is an interface to get all the card information under a kanban (except key fields). The basic protocol of the interface is as follows (the interface protocol has been negotiated with the background in advance) :

GET /v1/[projectid]/[boardid]/cards { "error": null, "status": "success", "result": [ { "column_id": "Seven c489b6746fe4329aa8c869f4c13fab5", "card_list" : [{" id ":" 4634045604195569664 ", / / id card "subject" : "Task ready, ready to start development task ", // card theme "sequence": "11203427", // card serial number "index": "12", // card serial number (used for drag sorting) "archived": False, // Whether the "blocked" is archived: false, // whether the "is_parent" is set to false, // Whether the parent card "createdOn": // Create date "updatedOn": "1598238210463", // last updated date "parent": {// parent card "subject": "design completed, developing requirements ", "id": "4634045604190851072"}, "board" : {/ / the kanban card "id" : "1661625 c5f72471a81979482ab148066", "name" : "development"}, "column" : {/ / state "id" : "7 c489b6746fe4329aa8c869f4c13fab5", "name" : "READY", "type" : "READY", "does" : false}, "card_type" : {/ / card type "color" : "# 6 CBFFF", "name" : "task", "icon" : "icon - op - task", "id" : "2"}, "author" : {/ author/card "name" : "kagolzeng", "id": "05329882ba000f711ffec00c21191097", "nick_name": "kagol", "gender": "male" }, "updater": {/ / last update is a "name" : "kagolzeng", "id" : "05329882 ba000f711ffec00c21191097", "nick_name" : "kagol", "gender" : "Male"}},... // Other cards]},... // Other status columns]}Copy the code

How can this interface be simulated using JSON Server?

Only the following 4 steps are required (assuming there are already project projects, such as NG CLI projects) :

  • Step 1: Install the JSON Server
  • Step 2: Configure the test data
  • Step 3: Write startup script commands
  • Step 4: Start the Mock service

Let’s build a Mock service step by step:

Step 1: Install the JSON Server

In the project root directory, run the following command:

npm i -D json-server
Copy the code

Step 2: Configure the test data

Create a db.json file in the root directory of the project and add the interface data that has been determined with the background before (some fields have been omitted to avoid duplication) :

{ "result": [ { "column_id": "7c489b6746fe4329aa8c869f4c13fab5", "card_list": [ { "id": "4634045604195569664", // card ID "subject": "task ready, ready to start development task ", // card theme "board": {// card ID" ID ": "1661625 c5f72471a81979482ab148066", "name", "development"}, "column" : {/ / state "id" : "Seven c489b6746fe4329aa8c869f4c13fab5", "name" : "READY", "type" : "READY", "does" : false}, "card_type" : {/ / card types "color" : "# 6 CBFFF", "name" : "task", "icon" : "icon - op - task", "id" : "2"}}}}]]Copy the code

Step 3: Write startup script commands

Just write the Mock service startup script in the scripts of package.json:

"mock": "node_modules/.bin/json-server --watch db.json --port 9090"
Copy the code

Step 4: Start the Mock service

npm run mock
Copy the code

After startup, the console displays:

In your browser’s address bar: http://localhost:9090/cards, you can view the interface of the data returned

How do I structure the test data?

Did you see any problems with the way you simulated the background interface?

Test data is too cumbersome to construct!

If each interface returns data that needs to be constructed one by one, there are at least two problems:

  • One is that every record is handwritten, too tired, data is too dead;
  • Second, it is difficult to simulate large amounts of data, and the project source file size will become larger.

To solve these problems, I’m going to introduce a second artifact: mock.js.

Mock.js positions itself as:

Generate random data to intercept Ajax requests

Mock.js can generate almost any data type you can think of, such as numbers, characters, booleans, dates, colors, images, addresses, urls, names, titles, paragraphs, and even regular expressions.

Integrating mock.js is also a simple 3 step process:

  • Step 1: Modify the JSON Server configuration
  • Step 2: Modify the script command
  • Step 3: Restart the Mock service

Step 1: Modify the JSON Server configuration

To integrate mock.js, we need to change the db.json to db.js and add the routes.json file, which can be placed under the Mock folder in the root directory.

mock/db.js var Mock = require('mockjs'); Const CARDS = Mock. Mock ({" error ", null, "status" : "success", "result | 10" : [{/ / generate 10 state "column_id" : "@ guid," "card_list | 20" : [{/ / under the status column has 20 card "id" : "@ guid", "subject" : / / card id '@ the title', / / card theme "sequence" : / \ d {8} /, / / card serial number "index" : "@ integer (1, 100)", / / serial number (drag) is used to "archived" : "@ Boolean", have / / archive "blocked" : "@boolean", // whether to set blocking "is_parent": "@boolean", // whether to set parent card "createdOn": "@date", // create time "updatedOn": "@ date", / / last update time "parent" : {/ / parent card "id" : "@ guid", "name" : "@ cword (2, 10)"}, "board" : {/ / the kanban CARDS "id" : "@ guid", "name" : "@ cword (2, 10)"}, "column" : {/ / state "id" : "@ guid", "name" : "@ cword (2, 10)", "type" : "@ string (' upper ', 2, 20)", "does" : "@ Boolean"}, "card_type" : {/ / card type "color" : "@ color", "name" : "@ cword (2, 10)", "icon" : / icon - [a-z] - {1-3} /, "id" : "@ integer (1, 100)"}, "author" : {/ author/card "name" : "@ the name", "id" : "@ guid," "nick_name" : "@ the name", "gender" : "@ string (' lower ', 4)"}, "updater" : {/ / last update is a "name" : "@ the name", "id" : "@guid", "nick_name": "@name", "gender": "@string('lower', 4)" } }] }] }); const API = () => ({ 'cards': CARDS, }); module.exports = API; mock/routes.json { "/cards": "/cards" }Copy the code

Step 2: Modify the script command

Script commands also need to be modified accordingly

"mock": "node_modules/.bin/json-server --watch mock/db.js --routes mock/routes.json --port 9090"
Copy the code

Step 3: Restart the Mock service

At this point we re-use:

npm run mock
Copy the code

Command to start the Mock service and type in your browser

http://localhost:9090/cards

Access /cards interface:

As you can see, mock. js generates a lot of random test data for us that would have taken a lot of work to construct before.

In order to construct this large amount of test data, we only added less than 50 lines of code to db.js without worrying about the size of the source file.

Is it very convenient?

Let’s take a look at how these Mock interfaces can be used in a business and how to seamlessly switch to a real back-end interface.

Let’s give it a try

Suppose we have created a project using the NG CLI. To invoke the Mock interface, we need to import Angular’s HttpClientModule module:

src/app/app.module.ts

import { HttpClientModule } from '@angular/common/http';

imports: [
  ...,
  HttpClientModule
]
Copy the code

Call the Mock service interface directly

Then inject Angular’s HttpClient service to make a request to the Mock service’s /cards interface:

src/app/app.component.ts

import { HttpClient } from '@angular/common/http';

constructor(
  private http: HttpClient
) {}

ngOnInit() {
  this.http.get('http://localhost:9090/cards').subscribe(cards => {
    console.log('cards:', cards);
  });
}
Copy the code

The obtained interface data is as follows:

Seamlessly switch back interfaces using proxies

You are smart enough to see a problem with the interface that calls the Mock service directly: what about deploying to a test environment or live network?

Because the environment invokes the background interface of the corresponding environment rather than the interface of the Mock service, the interface is proxy to the Mock service during local development, and the specific domain name information is not added when the interface is invoked.

The actual call interface should look like this:

this.http.get('/v1/cards').subscribe(cards => {
  console.log('cards:', cards);
});
Copy the code

The Mock service interface is invoked locally and the backend interface is invoked online to achieve seamless switching without any code modification.

We need to proxy the interface to the Mock service at local development time. We can use NG CLI to provide proxy configuration proxyConfig:

angular.json "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "Ng-demo :build", "port": 4600, "proxyConfig": "proxy.config.js" // Add proxy configuration},... }Copy the code

Proxy profile:

proxy.config.js

const PROXY_CONFIG = {
  '/v1': {
    target: 'http://localhost:9090/v1'
  }
};

module.exports = PROXY_CONFIG;
Copy the code

Our Mock service doesn’t need to change anything.

Other frameworks configure the proxy

If you are not using NG CLI, how do you configure the proxy?

Vue CLI configuration agent

vue.config.js

devServer: {
  proxy: {
    '/v1': {
      target: 'http://localhost:9090/v1'
    }
  }
}
Copy the code

Webpack configures the agent

Webpack is written in much the same way as Vue CLI

webpack.config.js

devServer: {
  proxy: {
    '/v1': {
      target: 'http://localhost:9090/v1'
    }
  }
}
Copy the code

CreateReactApp configures the proxy

React is a bit trickier, requiring the INSTALLATION of http-proxy-middleware.

const proxy = require("http-proxy-middleware");

module.exports = function(app) {
  app.use(
    proxy("/api/", {
      target: "http://localhost:9090/v1"
    })
  );
};
Copy the code

Adding the TS type

If your project uses TypeScript, it’s common to add TS types to interface data. Here’s a handy tool that automatically generates TS files based on your interface: QuickType.

Quicktype is positioned as:

Generate types and converters from JSON, Schema, and GraphQL. Generate types and converters from JSON, Schema, and GraphQL.

Just now we have started our Mock services, input http://localhost:9090/cards in your browser’s address bar, you can also view the interface/CARDS return data, then we can use quicktype tool root, according to the interface address to generate the corresponding type of TS file.

It only takes 2 steps:

  • Step 1: Install QuickType
  • Step 2: Generate TS type files

Step 1: Install QuickType

npm i -g quicktype
Copy the code

Step 2: Generate TS type files

quicktype http://localhost:9090/cards -o ./src/app/shared/types/card.interface.ts --runtime-typecheck
Copy the code

Use type TS

import { CardInterface } from './shared/types/card.interface';

this.http.get('/v1/cards').subscribe((cards: CardInterface) => {
  console.log('cards:', cards);
});
Copy the code

There are two obvious benefits to using the TS type:

One is type checksum automatic prompt;

Second, data documentation and field automatic reminder and completion.

Automatic prompt for type checksum:

Data documentation and field auto-reminder and completion:

summary

This paper mainly introduces how to use JSON Server and mock. js to build Mock service in the front end and simulate the background interface, so as to remove the dependence on the background during the development stage and improve the efficiency of business delivery.

Welcome to comment and exchange!

Source code address: github.com/kagol/ng-mo…

Join us

We are DevUI team, welcome to come here and build elegant and efficient human-computer design/research and development system with us. Email: [email protected].

The text/Kagol

Previous articles are recommended

Scheduler Scheduler Scheduler

Dark Mode and Thematic Development of Web Interfaces

“How to build a grayscale Publishing environment”

Appendix: Overview of XBoard Kanban projects

Development kanban for XBoard projects