{"id":318115,"date":"2020-08-10T07:32:47","date_gmt":"2020-08-10T14:32:47","guid":{"rendered":"https:\/\/css-tricks.com\/?p=318115"},"modified":"2020-08-10T07:32:48","modified_gmt":"2020-08-10T14:32:48","slug":"dont-wait-mock-the-api","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/dont-wait-mock-the-api\/","title":{"rendered":"Don’t Wait! Mock the API"},"content":{"rendered":"\n
Today we have a loose coupling between the front end and the back end of web applications. They are usually developed by separate teams, and keeping those teams and the technology in sync is not easy. To solve part of this problem, we can “fake” the API server that the back end tech would normally create and develop as if the API or endpoints already exist.<\/p>\n\n\n\n\n\n\n\n
The most common term used for creating simulated or “faking” a component is mocking<\/em>. Mocking allows you to simulate the API without (ideally) changing the front end. There are many ways to achieve mocking, and this is what makes it so scary for most people, at least in my opinion. <\/p>\n\n\n\n Let\u2019s cover what a good API mocking should look like and how to implement a mocked API into a new or existing application.<\/p>\n\n\n\n Note, the implementation that I am about to show is framework agnostic \u2014 so it can be used with any framework or vanilla JavaScript application.<\/p>\n\n\n The mocking approach we are going to use is called Mirage<\/a>, which is somewhat new. I have tested many mocking frameworks and just recently discovered this one, and it\u2019s been a game changer for me.<\/p>\n\n\n\n Mirage is marketed as a front-end-friendly framework that comes with a modern interface. It works in your browser, client-side, by intercepting We will go through creating a simple application with mocked API and cover some common problems along the way.<\/p>\n\n\n Let\u2019s create one of those standard to-do applications to demonstrate mocking. I will be using Vue as my framework of choice but of course, you can use something else since we\u2019re working with a framework-agnostic approach.<\/p>\n\n\n\n So, go ahead and install Mirage in your project:<\/p>\n\n\n\n To start using Mirage, we need to setup a “server” (in quotes, because it\u2019s a fake server). Before we jump into the setup, I will cover the folder structure I found works best.<\/p>\n\n\n\n In a The environment argument we’re adding to the function signature is just a convention. We can pass in a different environment as needed.<\/p>\n\n\n\n Now, open your app bootstrap file. In our case, this is he We’re using the That is all we need to set up Mirage! It\u2019s this sort of ease that makes the DX<\/a> of Mirage so nice.<\/p>\n\n\n\n Our Before we make our first request, let’s quickly cover how Mirage works.<\/p>\n\n\n\n Mirage is a client-side<\/strong> mocking framework, meaning all the mocking will happen in the browser, which Mirage does using the Pretender <\/a>library. Pretender will temporarily replace native If you crack open DevTools and head into the Network tab, you won’t see any Mirage requests. That\u2019s because the request is intercepted and handled by Mirage (via Pretender in the back end). Mirage logs all requests, which we\u2019ll get to in just a bit.<\/p>\n\n\nMirage: The mocking framework<\/h3>\n\n\n
XMLHttpRequest<\/code> and Fetch requests.<\/p>\n\n\n\n
Mirage setup<\/h3>\n\n\n
# Using npm\nnpm i miragejs -D\n\u2028\n# Using Yarn\nyarn add miragejs -D<\/code><\/pre>\n\n\n\n
\/\n\u251c\u2500\u2500 public\n\u251c\u2500\u2500 src\n\u2502 \u251c\u2500\u2500 api\n\u2502 \u2502 \u2514\u2500\u2500 mock\n\u2502 \u2502 \u251c\u2500\u2500 fixtures\n\u2502 \u2502 \u2502 \u2514\u2500\u2500 get-tasks.js\n\u2502 \u2502 \u2514\u2500\u2500 index.js\n\u2502 \u2514\u2500\u2500 main.js\n\u251c\u2500\u2500 package.json\n\u2514\u2500\u2500 package-lock.json<\/code><\/pre>\n\n\n\n
mock<\/code> directory, open up a new
index.js<\/code> file and define your mock server:<\/p>\n\n\n\n
\/\/ api\/mock\/index.js\nimport { Server } from 'miragejs';\n\u2028\nexport default function ({ environment = 'development' } = {}) {\n\u00a0 return new Server({\n\u00a0 \u00a0 environment,\n\u2028\n\u00a0 \u00a0 routes() {\n\u00a0 \u00a0 \u00a0 \/\/ We will add our routes here\n\u00a0 \u00a0 },\n\u00a0 });\n}<\/code><\/pre>\n\n\n\n
src\/main.js<\/code> file since we are working with Vue. Import your
createServer<\/code> function, and call it in the development environment<\/em>.<\/p>\n\n\n\n
\/\/ main.js\nimport createServer from '.\/mock'\n\u2028\nif (process.env.NODE_ENV === 'development') {\n\u00a0 \u00a0 createServer();\n}<\/code><\/pre>\n\n\n\n
process.env.NODE_ENV<\/code> environment variable here, which is a common global variable. The conditional allows Mirage to be tree-shaken in production, therefore, it won’t affect your production bundle.<\/p>\n\n\n\n
createServer<\/code> function is defaulting it to
development<\/code> environment for the sake of making this article simple. In most cases, this will default to
test<\/code> since, in most apps, you’ll call
createServer<\/code> once in development mode but many times in test files.<\/p>\n\n\n
How it works<\/h3>\n\n\n
XMLHttpRequest<\/code> and Fetch configurations, intercept all requests, and direct them to a little pretend service that the Mirage hooks onto.<\/p>\n\n\n\n
Let’s make requests!<\/h3>\n\n\n