Enhancing RESTful APIs with GraphQL's Expand and Only Concepts
Tags: rest, api, graphql
Published: 2023-01-28 13:26:09

GraphQL is a query language and runtime for building APIs. It allows clients to define the structure of the data they need, and the server will return only the requested data. This allows for more efficient data retrieval and a better developer experience, as the client can retrieve only the data they need.

We will talk about 2 interesting features provided by GraphQL in this blog; `expand` and `only`. These features greatly help in improving the flexibility and performance of APIs. The benefits of using these are as follows:

1. **Improved performance**: By allowing developers to retrieve only the data that they need, using the `only` concept can reduce the amount of data sent over the network. This can improve the performance of your APIs, especially when working with large data sets.
2. **Increased flexibility**: The `expand` concept allows developers to retrieve additional data for a specific resource on demand. This helps you avoid a few extra API calls thus reducing the overall latency of your application.
3. **Reduced code complexity**: When using expand and only concepts, developers can retrieve only the data they need. This helps them avoid processing the API response in application code to extract the data they need.

As amazing as these features are, they need not be limited to GraphQL alone. They can also be applied to standard RESTful APIs to improve the performance of your APIs. While there are several benefits of using REST over GraphQL like **simplicity**, **browser caching**, **better tooling**, **more resources and community support**, it is also a design decision that will vary from application to application. But if you are using REST APIs in your application you need not stay away from the awesomeness of these GraphQL features.

Here are a few examples of how to exactly use them.

Expanding fields in a RESTful API can be achieved by using a query parameter in the request URL. For example, if you have an endpoint that retrieves a list of users, you can include a query parameter, `expand`, in the request URL to retrieve additional data for each user. You can also add it in a JSON request body.

```
GET /users?expand=address

OR

GET /users
{
  "expand":["address"]
}
```

This will return the additional data for each user in the response.

```
Without expand:
{
    "users": [
        {
            "id": 1,
            "name": "John Smith",
            "address": "address_id_1"
        },
        {
            "id": 2,
            "name": "Jane Doe",
            "address": "address_id_2"
        }
    ]
}

With expand:
{
    "users": [
        {
            "id": 1,
            "name": "John Smith",
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "state": "NY",
                "zip": "12345"
            }
        },
        {
            "id": 2,
            "name": "Jane Doe",
            "address": {
                "street": "456 Park Ave",
                "city": "Sometown",
                "state": "CA",
                "zip": "67890"
            }
        }
    ]
}

```

The `only` concept can be applied to a RESTful API by using a query parameter in the request URL, similar to expanding fields. For example, if you only need the name and email of a user, you can include the `only` query parameter in the request URL.

```
GET /users?only=name,email

OR

GET /users
{
  "only": ["name", "email"]
}
```

This will return only the name and email fields for each user in the response.

```
{
    "users": [
        {
            "name": "John Smith",
            "email": "john.smith@example.com"
        },
        {
            "name": "Jane Doe",
            "email": "jane.doe@example.com"
        }
    ]
}

```

You can also use expand and only concepts in combination in RESTful APIs by including multiple query parameters in the request URL.

```
GET /users?expand=address&only=name,address.city,address.state

OR

GET /users
{
  "expand": ["address"],
  "only": ["name", "address.city", "address.state"]
}
```

This will return the name, city and state fields of address for each user in the response.

```
{
    "users": [
        {
            "name": "John Smith",
            "address": {
                "city": "Anytown",
                "state": "NY"
            }
        },
        {
            "name": "Jane Doe",
            "address": {
                "city": "Sometown",
                "state": "CA"
            }
        }
    ]
}

```

These concepts can provide several benefits when used in your APIs.

However, there are some challenges associated with using these:

1. The logic for `expand` and `only` will not be readily available and developers will have to implement it based on their use case.
2. Developers will have to spend more time to properly document such APIs as these fields are not standard or frequently used in REST APIs.

[Stripe API documentation](https://stripe.com/docs/expand) is a beautiful resource for learning more about this.

In summary, by using the expand and only concepts in standard RESTful APIs, you can create more efficient and flexible APIs that improve the developer experience and performance.