Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save patrickclery/bf3a3ffe3c99a951a4276e23e4e33373 to your computer and use it in GitHub Desktop.
Save patrickclery/bf3a3ffe3c99a951a4276e23e4e33373 to your computer and use it in GitHub Desktop.
How to design a full stack feature in pairs

How to design a full stack feature in pairs

How to work on frontend/backend without relying on each other's work

STEP 1: Define how the request/response flow works between the frontend at every step.

The Problem: One common issue that can arise is a form needs to be designed before the backend can test their controller... OR an API endpoint on the backend needs to be functioning before a frontend can test if their request works.

If you're building a backend feature, for example a Webhook for the Twilio API, then you can go into their Dashboard, test your webhook, and you don't have to worry about this kind of thing.

OR if you're building a frontend interface to get data from Google Maps, you can test everything live.

But when you're building a Frontend/Backend feature at the same time, you won't have this luxury.

In reality, the frontend doesn't care how the backend works, and the backend doesn't care how the frontend works. They wish they could say.

Frontend: "Look, I don't care how you do it, just save this blog post."

Backend: "That's fine - as long as you give me the name and title, we're good."

But the reality is more like...

Frontend: "Hey backend, save this blog post, please!"

Backend: "Uhhh.. What's a blog post?"

The problem this creates is that if either side is relying on each other to "work", then development is blocked and can't move forward for one side.


🐦 Mock... YEAH! Bird... YEAH! Mock-Ing-Bird!

That's where Mocking comes in. Mocking let's us pretend that they have a super complex API that saves their blog post no matter what they say:

Frontend: "Dear Mock Backend, save this blog post, please!" Mock Backend: "Sure thing, I've saved it!" (this is a lie, but the frontend can assume that it worked)

This part is easy because all we need to do to "mock" something is come up write the data, which is just a few lines of JSON, no code required. There's two types of mocks we agree on:

  1. Mock requests: POST/GET/PUT/DELETE requests sent from frontend > backend.
  2. Mock responses: JSON sent from backend > frontend in response to API requests.

Backend and frontend can both access these files and implement them in their tests to work as a control to ensure both frontend/backend remain in sync.

For example, if the feature is "Ability to submit a new blog post to the form", as a frontend team, you'd define the json that you would pass to the axios() module from JavaScript.

/public/mocks/blog/create_a_blog_post-request.json

{
    "url": "/blog/new",
    "method": "POST",
    "body": {
        "authorId": "52aae9ce-7db6-4b54-8a08-313a6cecc02f",
        "isPublished": true,
        "title": "How to knit baskets"
    }
}

/public/mocks/blog/create_a_blog_post-response.json

{
    "status": {
      "code": 201,
      "message": "OK"
    },
    "body": {
      "id": "38e0ac3a-b545-4ad8-af54-8b320b0ac14b"
    }
}

Once you've agreed on these, directly link to these in your tests. For example, in an RSpec test, you could use:

# blog_controller_test.rb

expected_request = JSON.parse(File.read('/public/mocks/blog/create_a_blog_post-request.json'))
expected_response = JSON.parse(File.read('/public/mocks/blog/create_a_blog_post-response.json'))
_(post('/blog/new', **expected_request)).must_equal expected_response

Note: There are many tools available such as Webmock, VCR, etc. - it's important that whatever the approach, the data should be kept in a format that both frontend/backend can use (YML cassettes with VCR, for example, is not ideal for expecting frontend developers to be trained with).

or in your Jest tests

// postNewBlog.test.js

import CreateBlogRequest from '/public/mocks/blog/create_a_blog_post-request.json'
import CreateBlogResponse from '/public/mocks/blog/create_a_blog_post-response.json'

const response = await axios.post('/blog/create', CreateBlogRequest.body)
expect(CreateBlogResponse).toEqual(response)

Note: There are many tools available such as nock, json-api-server, etc. - use any of these but ensure you rely on the JSON files as a constant/control to ensure development stays synchronized.

The idea here is that both frontend/backend build their feature based on the request/responses that never change (unless both sides agree to change it). And if the data does change, it should (on purpose) break tests to alert us that the structure has changed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment