npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-apollo-domain

v2.0.0

Published

This is a small library that allows you to map your own domain entities to the results returned from a graphql operation. By domain entities we understand classes that wrap the mentioned results and can add extra functionality like computed properties or

Downloads

14

Readme

React Apollo Domain

This is a small library that allows you to map your own domain entities to the results returned from a graphql operation. By domain entities we understand classes that wrap the mentioned results and can add extra functionality like computed properties or custom methods that operate with the entity data.

React Apollo Domain is designed to create the less amount of friction possible with your existing code and to be fully compatible with Apollo Client.

Installation

It's as simple as installing the npm package:

$ npm install --save react-apollo-domain

You can use React Apollo Domain in any of the environments where you can use React and Apollo Client.

Usage example

Out of date

Minimal changes are needed to existing codebases in order to start using this domain approach. Let's see a simple example that's going to demostrate everything you need to know in order to start using this library. Or if you're more of a seeing things in action guy, there's an example ready here.

Let's suppose we have the following graphql schema (taken from graphql-pokemon):

type Pokemon {
  id: ID!
  number: String
  name: String
  # some more properties not needed for the example...
  attacks: PokemonAttack
  evolutions: [Pokemon]
}

type Attack {
  name: String
  type: String
  damage: Int
}

type PokemonAttack {
  fast: [Attack]
  special: [Attack]
}

First we start defining our own domain classes. The way this works is that every domain entity we define is going to be mapped to the same __typename in graphql.

domain.js

import { DomainEntity } from 'react-apollo-domain';

// Define a domain entity that is going to wrap the Pokemon type
class Pokemon extends DomainEntity {
  // custom method
  toString() {
    return this.name;
  }
}

// Define a domain entity that is going to wrap the Attack type
class Attack extends DomainEntity {
  // custom property
  get fullName() {
    return this.name + '-' + this.type;
  }
}

// We don't need to define an entity for PokemonAttack because it's not
// a real entity, and more an utility type to hold both types of attacks.

// Finally, export our domain
export default {
  Pokemon,
  Attack,  // We could even alias our domain to other typenames with => Alias: DomainEntity
};

Then, we need to add the domain cache and link to the client. DomainCache is just a subclass of InMemoryCache so both have the same behavior.

app.js

import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { ApolloLink } from 'apollo-link';
import { setContext } from 'apollo-link-context';

import domain from '../domain';
import { createDomainCache, createDomainLink } from './react-apollo-domain';

const client = new ApolloClient({
  link: ApolloLink.from([
    middlewareLink,
    createDomainLink(domain),
    new HttpLink({ uri: 'https://fakerql.com/graphql' }),
  ]),
  cache: createDomainCache(domain),
});


export default client;

Description

When developing web applications that interact through graphql, sometimes, you need to add extra functionality to the results you get from graphql. Either you want to calculate extra data based on the data you got or to add new methods that would allow you to perform operations with that data.

There are multiple ways of doing that, the most simple one is just adding extra methods to the component performing the graphql query. Other way would be creating an utils collection of functions that receives the data and returns the computed data.

The problem those approaches have is that in the first place, every time you want to compute the same data in a different component, you have to duplicate functionality. In the second case, every function can be very spread through the whole system and depending on the organization method you choose, very complicated to follow which function affects what data.

As a third option, we think those computations should be a property of the data itself, this way, every time you have access to that data, you'll have access to those computations. That has some benefits, for example, the children components don't need to know that the data is computed, everything related to an entity, is close to that entity instead of spread through a collection of functions, some computations can use other computations transparently to the user, etc. You can even use the computed properties to normalize the data passed between the back-end and the front-end.

Main concepts

The two basic principles of this library are:

  • Everything that is a domain entity in the back-end, should be a domain entity in the front-end.
  • And every computation based on the internal data of an entity, should be as close to that entity as possible.

With those two principles in mind, let's see what is a Domain Entity:

A domain entity is just a normal JavaScript class that encapsulates all the data received from a graphql operation. That class can define extra properties and methods that operate on said data. By default, if just the class is defined, the behavior is the same as the one of raw data.

Examples:

import { DomainEntity } from 'react-apollo-domain';

class Pokemon extends DomainEntity {
}

class Attack extends DomainEntity {
}

API

DomainEntity

Base class for a domain entity. Defines common behavior between all entities. Example:

import { DomainEntity } from 'react-apollo-domain';

class Pokemon extends DomainEntity {
}

createDomainLink()

Creates a link that will map the domain entities to every response to a mutation or subscription.

createDomainCache()

Creates a cache inheriting from InMemoryCache that will map every domain entity to every read operation.

License

MIT. See LICENSE for details.