github.com/maeglindeveloper/gqlgen@v0.13.1-0.20210413081235-57808b12a0a0/docs/content/recipes/federation.md (about)

     1  ---
     2  title: 'Using Apollo federation gqlgen'
     3  description: How federate many services into a single graph using Apollo
     4  linkTitle: Apollo Federation
     5  menu: { main: { parent: 'recipes' } }
     6  ---
     7  
     8  In this quick guide we are going to implement the example [Apollo Federation](https://www.apollographql.com/docs/apollo-server/federation/introduction/)
     9  server in gqlgen. You can find the finished result in the [examples directory](https://github.com/99designs/gqlgen/tree/master/example/federation).
    10  
    11  ## Enable federation
    12  
    13  Uncomment federation configuration in your `gqlgen.yml`
    14  
    15  ```yml
    16  # Uncomment to enable federation
    17  federation:
    18    filename: graph/generated/federation.go
    19    package: generated
    20  ```
    21  
    22  ## Create the federated servers
    23  
    24  For each server to be federated we will create a new gqlgen project.
    25  
    26  ```bash
    27  go run github.com/99designs/gqlgen
    28  ```
    29  
    30  Update the schema to reflect the federated example
    31  ```graphql
    32  type Review {
    33    body: String
    34    author: User @provides(fields: "username")
    35    product: Product
    36  }
    37  
    38  extend type User @key(fields: "id") {
    39    id: ID! @external
    40    reviews: [Review]
    41  }
    42  
    43  extend type Product @key(fields: "upc") {
    44    upc: String! @external
    45    reviews: [Review]
    46  }
    47  ```
    48  
    49  
    50  and regenerate
    51  ```bash
    52  go run github.com/99designs/gqlgen
    53  ```
    54  
    55  then implement the resolvers
    56  ```go
    57  // These two methods are required for gqlgen to resolve the internal id-only wrapper structs.
    58  // This boilerplate might be removed in a future version of gqlgen that can no-op id only nodes.
    59  func (r *entityResolver) FindProductByUpc(ctx context.Context, upc string) (*model.Product, error) {
    60  	return &model.Product{
    61  		Upc: upc,
    62  	}, nil
    63  }
    64  
    65  func (r *entityResolver) FindUserByID(ctx context.Context, id string) (*model.User, error) {
    66  	return &model.User{
    67  		ID: id,
    68  	}, nil
    69  }
    70  
    71  // Here we implement the stitched part of this service, returning reviews for a product. Of course normally you would
    72  // go back to the database, but we are just making some data up here.
    73  func (r *productResolver) Reviews(ctx context.Context, obj *model.Product) ([]*model.Review, error) {
    74  	switch obj.Upc {
    75  	case "top-1":
    76  		return []*model.Review{{
    77  			Body: "A highly effective form of birth control.",
    78  		}}, nil
    79  
    80  	case "top-2":
    81  		return []*model.Review{{
    82  			Body: "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.",
    83  		}}, nil
    84  
    85  	case "top-3":
    86  		return []*model.Review{{
    87  			Body: "This is the last straw. Hat you will wear. 11/10",
    88  		}}, nil
    89  
    90  	}
    91  	return nil, nil
    92  }
    93  
    94  func (r *userResolver) Reviews(ctx context.Context, obj *model.User) ([]*model.Review, error) {
    95  	if obj.ID == "1234" {
    96  		return []*model.Review{{
    97  			Body: "Has an odd fascination with hats.",
    98  		}}, nil
    99  	}
   100  	return nil, nil
   101  }
   102  ```
   103  
   104  > Note
   105  >
   106  > Repeat this step for each of the services in the apollo doc (accounts, products, reviews)
   107  
   108  ## Create the federation gateway
   109  
   110  ```bash
   111  npm install --save @apollo/gateway apollo-server graphql
   112  ```
   113  
   114  ```typescript
   115  const { ApolloServer } = require('apollo-server');
   116  const { ApolloGateway } = require("@apollo/gateway");
   117  
   118  const gateway = new ApolloGateway({
   119      serviceList: [
   120          { name: 'accounts', url: 'http://localhost:4001/query' },
   121          { name: 'products', url: 'http://localhost:4002/query' },
   122          { name: 'reviews', url: 'http://localhost:4003/query' }
   123      ],
   124  });
   125  
   126  const server = new ApolloServer({
   127      gateway,
   128  
   129      subscriptions: false,
   130  });
   131  
   132  server.listen().then(({ url }) => {
   133      console.log(`🚀 Server ready at ${url}`);
   134  });
   135  ```
   136  
   137  ## Start all the services
   138  
   139  In separate terminals:
   140  ```bash
   141  go run accounts/server.go
   142  go run products/server.go
   143  go run reviews/server.go
   144  node gateway/index.js
   145  ```
   146  
   147  ## Query the federated gateway
   148  
   149  The examples from the apollo doc should all work, eg
   150  
   151  ```graphql
   152  query {
   153    me {
   154      username
   155      reviews {
   156        body
   157        product {
   158          name
   159          upc
   160        }
   161      }
   162    }
   163  }
   164  ```
   165  
   166  should return
   167  
   168  ```json
   169  {
   170    "data": {
   171      "me": {
   172        "username": "Me",
   173        "reviews": [
   174          {
   175            "body": "A highly effective form of birth control.",
   176            "product": {
   177              "name": "Trilby",
   178              "upc": "top-1"
   179            }
   180          },
   181          {
   182            "body": "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.",
   183            "product": {
   184              "name": "Trilby",
   185              "upc": "top-1"
   186            }
   187          }
   188        ]
   189      }
   190    }
   191  }
   192  ```