Mocking a REST API with VSCode Mock Server Extension ===================================================== Resources ---------- Our API is based on the `{JSON} Placeholder `_ free fake API. The API supports posts, comments and users. - /posts/:id - /posts/:id/comments - /comments/:id - /users/:id As you can see we want to be able to access comments for a post. Preparation ------------- To be able to follow my steps, you should have installed the `Mock Server extension for Visual Studio Code `_. From the VSCode explorer, create a directory called mocks. Right click the `mocks` directory and select the "Generate Mock Files" item from the context menu. Right click the `mocks` directory once more and select the "Set as Server Root Folder" item from the context menu. .. note:: If you already have existing `db.json` file in your workspace root, the extension will use it. This is a perfectly valid scenario, but if it is not what you intended, you need to update the generated `settings.json` file to point to the desired `db.json`. Here is an example from my setup. .. code-block:: json :caption: .vscode/settings.json { "mock-server.settings.paths": { "root": "c:/Sandbox/PoC/vscode/mockserver/mocks/server", "db": "c:/Sandbox/PoC/vscode/mockserver/mocks/db.json", "middlewares": "c:/Sandbox/PoC/vscode/mockserver/mocks/middlewares.js", "injectors": "c:/Sandbox/PoC/vscode/mockserver/mocks/injectors.json", "store": "c:/Sandbox/PoC/vscode/mockserver/mocks/store.json", "rewriters": "c:/Sandbox/PoC/vscode/mockserver/mocks/rewriters.json", "environment": "c:/Sandbox/PoC/vscode/mockserver/mocks/env", "static": "", "snapshots": "c:/Sandbox/PoC/vscode/mockserver/snapshots" } } Now open the `db.json` file and set the content to an empty object: .. code-block:: json :caption: db.json {} Update the `injectors.json` to an empty array: .. code-block:: json :caption: injectors.json [] Update also the `rewriters.json` to have a single rule which will make our REST api accessible at `/api` path. .. code-block:: json :caption: rewriters.json { "/api/*": "/$1" } Now you can start the mock server to see what it looks like when empty. There are different ways to start the server: - Click the `Mock it` button at the VSCode status bar to toggle the Mock Server status - From the command pallete (:kbd:`Ctrl` + :kbd:`Shift` + :kbd:`P`) execute the `MockServer: Start Server` command. Open the mock server in a browser: http://localhost:3000. .. image:: vscode-mockserver-initial-state.png :width: 60% I agree. Doesn't look very exciting, but with almost zero effort we have a running mock server ready to serve our data. Defining the Base Resources ---------------------------- Let's define our base resources. Modify the `db.json` file and save it: .. code-block:: json :caption: db.json { "/posts/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/comments/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/users/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 } } After you save the `db.json`, the Mock Server is automatically restarted. Now I am getting excited! Our mock server fully supports posts, comments, and users. .. image:: vscode-mockserver-base-resources.png :width: 60% Defining a Fetch Route ---------------------- First let's create a route which fetches all the comments for a post. This is a proxy route which we will use in a rewrite so that we get neat and clean post comments resource. Update the `db.json` adding a `/proxy/comments/by-post` route: .. code-block:: json :caption: db.json { "/posts/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/comments/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/users/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/proxy/comments/by-post": { "_config": true, "fetch": "https://jsonplaceholder.typicode.com/comments", "middlewares": [ "_AdvancedSearch" ] } } After you save the updated `db.json` and the Mock Server is restarted, you can query the comments resource by post id. Try http://localhost:3000/proxy/comments/by-post?postId=3. This works thanks to the `_AdvancedSearch` `help middleware `_. The only step left is to define the rewrite rule. Update the `rewriters.json`, adding a rule to rewrite the requests to the post's comments resource to our proxy route: .. code-block:: json :caption: rewriters.json { "/api/*": "/$1", "/posts/:id/comments": "/proxy/comments/by-post?postId=:id" } Now we have routes for all required resources in place. Try http://localhost:3000/posts/5/comments to see all comments for the post with id 5. Fetch Routes With Data Files ----------------------------- Fetch could be used to fetch local data files: #. Create a file `topics.json` in the `data` folder. .. code-block:: json :caption: data/topics.json [ {"id": 1, "name":"Python"}, {"id": 2, "name":"JavaScript"} ] #. Update the `db.json` file adding the `topics` resource. .. code-block:: json :caption: db.json { "/posts/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/comments/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/users/:id?": { "_config": true, "fetch": "http://jsonplaceholder.typicode.com${req.url}", "fetchCount": -1 }, "/proxy/comments/by-post": { "_config": true, "fetch": "https://jsonplaceholder.typicode.com/comments", "middlewares": [ "_AdvancedSearch" ] }, "/topics": { "_config": true, "fetch": "data/topics.json" } } Now we have another resource - `topics`. Note that you can add topics by submitting POST requests. Consider following requests: .. code-block:: text @api_url = http://localhost:3000 ### POST {{api_url}}/api/topics Content-Type: application/json { "name": "Scala" } ### GET {{api_url}}/api/topics ### DELETE {{api_url}}/api/topics/2 ### GET {{api_url}}/api/topics With these requests we add a new topic - 'Scala' and remove the topic with `id` 2. The last request result is: .. code-block:: json [ { "id": 1, "name": "Python" }, { "name": "Scala", "id": 3 } ] I used the `REST Client `_ VSCode extension to interact with the Mock Server. The changes you make are not persisted. When Mock Server is restarted (e.g. `db.json` is updated) all the changes you have made will be lost. Meta ------ - Created on: 2023-03-26