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