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!