Introducing Platapi: Effortless Mocking of API Responses with Pseudo Realistic Data
Tags: api, programming, webdev, ux
Published: 2024-02-09 04:25:31

You just released your brand new software to the public and you're confident that all is well, until one of your friends says "I just got a gray screen". You realize that your new software didn't handle a slow response. How can you make sure that your software gracefully handles all possible API responses?

# Understanding API responses
API's are the backbone to all of our applications in the world. They provide us with the vital information we need but sometimes we get unexpected responses.

A standard GET request returns some data with a 200 response. It could also return a 401 or 403 if proper authentication wasn't supplied. Another possibility is a 500 response if the server encounters an error. 

The happy path for our applications is handling successful responses but as developers we need to handle the not so happy paths. These paths can be difficult to code for if the API you're using always returns a successful response. This is where [Platapi](https://www.platapi.com) comes in. 

# Creating a Mock API with JSON
The simplest way to use Platapi is to capture a valid response from your existing API or to create a JSON response that we want to get back. 

I personally love cats so here's some cat data
```
{
   "id":"0XYvRd7oD",
   "url":"https://cdn2.thecatapi.com/images/0XYvRd7oD.jpg",
   "breeds":[
      {
         "weight":{
            "imperial":"7  -  10",
            "metric":"3 - 5"
         },
         "id":"abys",
         "name":"Abyssinian",
         "cfa_url":"http://cfa.org/Breeds/BreedsAB/Abyssinian.aspx",
         "vetstreet_url":"http://www.vetstreet.com/cats/abyssinian",
         "vcahospitals_url":"https://vcahospitals.com/know-your-pet/cat-breeds/abyssinian",
         "temperament":"Active, Energetic, Independent, Intelligent, Gentle",
         "origin":"Egypt",
         "country_codes":"EG",
         "country_code":"EG",
         "description":"The Abyssinian is easy to care for, and a joy to have in your home. They’re affectionate cats and love both people and other animals.",
         "life_span":"14 - 15",
         "wikipedia_url":"https://en.wikipedia.org/wiki/Abyssinian_(cat)",
      }
   ],
   "width":1204,
   "height":1445
}
```
Inside the Platapi app I can just upload the above json to create the mock endpoint.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s8t2trdogjzmh8oalirp.png)

After creating the endpoint and navigating back to the dashboard I am presented with this sweet view!

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j1qdnf3sjiz9gj6t4tll.png)

# Implementing the mock API
After your mock is created you can simply copy the Platapi urls and add them to your application. Once you are done testing or building simply update the root domain and you're good to go!

## Example
**Platapi url** - https://app.platapi.com/ddavis_testing/iQ7hbwFFAmfg0X3K3jjt6JhtRSH2/locations

**Production Url** - https://**production_url**/locations

# Custom Response Codes
From here I can click Test Endpoint and get the same response that I just uploaded. I can also change the status code that is returned by the endpoint.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tjhee4g1qs3g3rgrk40.png)

Let's say I want to make sure my app handles a 403 response.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0bdturin4c6bm9nmmii3.png)

After setting the status code I can hit the new url and get a 403 response

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwa618mo9x6g7zdud625.png)

# Overriding Response Values
What if we want to test different values in our app? Platapi has you covered. You can update json values by specifying the key path.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4lkmcnbhrqu4qgwcu7yp.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/70k1vi8hek7h8s0l54ue.png)

# Creating a Mock API with Swagger/OpenAPI
Platapi can also utilize an api definition to create a mock backend. Here's an example swagger doc I can use to create a full mock api.
```
swagger: "2.0"
info:
  version: "1.0.0"
  title: "Realistic API with Five GET Endpoints (Objects with Descriptions)"
paths:
  /users:
    get:
      summary: "Get user data"
      responses:
        400:
          description: "Bad response"
          schema:
            type: "object"
            properties:
              error:
                type: "string"
                description: An error code or message.
              message:
                type: "string"
                description: A description of the bad request.
        200:
          description: "Successful response"
          schema:
            type: "object"
            properties:
              id:
                type: "integer"
                description: "Unique identifier for the user."
              username:
                type: "string"
                description: "Username of the user."
              email:
                type: "string"
                description: "Email address of the user."
              age:
                type: "integer"
                description: "Age of the user."
              address:
                type: "object"
                description: "Address details of the user."
                properties:
                  street:
                    type: "string"
                    description: "Street address."
                  city:
                    type: "string"
                    description: "City where the user lives."
                  zipCode:
                    type: "string"
                    description: "ZIP code of the user's location."
              hobbies:
                type: "array"
                description: "List of hobbies or interests of the user."
                items:
                  type: "string"
              isActive:
                type: "boolean"
                description: "Indicates whether the user's account is active."
              registrationDate:
                type: "string"
                format: "date-time"
                description: "Date and time when the user registered."

  /products:
    get:
      summary: "Get product data"
      responses:
        200:
          description: "Successful response"
          schema:
            type: "object"
            properties:
              productId:
                type: "integer"
                description: "Unique identifier for the product."
              productName:
                type: "string"
                description: "Name of the product."
              description:
                type: "string"
                description: "Detailed description of the product."
              price:
                type: "number"
                description: "Price of the product."
              manufacturer:
                type: "string"
                description: "Manufacturer or brand of the product."
              category:
                type: "string"
                description: "Category to which the product belongs."
              inStock:
                type: "boolean"
                description: "Indicates whether the product is in stock."
              releaseDate:
                type: "string"
                format: "date"
                description: "Date when the product was released."

  /orders:
    get:
      summary: "Get order data"
      responses:
        200:
          description: "Successful response"
          schema:
            type: "object"
            properties:
              orderId:
                type: "integer"
                description: "Unique identifier for the order."
              customerName:
                type: "string"
                description: "Name of the customer who placed the order."
              orderDate:
                type: "string"
                format: "date-time"
                description: "Date and time when the order was placed."
              totalAmount:
                type: "number"
                description: "Total amount of the order."
              status:
                type: "string"
                description: "Status of the order (e.g., 'pending', 'shipped')."
              items:
                type: "array"
                description: "List of items included in the order."
                items:
                  type: "object"
                  properties:
                    itemId:
                      type: "integer"
                      description: "Unique identifier for the item."
                    productName:
                      type: "string"
                      description: "Name of the product."
                    quantity:
                      type: "integer"
                      description: "Quantity of the product in the order."
                    unitPrice:
                      type: "number"
                      description: "Price of a single unit of the product."

  /articles:
    get:
      summary: "Get article data"
      responses:
        200:
          description: "Successful response"
          schema:
            type: "object"
            properties:
              articleId:
                type: "integer"
                description: "Unique identifier for the article."
              title:
                type: "string"
                description: "Title of the article."
              author:
                type: "string"
                description: "Author of the article."
              publicationDate:
                type: "string"
                format: "date-time"
                description: "Date and time when the article was published."
              content:
                type: "string"
                description: "Content or body of the article."

  /locations:
    get:
      summary: "Get location data"
      responses:
        200:
          description: "Successful response"
          schema:
            type: "object"
            properties:
              locationId:
                type: "integer"
                description: "Unique identifier for the location."
              locationName:
                type: "string"
                description: "Name or label for the location."
              address:
                type: "string"
                description: "Address or description of the location."
              latitude:
                type: "number"
                description: "Latitude coordinate of the location."
              longitude:
                type: "number"
                description: "Longitude coordinate of the location."
```
After the upload is complete we have a full mock API with all of the endpoints.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/08xiea22a0kse73czje6.png)

## Responses
`/locations`
```
{
  "address": "123 Main St, Anytown, USA",
  "latitude": 40.712776,
  "locationId": 1,
  "locationName": "Central Park",
  "longitude": -74.005974
}
```
`/products`
```
{
  "category": "Computers",
  "description": "The latest innovation in high-speed computing, the Quantum X9000 is designed for professionals and enthusiasts seeking unparalleled performance. With its cutting-edge quantum processing unit, it delivers speeds unimaginable to traditional computers, making it perfect for complex simulations, data analysis, and advanced gaming. Its sleek design and efficient cooling system ensure it fits perfectly in any workspace or gaming setup.",
  "inStock": true,
  "manufacturer": "QuantumTech",
  "price": 4999.99,
  "productId": 10567,
  "productName": "Quantum X9000",
  "releaseDate": "2023-03-15"
}
```
`users`
```
{
  "address": {
    "city": "New York",
    "street": "123 Broadway",
    "zipCode": "10001"
  },
  "age": 29,
  "email": "johndoe@example.com",
  "hobbies": [
    "reading",
    "traveling",
    "photography"
  ],
  "id": 45321,
  "isActive": true,
  "registrationDate": "2021-07-15T14:48:00Z",
  "username": "johndoe"
}
```
`/orders`
```
  "items": [
    {
      "itemId": 1,
      "productName": "Wireless Headphones",
      "quantity": 1,
      "unitPrice": 99.99
    },
    {
      "itemId": 2,
      "productName": "Smartwatch",
      "quantity": 1,
      "unitPrice": 199.99
    }
  ],
  "orderDate": "2023-04-14T15:30:00Z",
  "orderId": 12345,
  "status": "shipped",
  "totalAmount": 299.99
}
```
`/articles`
```
{
  "articleId": 3421,
  "author": "Alex Rivera",
  "content": "The Mariana Trench, located in the western Pacific Ocean, is the deepest part of the world's oceans. It reaches a maximum known depth of about 11 kilometers (nearly 7 miles). This article delves into the mysteries and discoveries made in this remote underwater frontier. Scientists and explorers have been drawn to the Mariana Trench for decades, seeking to understand more about its unique ecosystem and the creatures that inhabit it. Despite the challenges posed by its extreme depth, recent technological advancements have enabled more detailed exploration than ever before, revealing fascinating insights into life in one of Earth's most inhospitable places.",
  "publicationDate": "2023-04-10T15:00:00Z",
  "title": "Exploring the Depths of the Mariana Trench"
}
```