Skip to content

Instantly share code, notes, and snippets.

@jayair
Last active July 13, 2018 10:20
Show Gist options
  • Save jayair/deffea8bcd5b277c4fe48b51ba124026 to your computer and use it in GitHub Desktop.
Save jayair/deffea8bcd5b277c4fe48b51ba124026 to your computer and use it in GitHub Desktop.

Step 1

Create a new directory.

$ mkdir micro-api
$ cd micro-api

Step 2

Create a file called package.json and add the following.

{
  "name": "api",
  "engines": {
    "node": "8.9.4"
  },
  "scripts": {
    "start": "micro",
    "dev": "micro-dev"
  },
  "dependencies": {
    "micro": "latest",
    "micro-dev": "latest",
    "micro-cors": "latest"
  }
}

Step 3

Let's install the packages.

$ npm install

Step 4

Create a file called index.js and add the following.

const { json } = require("micro");

const list = ["Install stuff", "Look at the slides", "Starting hacking"];

module.exports = req => {
  return list;
};

Step 5

Start our API.

$ npm run dev

Step 6

Let's quickly test it in a new terminal.

$ curl http://localhost:3000

Your output should look like this:

[
  "Install stuff",
  "Look at the slides",
  "Starting hacking"
]

Step 7

Let's add our PUT request. Replace your index.js with:

const { json } = require("micro");

const list = ["Install stuff", "Look at the slides", "Starting hacking"];

module.exports = async req => {
  let body;

  switch (req.method) {
    case "PUT":
      body = await json(req);
      list.push(body.text);
      break;
  }

  return list;
};

Step 8

Test our PUT request.

$ curl http://localhost:3000 -X PUT -d '{"text":"Buy eggs"}'

Your output should look like this:

[
  "Install stuff",
  "Look at the slides",
  "Starting hacking",
  "Buy eggs"
]

Step 9

Let's add our DELETE request. Replace your index.js with:

const { json } = require("micro");

const list = ["Install stuff", "Look at the slides", "Starting hacking"];

module.exports = async req => {
  let body;

  switch (req.method) {
    case "PUT":
      body = await json(req);
      list.push(body.text);
      break;
    case "DELETE":
      body = await json(req);
      list.splice(body.id, 1);
      break;
  }

  return list;
};

Step 9

Test our DELETE request.

$ curl http://localhost:3000 -X DELETE -d '{"id":3}'

Your output should look like this:

[
  "Install stuff",
  "Look at the slides",
  "Starting hacking"
]

Step 10

Finally let's add CORS support. Replace your index.js with:

const { json } = require("micro");
const cors = require("micro-cors")();

const list = ["Install stuff", "Look at the slides", "Starting hacking"];

module.exports = cors(async req => {
  let body;

  switch (req.method) {
    case "PUT":
      body = await json(req);
      list.push(body.text);
      break;
    case "DELETE":
      body = await json(req);
      list.splice(body.id, 1);
      break;
  }

  return list;
});

Step 11

Create a new directory.

$ cd ../
$ mkdir micro-ui
$ cd micro-ui

Step 12

Create a file called package.json and add the following.

{
  "name": "app",
  "dependencies": {
    "react": "latest",
    "react-dom": "latest",
    "create-react-app": "latest"
  },
  "devDependencies": {
    "react-scripts": "latest"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build"
  }
}

Step 13

Let's install the packages.

$ npm install

Step 14

Create a couple of directories.

$ mkdir src
$ mkdir public

Step 15

Create a file in public/index.html and add the following.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    >
    <title>Micro App</title>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

Step 16

Create a file in src/index.js and add the following.

import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./index.css";

const api = "http://localhost:3000";

class App extends Component {
  render() {
    return (
      <div className="App">
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("root"));

Step 17

Create a file in src/index.css and add the following.

html,
body {
  height: 100%;
  color: white;
  font-size: 24px;
  font-family: sans-serif;
  text-shadow: 0 1px 2px rgba(0, 0, 0, .2);
  background: linear-gradient(297.5deg, DarkOrchid, CornflowerBlue);
}

Step 18

Start our client.

$ npm start

Step 19

Add the following to our App class in src/index.js.

state = {
  list: []
};

async componentDidMount() {
  const list = await this.request();

  this.setState({ list });
}

request = async options => {
  const res = await fetch(api, options);
  return res.json();
};

Step 20

Replace our render() function in src/index.js with:

render() {
  return (
    <div className="App">
      <section>
        {this.state.list.map((item, id) => (
          <p key={id}>
            {item}
          </p>
        ))}
      </section>
    </div>
  );
}

Step 21

Add a couple of styles to our src/index.css.

.App {
  padding: 15px;
  margin: 0 auto;
  max-width: 480px;
}

.App section {
  margin-top: 10px;
  box-sizing: border-box;
  border-radius: 3px;
  border: 1px solid rgba(0, 0, 0, 0.15);
}

.App section p {
  margin: 0;
  padding: 15px;
  cursor: pointer;
  background: rgba(0, 0, 0, 0.1);
  border-bottom: 1px solid rgba(0, 0, 0, 0.15);
}
.App section p:before {
  content: "👉";
  padding-right: 10px;
}
.App section p:last-child {
  border-bottom: 0;
}

Step 22

Handle removing todos with replacing our render() function in src/index.js.

render() {
  return (
    <div className="App">
      <section>
        {this.state.list.map((item, id) => (
          <p key={id} onClick={e => this.handleClick(id)}>
            {item}
          </p>
        ))}
      </section>
    </div>
  );
}

Step 23

And add the following to our App class in src/index.js.

handleClick = async id => {
  const list = await this.request({
    method: "DELETE",
    body: JSON.stringify({ id })
  });

  this.setState({
    list
  });
};

Step 24

Handle adding todos with replacing our render() function in src/index.js.

render() {
  return (
    <div className="App">
      <form onSubmit={this.handleSubmit}>
        <input
          required
          autoFocus
          type="text"
          value={this.state.text}
          placeholder="✨ New Todo"
          onChange={this.handleChange}
        />
      </form>
      <section>
        {this.state.list.map((item, id) => (
          <p key={id} onClick={e => this.handleClick(id)}>
            {item}
          </p>
        ))}
      </section>
    </div>
  );
}

Step 25

Replace state in src/index.js.

state = {
  text: "",
  list: []
};

Step 26

Add the following to our App class in src/index.js.

handleChange = event => {
  this.setState({ text: event.target.value });
};

Step 27

Style the input field by adding to src/index.css.

input {
  border: 0;
  width: 100%;
  padding: 10px;
  font-size: 24px;
  border-radius: 3px;
  color: MidnightBlue;
  box-sizing: border-box;
}

Step 28

Add the following to our App class in src/index.js.

handleSubmit = async event => {
  event.preventDefault();

  const list = await this.request({
    method: "PUT",
    body: JSON.stringify({ text: this.state.text })
  });

  this.setState({
    list,
    text: ""
  });
};

Step 29

Remix this project glitch.com/~wolfhacks-micro-api.

Step 30

Replace the package.json & index.js with your local version.

Step 31

Hit Show and save the URL.


Step 32

Remix this project glitch.com/~wolfhacks-micro-app.

Step 33

Replace the package.json, public/index.html, src/index.css, & src/index.js with your local version.

Step 34

Replace the following with the URL from your API.

const api = "http://localhost:3000";

Step 35

Hit Show and celebrate 🎉

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