The introduction

At present, Web development generally switches to the development mode of front – end separation. Although the project and function have been separated, but in practical work, the development schedule of the front and back end often appear inconsistent, at this time will greatly affect the development efficiency. This is where the interface mock comes into its own, smoothing out this time lag and ultimately enabling efficient front-end and back-end separation.

There are a variety of mock interface schemes, but they are generally “hard coding”, “front-end intercepting”, and “back-end intercepting”. This article will attempt a brief analysis of the pros and cons of these three common schemes before moving on to the main topic: SVRX-based interface mocks.

Hard coding scheme

Hard coding is the practice of writing mock data directly into front-end code, such as:

function getUser(id) {
  return { username: 'mock username'.id: 100 }; / / interface mock
  return ajax('/user', { id });
}
Copy the code

Remove or comment out when submitting:

function getUser(id) {
  // return {username: 'mock username', id: 100}
  return ajax(`/user/${id}`);
}
Copy the code

Back-end hardcoded mocks do the same, but their invasiveness is kept in the back-end logic, and the front-end business code can be kept clean:

router.get('/user/:id'.async ctx => {
  ctx.body = { username: 'mock username'.id: 100 };
  // ctx.body = await userService.get(ctx.params.id);
});
Copy the code

Note: The above example is based on the Koa framework

Advantages of hard coding

  • Simple and flexible, do not need any tools and framework support, use in situ.
  • If front-end hard coding is used, the modification takes effect without restarting the server.

Disadvantages of hard coding

  • Interface mock and business code coupling, dig a pit for fun, fill a pit crematorium.

This SAO operation is estimated that a lot of people when they were young have done, forget to delete the site of the accident that led to the entrained illicit goods online. Whether or not you use some professional mock framework (like mock.js), this way of coupling in business logic is clearly the next best thing, and it’s likely to get your name in online incident notifications as a result.

A more serious student might work with a build tool (such as Webpack) to separate native mock code from business code, but it doesn’t solve this coupling in nature, and as the project iterates, it also becomes difficult to maintain.

It would be better to completely decouple the mock logic from the business logic and manage it in a separate aspect to avoid committing non-business code to the repository.

This section is divided into front-end interception and back-end interception. As shown in the figure below, the data response is directly intercepted and returned in the corresponding section:

The front intercept

Front-end interception is the interception returned before the request is actually sent, and this aspect can be implemented in two ways: “Webview container customization” and “browser plug-in”.

Webview container customization

Webview container customization can generally be done in two ways: “network interception” and “script injection”, which are also the main ways of front-end and Native interaction in general hybrid applications.

Network to intercept

Network interception is often used in functional scenarios such as offline packages, and can of course be used for interface emulation in conjunction with mock management tools. Referring to Android, intercepts are typically used to replace the response with the following method

public WebResourceResponse shouldInterceptRequest(final WebView view, final String urlstr)
Copy the code

This content is not the main topic of this article and will not be further expanded

Script injection

Both Android and iOS have the ability to inject JS logic directly into webViews, which is how the Bridge communication layer is implemented in Hybrid applications.

Interception rewriting of the response can be achieved by modifying a native object such as fetch or XMLHttpRequest in an injection script.

Examples of key iOS apis

[self.webView stringByEvaluatingJavaScriptFromString:injectjs];
Copy the code

Key Android code snippets

webView.loadUrl("javascript:" + injectjs);
Copy the code

However, whether network interception or script injection, interception based on Webview container is rarely used in real scenarios, because the cost of customization and use is too high, and can only be used in this App.

Browser plug-in

Browser plug-ins are obviously a much cheaper solution to front-end container hijacking than custom Webview containers. Take the code-Mancers/Interceptor project for example:

The Interceptor plug-in makes it easy to configure our mock data in a GUI manner, simple and intuitive, without intruding into project code at all.

Front-end intercept analysis

Front-end interception has two natural advantages:

  • Configurable interface: Because intercepting is done in the browser, you can use the DOM API to provide a configurable interface such as the Interceptor plug-in.
  • Take effect immediately: After the modification, services do not need to be restarted.

But whether it’s a browser plug-in or a custom Webview container, we’re missing an important fact: browser environments are diverse. This leads to one of the typical pitfalls of front-end interception: it can’t be used across browsers, and the Intercepror plug-in shown above won’t work in the wechat browser.

This can be avoided by server-side interception.

Server interception scheme

Server-side interception of implementation interface mocks, implemented primarily through a separate Dev Server layer, typically intercepts requests and returns mock data before accessing the real interface.

Naked Dev Server

For convenience, take Koa as an example and run a dev server naked:

const proxy = require('koa-proxy');
const Koa = require('koa');

const app = new Koa();
app.use((ctx, next) = > {
  switch (ctx.path) {
    case '/api/blog':
      ctx.body = { type: 'blog' };
      break;
    case '/api/user':
      ctx.body = { type: 'user' };
      break;
    default:
      returnnext(); }}); app.use( proxy({host: 'http://api.yoursite.com'})); app.listen(8000.() = > {
  console.log(`server start at http://localhost:8000`);
});
Copy the code

As seen in the example above, the default is to proxy the interface to api.yoursite.com(your target API or backend gay friend’s server). Mock data priority is greater than the real agent interface, we visit https://localhost:8000/api/user, for example, is our mock data of return later if need to increase the mock interface, you need to keep adding case branch.

This bare-streaking approach is unintuitive, as it mixes mock rules with other Dev Server configuration logic and has a high learning cost for non-Node players.

Professional Dev Server

Due to the obvious pain point of running naked server, some dev Server-focused solutions have become popular, such as webpack-dev-server, which developers are familiar with.

It integrates some common service configurations, such as ports, hosts, agents, and so on, and is designed to be integrated into the WebPack build process to serve the build artifacts. This allows us to embed the mock logic independently, using the following WebPack configuration as an example:

module.exports = {
  / /...
  devServer: {
    port: 9000.headers: {
      'X-Custom-Foo': 'bar'
    },
    proxy: {
      '/api': 'http://localhost:3000'
    },
    before(app) {
      // Configure the mock logic
      app.get('/api/blog'.function(req, res) {
        res.json({ custom: 'response'}); }); }}};Copy the code

(Professional Dev Server replaces manual code logic with preset configuration, significantly improving development efficiency.)

But whether you’re naked or using a professional Dev Server, there are essentially the following problems:

  • Hot overloading is not supported: Every time a mock rule is modified, the server needs to be restarted.
  • Unintuitive: Mock rules are mixed with other server configurations and have a high learning cost for non-Node players.
  • There is no interface support, and compared to front-end interception, it does not provide GUI interface configuration capabilities.

Implement efficient interface mocks using SVRX

From the above analysis, it can be concluded that front-end interception and back-end interception have some essential defects. Is there a way to mock both the front and back end interfaces? The answer is SVRX.

Advertising high warning, see this step, I believe you are SVRX potential customers

SVRX profile

SVRX (server-X) is a front-end development Server with microkernel architecture and plug-in. Its internal function module mainly consists of three parts:

  • Front-end injection module: SVRX hijacks all HTML response injection seed scripts, which integrate management of registered front-end resources (JS, CSS).
  • Back-end injection module: SVRX has a built-in middleware registration module with priority.
  • Front-end and back-end communication module: realize the unified communication mode of front-end and back-end injection (based on Websocket), and can complete the event or message communication in an isomorphic way.

As shown above, with a clear module division, plug-ins can be registered in a unified manner, with flexible use of front-end and back-end injection functions.

SVRX also takes the general-purpose functionality of dev-Server and integrates it as a built-in plug-in (livereload, Proxy, HTTPS, etc.) while other proprietary domain functionality (markdown, Qrcode, etc.) is provided as an external plug-in. Maximize the balance between convenience and flexibility.

Subdivided into the field of interface mock, there are currently a series of out-of-the-box kits to meet the needs of developers. Let’s give it a try!

The installation

npm install @svrx/cli -g
Copy the code

Note: All subsequent plug-in capabilities do not need to be explicitly installed

use

Switch to your working directory and run SVRX, and you’ll find a generic dev-server already up and running.

svrx
Copy the code

The SVRX Routing DSL implements the interface mock

For mock interface requirements, we can directly use the built-in dynamic routing functionality:

touch route.js
svrx --route route.js
Copy the code

This is the successful startup interface. Add the following code to route.js:

get('/api/user/:id').to.json({ name: 'svrx' });
Copy the code

Open the browser to/API /user/1 and see the corresponding JSON response. All changes to route.js are hot Reload enabled, so we don’t need to restart the server.

For more instructions on using the SVRX Routing DSL click here

If you use SVRX routing instead of the other dev-servers above, besides making routing more intuitive and efficient, you can also manage routing priorities at a more granular level, such as mock and proxy priorities:

get('/api/user/:id').to.json({ name: 'svrx' });
post('/api/blog(.*)').to.proxy('http://path.to.api.com');
get('/' (. *)).to.send('404 PAGE IS NOT FOUND');
Copy the code

Note: The earlier a routing rule is, the higher its priority is

Use the Mock plug-in to quickly emulate the interface

Direct naked SVRX routing solves the functional problem of mocks, but not the efficiency problem.

SVRX provides svrx-plugin-mock, which comes with the handy mock.js to help us implement fast data simulation:

svrx --mock --route route.js
Copy the code

Use -p mock or –mock directly to activate the plug-in.

As shown in the red box above, the SVRX plugin system has the feature of first install, installed plug-ins will automatically enter SVRX global management, subsequent activation of plug-ins do not need to download again, more importantly, does not pollute your working directory (including node_modules).

Add the following code to route.js:

get('/api/user/:id').to.mock({
  name: '@name'.email: '@email'
});
Copy the code

The Mock plug-in registers a mockRouting the Action, can be used in the Routing DSL

Call/API /user/1 again and you’ll get the following random responses that satisfy certain patterns, such as:

{
  "user": "Linda Thomas"."email": "[email protected]"
}
Copy the code

In addition, the mock plugin can also quickly simulate some list loop logic, such as:

get('/api/user/:id').to.mock({
  name: '@name'.email: '@email'.'region|1-3': ['@region']});Copy the code

Region in the response will be an array of 1 to 3 regions, such as:

{
  "name": "Nancy Allen"."email": "[email protected]"."region": ["Northwest"."Central China"]}Copy the code

You can see how using the mock plug-in can greatly improve our mock efficiency and still be intuitive to read.

Use JSON-server to create batch interfaces based on certain rules

SVRX’s mock plug-in with built-in dynamic routing capabilities handles almost 90% of native mock requirements efficiently.

But if your service is based on the JSON-server specification, you can also use sVRX-plugin-Json-server to quickly implement a massive interface. Let’s give it a try.

Start by creating a db.json file in the current directory with the following contents:

{
  "posts": [{ "id": 1."title": "json-server"."author": "typicode"}]."comments": [{ "id": 1."body": "some comment"."postId": 1}}]Copy the code

Start SVRX and activate jSON-server plug-in:

svrx -p json-server --route route.js
Copy the code

Similar to mock, the JSON-Server plug-in registers a routing Action named jsonServer.

Add the following configuration to route.js:

route('/' (. *)).to.jsonServer();
Copy the code

The above statement proxies all requests directly to the internal JSON-server module.

Visit /posts and you’ll see the following response:

[{id: 1.title: 'json-server'.author: 'typicode'}];Copy the code

It’s worth noting that all CRUD operations are built into jSON-server. For example, at posts:

POST /posts => Create UPDATE /posts/:id => UPDATE GET /posts/:id => READ LIST DELETE /posts/:id => DELETECopy the code

For example, when you make a create request (previous fetch example):

fetch('/posts', {
  method: 'POST'.body: JSON.stringify({ title: 'svrx'.author: 'x-orpheus' }),
  headers: {
    'content-type': 'application/json'}});Copy the code

If you visit the /posts list again, you will find an additional record, which will be persisted synchronously to db.json:

[{id: 1.title: 'json-server'.author: 'typicode'
  },
  {
    title: 'svrx'.author: 'x-orpheus'.id: 2}];Copy the code

Requests to rewrite

Using the rewrite directive to wire routing, we can direct only part of the traffic to the JSON-server service, for example:

route('/api/(.*)')
  .rewrite('/ {0}')
  .to.jsonServer(); // /api/posts => /posts
Copy the code

This way only requests starting with/API will be proxied to jSON-server, and other requests can follow other mock logic.

Use the interface management platform

One big problem with all of these mocks is that the mock rules are local and we can’t share the configuration.

In fact, large teams should have AN API management platform to manage the definition of the interface. In netease, we use NEI: Interface management platform to manage the API(maintained by the cloud music front end team, welcome free trial). If you want to mock an interface, you can easily mock it:

With this interface management platform, the cloud music team also encapsulated sVRX-plugin-NEI (open source soon) to realize the data simulation of proxy to NEI platform, as shown in the following figure:

The interface simulation based on the interface management platform matches the real interface specification, so the front and back end specifications are more consistent, and its platform attributes make it easy for developers to share configurations. But this approach also has a huge disadvantage of being much less flexible than native interface emulation.

It is worth mentioning that this plug-in uses the front-end injection capability of SVRX to realize the cross-browser front-end configuration interface. SVRX has automatically injected seed scripts for HTML type resources through the internal Injector module. The seed scripts will integrate all the scripts registered by the plugin. Thus the front-end logic is injected on the dev-server side.

Mock out the core values of SVRX

As you can see, all of the above features complement each other in the world of data Mock, and there is no panacea solution.

So SVRX is not about sVRX-plugin-Mock, sVRx-plugin-json-server, or sVRX-plugin-nei, but about SVRX. It is easy to integrate these functions around the Dev-Server domain in a unified way, avoiding repeated installation and configuration efforts.

For example, 🌰, when developers want JSON response output to look better, they can directly use -p json-viewer to activate the plugin:

svrx --route router.js \
  -p json-viewer \
  -p json-server \
  -p mock
Copy the code

Response view immediately from the following unordered plain text:

Seamlessly switch to intuitive image below:

For another example 🌰, when we want to expose our local service to extranet use, we can use -p localtunnel to activate the localtunnel gateway service.

svrx --route route.js \
  -p json-viewer \
  -p json-server \
  -p mock \
  -p "localtunnel? host=https://tunnel.svrx.io"
Copy the code
  • If the parameter is too long, it can be usedSVRX configuration fileIn the
  • Tunnel.svrx. IO is a welfare facility, stability is not guaranteed, please use it carefully to avoid service unavailability due to various reasons.

A random address like fast-dragon-86.tunnel.svrx. IO can be used to access the domain name of the external network. This kind of open and go experience is not provided by various fragmented dev Server platforms.

More importantly, mock interface is just a part of our daily development. SVRX is positioned as a universal development server with built-in integration of serve, Proxy, Livereload, Route and other essential functions in daily front-end development. And it can be freely combined through the community’s growing pool of plug-ins, as we should have seen from the description of the interface mock scenario above.

It’s safe to say that the more infrastructure around Dev-Server, the more valuable SVRX will be

Write in the last

In addition to “hard coding”, which is not recommended at all, “pure front-end interception” and “pure back-end interception” interface mocks decoupled from business code have some inherent problems that cannot be avoided.

With SVRX and its supporting community plug-ins, we can not only integrate the advantages of front-end and back-end interception, but also integrate various mock functions into one service, which solves the fragmentation problem of tools and effectively implements the interface mock requirements.

Links

  • SVRX (PRONOUNCED :Server-X) is a progressive, easy-to-use, plug-in front-end development Server.
  • Server-x: A tool that can increase your productivity tenfold
  • Mock.js (front-end Mock tool library) and the corresponding svrx-plugin-mock plug-in
  • json-server: Get a full fake REST API with zero coding in less than 30 seconds (seriously)
  • Localtunnel: a reverse tunnel service used to expose local services to public domain names. There is also a quick deployment solution for Docker compiled by the team
  • NEI Interface management platform: an interface management platform used by netease’s R&D team
  • Koa: A lightweight Nodejs framework

This article is published from netease Cloud music front end team, the article is prohibited to be reproduced in any form without authorization. We’re always looking for people, so if you’re ready to change jobs and you like cloud music, join us!