This package has been deprecated

Author message:

This package has been moved to ngrx-entity-relationship as an entry point

ngrx-graphql
TypeScript icon, indicating that this package has built-in type declarations

1.1.2 • Public • Published

ngrx-graphql

npm version CircleCI Coverage Status

A helper library for convertion of selectors made by ngrx-entity-relationship to a GraphQL query.

Supports

  • Angular 6 and ngrx/store@6
  • Angular 7 and ngrx/store@7
  • Angular 8 and ngrx/store@8
  • Angular 9 and ngrx/store@9
  • Angular 10 and ngrx/store@10

Installation

To install the package execute the next command npm install --save ngrx-graphql.

The next step is to add needed augments for types. It will help with integration of ngrx-graphql into ngrx-entity-relationship. For that add the next line in src/main.ts.

import 'ngrx-graphql/augments';

Usage

Note: you should be familiar with ngrx-entity-relationship.

Imagine we have a selector:

export const selectUser = rootEntity(
    selectUserState,
    relatedEntity(
        selectCompanyState,
        'companyId',
        'company',
        relatedEntity(
            selectAddressState,
            'addressId',
            'address',
        ),
    ),
);

And we want to get a GraphQL query like that:

{
    user(id: "1") {
        id
        firstName
        lastName
        companyId
        company {
            id
            name
            addressId
            address {
                id
                street
                city
                country
            }
        }
    }
}

The only issue is that the selector doesn't know fields of the entities. To solve this we need to define them manually as meta of every selector.

Don't forget to include fields for the id detection.

export const selectUser = rootEntity(
    selectUserState,
    {
        gqlFields: ['id', 'firstName', 'lastName'],
    },
    relatedEntity(
        selectCompanyState,
        'companyId',
        'company',
        {
            gqlFields: ['id', 'name'],
        },
        relatedEntity(
            selectAddressState,
            'addressId',
            'address',
            {
                gqlFields: ['id', 'street', 'city', 'country'],
            },
        ),
    ),
);

Profit, now we can use this selector to generate a GraphQL query via toGraphQL helper function.

const allUsers = toGraphQL('users', selectUser); // works for arrays of entities
const userId1 = toGraphQL('user(id: "1")', selectUser); // works with parameters
const userId2 = toGraphQL('user', {id: '2'}, selectUser); // converts parameters

The result will be

{
  users {
    id
    firstName
    lastName
    companyId
    company {
      id
      name
      addressId
      address {
        id
        street
        city
        country
      }
    }
  }
}
{
  user(id: "1") {
    id
    # and all other fields with relationships.
  }
}
{
  user(id: "2") {
    id
    # and all other fields with relationships.
  }
}

If we want we can combine them together to a single query

const combined = toGraphQL(
    toGraphQL('all:users', selectUser),
    toGraphQL('u1:user(id: "1")', selectUser),
    toGraphQL('u2:user', {id: '2'}, selectUser),
);

will generate

{
  all:users {
    id
    # ...
  }
  u1:user(id: "1") {
    id
    # ...
  }
  u2:user(id: "2") {
    id
    # ...
  }
}

Usage with HttpClient

An example of a ngrx effect and HttpClient.

@Injectable()
export class EntityEffects {
    @Effect()
    public readonly dataGraph$ = this.actions$.pipe(
        ofType(UserActionTypes.LOAD),
        switchMap(
            () => this.http.get<{data: {users: Array<User>}}>('http://localhost:3000/graphql', {
                params: {
                    // toGraphQL generates the query
                    query: toGraphQL('users', selectUser),
                }
            }).pipe(
                // reduces data, requires meta reducer from ngrx-entity-relationship.
                map(response => reduceGraph({
                    data: response.data.users,
                    selector: selectUser,
                })),
            ),
        ),
    );
 
    constructor(
        protected readonly actions$: Actions,
        protected readonly http: HttpClient,
    ) {
    }
}

Usage with Apollo Service

An example of a ngrx effect and Apollo service.

@Injectable()
export class EntityEffects {
    @Effect()
    public readonly dataGraph$ = this.actions$.pipe(
        ofType(UserActionTypes.LOAD),
        switchMap(
            () => this.apollo.query<{users: Array<User>}>({
                // toGraphQL generates the query
                query: gql(toGraphQL('users', selectUser)),
            }).pipe(
                // reduces data, requires meta reducer from ngrx-entity-relationship.
                map(response => reduceGraph({
                    data: response.data.users,
                    selector: selectUser,
                })),
            ),
        ),
    );
 
    constructor(
        protected readonly actions$: Actions,
        protected readonly apollo: Apollo,
    ) {
    }
}

Subscriptions

Usage of toGraphQL isn't enough to generate a subscription query. Here toSubscription solves the issue.

For example

const query = toSubscription(toGraphQL('users', action.selector));

will generate

subscription {
  users {
    id
    # ...
  }
}

With Apollo service it can be used like thath

apollo.subscribe({
  query: gql(toSubscription(toGraphQL('users', action.selector))),
}).subscribe(update => {
  // magic is here.
});

Mutations

Usage of toGraphQL isn't enough to generate a mutation query. Here toMutation solves the issue.

For example

const query = toMutation(toGraphQL('updateUser', {
  id: 'id1',
  data: {
    firstName: 'updatedFirstName',
    lastName: 'lastFirstName',
  }
}, action.selector));

will generate

mutation {
  updateUser(
    id:"id1",
    data: {
      firstName:"updatedFirstName",
      lastName:"lastFirstName"
    }
  ) {
    id
    # and all other fields with relationships.
  }
}

With Apollo service it can be used like that

apollo.mutate({
  mutation: gql(toMutation(toGraphQL('updateUser', {
    id: 'id1',
    data: {
      firstName: 'updatedFirstName',
      lastName: 'lastFirstName',
    }
  }, action.selector))),
}).subscribe(update => {
  // magic is here.
});

Query

Usage of toGraphQL isn't enough to generate a query with variables. Here toQuery solves the issue, but about that in the Variables section.

Variables

All toQuery, toSubscription and toMutation support variables. They can be passed as the first parameter. toGraphQL supports $ to define variables instead of values.

apollo.mutate({
  // the same for toQuery and toSubscription too.
  mutation: gql(toMutation({
    // definition of variables and their types.
    data: 'UpdateUserInput!',
  }, toGraphQL('updateUser', {
    id: 'id1', // a normal parameter with its value.
    // under $ parameters and their variables can be defined.
    $: {
      data: '$data',
    },
  }, action.selector))),
  variables: {
    data: {
      firstName: 'updatedFirstName',
      lastName: 'lastFirstName',
    },
  },
}).subscribe(update => {
  // magic is here.
});

will generate

mutation($data: UpdateUserInput!) {
  updateUser(
    id:"id1",
    data: $data
  ) {
    id
    # and all other fields with relationships.
  }
}

Readme

Keywords

Package Sidebar

Install

npm i ngrx-graphql

Weekly Downloads

38

Version

1.1.2

License

Apache-2.0

Unpacked Size

241 kB

Total Files

49

Last publish

Collaborators

  • satantime