├── .gitignore
├── .idea
├── .gitignore
├── graphql-settings.xml
└── jsonSchemas.xml
├── .vscode
├── extensions.json
└── settings.json
├── .github
├── router.yaml
└── workflows
│ ├── test.yaml
│ ├── update-router-config.yaml
│ └── supergraph.graphql
├── render.yaml
├── renovate.json
├── Dockerfile
├── CONTRIBUTING.md
├── supergraph.yaml
├── LICENSE
├── router.yaml
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .env
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !jsonSchemas.xml
4 | !graphql-settings.xml
5 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "redhat.vscode-yaml"
4 | ]
5 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "yaml.schemas": {
3 | ".apollo/router_config_schema.json": "router.yaml",
4 | ".apollo/supergraph_config_schema.json": "supergraph.yaml"
5 | }
6 | }
--------------------------------------------------------------------------------
/.idea/graphql-settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.github/router.yaml:
--------------------------------------------------------------------------------
1 | sandbox:
2 | enabled: true
3 | supergraph:
4 | introspection: true
5 | listen: 0.0.0.0:4000
6 | homepage:
7 | enabled: false
8 |
9 | # apq:
10 | # router:
11 | # cache:
12 | # in_memory:
13 | # limit: 512 # This is the default value
14 |
--------------------------------------------------------------------------------
/render.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | - type: web
3 | name: apollo-router
4 | runtime: docker
5 | repo: https://github.com/apollographql/router-template
6 | plan: free
7 | envVars:
8 | - key: APOLLO_GRAPH_REF
9 | sync: false
10 | - key: APOLLO_KEY
11 | sync: false
12 | - key: PORT
13 | value: "4000"
14 | sync: true
15 | region: oregon
16 | dockerContext: .
17 | dockerfilePath: ./Dockerfile
18 | rootDir: ./
19 | version: "1"
20 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "config:base",
5 | ":automergeMinor",
6 | "schedule:automergeWeekdays"
7 | ],
8 | "packageRules": [
9 | {
10 | "matchDatasources": ["docker"],
11 | "matchPackageNames": ["ghcr.io/apollographql/apollo-runtime"],
12 | "allowedVersions": "/^\\d+\\.\\d+\\.\\d+_router\\d+\\.\\d+\\.\\d+_mcp-server\\d+\\.\\d+\\.\\d+$/",
13 | "versioning": "loose",
14 | "prCreation": "immediate"
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # renovate: datasource=docker depName=ghcr.io/apollographql/apollo-runtime extractVersion=^[^_]+
2 | FROM ghcr.io/apollographql/apollo-runtime:0.0.28_router2.7.0_mcp-server1.1.0
3 |
4 | # The runtime container comes with a set of default values that work well for most use cases.
5 | # Uncomment the line below if you'd like to modify the router configuration.
6 | COPY router.yaml /config/router_config.yaml
7 |
8 | # For local development without GraphOS:
9 | # Uncomment the line below to use a locally composed supergraph schema
10 | # COPY data/schema.graphql /config/schema.graphql
11 |
12 | ENTRYPOINT ["/init"]
13 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | We want this template to be useful to as many members of the community as possible, so please contribute any ideas you have! You should start by [searching for an existing discussion](https://github.com/apollographql/router-template/discussions?discussions_q=) and adding your thoughts to it. If we've agreed on a strategy for solving a problem, but we haven't implemented it yet, feel free to create a pull request!
2 |
3 | We will be prioritizing new features based on how many people have "voted" for an idea using the little up-arrow button, so if you'd like to see certain improvements prioritized, please click that button!
4 |
5 | You can also hop into our [community forum](https://community.apollographql.com/) to discuss all things GraphQL and Apollo.
6 |
--------------------------------------------------------------------------------
/.github/workflows/test.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | paths:
4 | - Dockerfile
5 | - router.yaml
6 | - .github/workflows/test.yaml
7 | - .github/workflows/supergraph.graphql
8 | jobs:
9 | test:
10 | name: Smoke test Router
11 | runs-on: ubuntu-latest
12 | steps:
13 | - name: Checkout
14 | uses: actions/checkout@v6.0.0
15 | - name: Build Docker image
16 | run: docker build -t runtime .
17 | - name: Run Router
18 | run: docker run -d --name runtime -p 4000:4000 -v ./.github/router.yaml:/config/router_config.yaml -v ./.github/workflows/supergraph.graphql:/config/schema.graphql runtime
19 | - name: Wait for Router to start
20 | run: sleep 5
21 | - name: Test Router
22 | run: |
23 | curl http://localhost:4000 -d '{"query": "query{__typename}"}' -H "Content-Type: application/json"
24 |
--------------------------------------------------------------------------------
/.idea/jsonSchemas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/supergraph.yaml:
--------------------------------------------------------------------------------
1 | # Supergraph Configuration for Local Development
2 | # This file defines your federated GraphQL architecture by listing all subgraphs.
3 | #
4 | # To use this file for local development without GraphOS:
5 | # 1. Install rover CLI: https://www.apollographql.com/docs/rover/getting-started
6 | # 2. Run: rover supergraph compose --config ./supergraph.yaml > data/schema.graphql
7 | # 3. The generated schema will be used by the router container
8 | #
9 | # Note: The subgraph URLs below should point to your running subgraph services.
10 | # Update these URLs to match your local development setup.
11 |
12 | federation_version: =2.10.0
13 | subgraphs:
14 | products:
15 | schema:
16 | # URL where your products subgraph is running
17 | subgraph_url: http://localhost:4001
18 | users:
19 | schema:
20 | # URL where your users subgraph is running
21 | subgraph_url: http://localhost:4002
22 |
23 | # Add more subgraphs as needed:
24 | # inventory:
25 | # schema:
26 | # subgraph_url: http://localhost:4003
--------------------------------------------------------------------------------
/.github/workflows/update-router-config.yaml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | paths:
4 | - Dockerfile
5 | jobs:
6 | update_schema:
7 | name: Update Router Config JSON Schema
8 | runs-on: ubuntu-latest
9 | continue-on-error: true
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v6.0.0
13 | - name: Build Docker image
14 | run: docker build -t runtime .
15 | - name: Update Config JSON Schema
16 | run: docker run --rm --entrypoint /opt/router runtime config schema > router_config.schema.json
17 | - name: Check if anything changed
18 | run: git diff --exit-code .apollo/router_config_schema.json
19 | - name: Commit and push changes
20 | if: ${{ failure() }}
21 | run: |
22 | git config --global user.name "github-actions[bot]"
23 | git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
24 | git add .apollo/router_config_schema.json
25 | git commit -m "Update router config schema"
26 | git push
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Apollo Graph, Inc.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/router.yaml:
--------------------------------------------------------------------------------
1 | # The runtime container comes with sensible defaults that work well for most use cases.
2 | # Uncomment the COPY and CMD lines in the Dockerfile to use this configuration.
3 |
4 | sandbox:
5 | enabled: false
6 | supergraph:
7 | introspection: true
8 | listen: 0.0.0.0:${env.ROUTER_PORT:-4000}
9 | query_planning:
10 | cache:
11 | in_memory:
12 | limit: 512 # This is the default value
13 |
14 | health_check:
15 | listen: 0.0.0.0:8088
16 | enabled: true
17 | path: /health # Optional, default: /health
18 |
19 | homepage:
20 | enabled: false
21 | include_subgraph_errors:
22 | all: true
23 |
24 | cors:
25 | # WARNING: allow_any_origin: true is NOT safe for production!
26 | # This setting allows requests from any origin, which can lead to security vulnerabilities.
27 | #
28 | # For development/testing: Keep as-is for quick experimentation
29 | # For production: Replace with specific origins like:
30 | #
31 | # origins:
32 | # - "https://yourdomain.com"
33 | # - "https://app.yourdomain.com"
34 | # - "https://admin.yourdomain.com"
35 | #
36 | # You can also use environment variables:
37 | # origins:
38 | # - "${env.FRONTEND_URL}"
39 | # - "${env.ADMIN_URL}"
40 | allow_any_origin: true
41 |
42 | limits:
43 | parser_max_tokens: 15000 # This is the default value.
44 | parser_max_recursion: 4096 # This is the default value.
45 | max_depth: 100 # Must be 15 or larger to support standard introspection query
46 | max_height: 200
47 | max_aliases: 30
48 | max_root_fields: 20
49 |
50 | telemetry:
51 | instrumentation:
52 | spans:
53 | mode: spec_compliant
54 |
--------------------------------------------------------------------------------
/.github/workflows/supergraph.graphql:
--------------------------------------------------------------------------------
1 | schema
2 | @link(url: "https://specs.apollo.dev/link/v1.0")
3 | @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION)
4 | @link(url: "https://specs.apollo.dev/tag/v0.3")
5 | {
6 | query: Query
7 | }
8 |
9 | enum join__Graph {
10 | PRODUCTS @join__graph(name: "products", url: "http://localhost:4001/")
11 | USERS @join__graph(name: "users", url: "http://localhost:4002/")
12 | }
13 | scalar join__FieldSet
14 |
15 | scalar link__Import
16 |
17 | enum link__Purpose {
18 | """
19 | `SECURITY` features provide metadata necessary to securely resolve fields.
20 | """
21 | SECURITY
22 |
23 | """
24 | `EXECUTION` features provide metadata necessary for operation execution.
25 | """
26 | EXECUTION
27 | }
28 |
29 | directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE
30 |
31 | directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION
32 |
33 | directive @join__graph(name: String!, url: String!) on ENUM_VALUE
34 |
35 | directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE
36 |
37 | directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR
38 |
39 | directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION
40 |
41 | directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA
42 |
43 | scalar ErrorRate
44 | @join__type(graph: PRODUCTS)
45 | @join__type(graph: USERS)
46 |
47 | directive @synthetics(
48 | """The synthetic timeout configured for the field."""
49 | timeout: Int
50 |
51 | """The synthetic error rate configured for the field."""
52 | errorRate: ErrorRate
53 |
54 | """Enable or disable synthetics for the field."""
55 | enabled: Boolean = true
56 | ) on FIELD
57 |
58 | directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA
59 |
60 | type Query
61 | @join__type(graph: USERS)
62 | {
63 | """Information about the current logged-in user."""
64 | me: User @join__field(graph: USERS)
65 | }
66 |
67 | type User
68 | @join__type(graph: USERS)
69 | {
70 | name: String
71 | }
72 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://railway.com/deploy/apollo-router)
2 | [](https://render.com/deploy?repo=github.com/apollographql/router-template)
3 |
4 | # Apollo Runtime Template
5 |
6 | A starting point for deploying the Apollo Router using the new runtime container. This template provides easy deployment options for **Railway** and **Render**.
7 |
8 | > 💡 **Quick Start**: This template uses the Apollo runtime container with sensible defaults. You can deploy immediately or customize the configuration for your specific needs.
9 |
10 | ## Prerequisites
11 |
12 | - A [GraphOS account](https://www.apollographql.com/docs/graphos/) (Free and usage-based tiers available)
13 | - Your `APOLLO_KEY` and `APOLLO_GRAPH_REF` from GraphOS Studio
14 |
15 | ## Deploy Options
16 |
17 | ### Option 1: Use Railway Template (Recommended)
18 | For the easiest deployment experience, use the official Railway template:
19 | **[Deploy with Railway Template](https://railway.com/deploy/apollo-router)**
20 |
21 | ### Option 2: Clone and Deploy
22 | For more control or to use other platforms:
23 |
24 | 1. **Fork or clone this repository to your own repo**
25 | 2. **Set up your environment variables** in your deployment platform:
26 | - `APOLLO_KEY` - Your Graph API key
27 | - `APOLLO_GRAPH_REF` - Your graph reference (e.g., `my-graph@production`)
28 | 3. **Deploy using one of the options below**:
29 |
30 | **Railway**: Use the deploy button above or connect your repo in Railway
31 |
32 | **Render**: Use the deploy button above or connect your repo in Render
33 |
34 | ### Alternative Deployment Options
35 | Looking to deploy to other platforms like AWS, GCP, or Azure? Check out our comprehensive deployment guides in the [Apollo Router documentation](https://www.apollographql.com/docs/graphos/routing#deployment-guides). These guides provide step-by-step instructions for various cloud providers and deployment scenarios.
36 |
37 | ## What's included
38 |
39 | - `Dockerfile`—configured to use the Apollo Router runtime container
40 | - `render.yaml`—Render deployment configuration
41 | - `router.yaml`—sample router configuration
42 | - `.apollo/`—JSON schemas for better IDE experience
43 | - `.github/workflows/`—automated dependency updates
44 | - `.vscode/` and `.idea/`—recommended editor settings (install recommended extensions when prompted)
45 | - `renovate.json`—keeps Router version up to date
46 |
47 | ## Apollo MCP Server
48 |
49 | The Apollo Runtime container includes an optional MCP (Model Context Protocol) server that is disabled by default. This server provides AI assistants with structured access to your GraphQL schema and operations.
50 |
51 | ### Enabling MCP Server
52 |
53 | To enable the MCP server, set the `MCP_ENABLE` environment variable to `1`:
54 |
55 | **Local development:**
56 | ```bash
57 | docker run -it --env APOLLO_KEY=your-key --env APOLLO_GRAPH_REF=your-graph-ref --env MCP_ENABLE=1 -p 4000:4000 apollo-runtime
58 | ```
59 |
60 | **Railway deployment:**
61 | Add `MCP_ENABLE=1` to your environment variables in the Railway dashboard.
62 |
63 | **Render deployment:**
64 | Add `MCP_ENABLE=1` to your environment variables in the Render dashboard.
65 |
66 | ### MCP Server Features
67 |
68 | When enabled, the MCP server provides:
69 | - Schema introspection capabilities for AI assistants
70 | - Structured access to GraphQL operations
71 | - Enhanced development experience with AI tools
72 |
73 | ## Local Development
74 |
75 | **Quick test with Docker:**
76 | ```bash
77 | docker build -t apollo-runtime .
78 | docker run -it --env APOLLO_KEY=your-key --env APOLLO_GRAPH_REF=your-graph-ref -p 4000:4000 apollo-runtime
79 | ```
80 |
81 | **Using environment file:**
82 | ```bash
83 | # Create .env file (don't commit this!)
84 | echo "APOLLO_KEY=your-key-here" > .env
85 | echo "APOLLO_GRAPH_REF=your-graph-ref-here" >> .env
86 |
87 | # Run with env file
88 | docker run -it --env-file .env -p 4000:4000 apollo-runtime
89 | ```
90 |
91 | Visit `http://localhost:4000` to access your router.
92 |
93 | ## Running Locally Without GraphOS
94 |
95 | You can run the Apollo Router locally using a supergraph schema file instead of connecting to GraphOS. This is useful for:
96 | - Local development without internet connectivity
97 | - Testing federation changes before publishing
98 | - Running in air-gapped environments
99 |
100 | ### Steps to Run with Local Schema
101 |
102 | 1. **Install Rover CLI** (if not already installed):
103 | ```bash
104 | curl -sSL https://rover.apollo.dev/nix/latest | sh
105 | ```
106 |
107 | 2. **Start your subgraph services** locally (ensure they're running on the ports specified in `supergraph.yaml`)
108 |
109 | 3. **Compose your supergraph schema**:
110 | ```bash
111 | # Create the data directory if it doesn't exist
112 | mkdir -p data
113 |
114 | # Generate the supergraph schema from your subgraphs
115 | rover supergraph compose --config ./supergraph.yaml > data/schema.graphql
116 | ```
117 |
118 | 4. **Create a modified Dockerfile** for local development:
119 | ```dockerfile
120 | FROM ghcr.io/apollographql/apollo-runtime:0.0.14_router2.5.0_mcp-server0.7.0
121 |
122 | # Copy the router configuration
123 | COPY data/router.yaml /config/router_config.yaml
124 |
125 | # Copy the composed supergraph schema
126 | COPY data/schema.graphql /config/schema.graphql
127 |
128 | ENTRYPOINT ["/init"]
129 | ```
130 |
131 | 5. **Run the router without GraphOS credentials**:
132 | ```bash
133 | # Build the container
134 | docker build -t apollo-router-local .
135 |
136 | # Run without APOLLO_KEY and APOLLO_GRAPH_REF
137 | docker run -it -p 4000:4000 apollo-router-local
138 | ```
139 |
140 | ### Notes on Local Development
141 |
142 | - The `supergraph.yaml` file defines your federated architecture
143 | - Update the subgraph URLs in `supergraph.yaml` to match your local setup
144 | - Re-run `rover supergraph compose` whenever you change your subgraph schemas
145 | - The router expects the schema at `/config/schema.graphql` and config at `/config/router_config.yaml`
146 |
147 | ## Customization
148 |
149 | The runtime container comes with sensible defaults, but you can customize the router configuration:
150 |
151 | 1. **Uncomment the lines in `Dockerfile`** to use a custom configuration:
152 | ```dockerfile
153 | COPY router.yaml /config.yaml
154 | CMD ["--config", "/config.yaml"]
155 | ```
156 |
157 | 2. **Edit `router.yaml`** to customize your router behavior
158 |
159 | 3. **Rebuild and redeploy** your container
160 |
161 | ## ⚠️ Security Configuration
162 |
163 | This template includes development-friendly defaults that **are not production-ready**. Review these settings before deploying to production:
164 |
165 | ### CORS Configuration
166 | - **Current setting**: `allow_any_origin: true` - allows requests from any domain
167 | - **Security risk**: This can enable cross-site request forgery (CSRF) attacks
168 | - **For production**: Replace with specific origins in `router.yaml`:
169 | ```yaml
170 | cors:
171 | origins:
172 | - "https://yourdomain.com"
173 | - "https://app.yourdomain.com"
174 | ```
175 | - **Environment variables**: Use `${env.FRONTEND_URL}` for flexible deployments
176 |
177 | ### Other Security Considerations
178 | - **Introspection**: Enabled by default (`introspection: true`) - disable in production
179 | - **Sandbox**: disabled by default
180 | - **Subgraph errors**: All errors exposed (`include_subgraph_errors.all: true`) - consider limiting in production
181 |
182 | ## Recommended Next Steps
183 |
184 | Once you have your router deployed, consider these production-ready improvements:
185 |
186 | - [ ] **Set up CI/CD** to automatically deploy newer versions
187 | - [ ] **Enable Renovate** on your repo to keep Router up to date
188 | - [ ] **Set up deployment previews** for PRs to test changes
189 | - [ ] **Configure subgraph secrets** so only your routers can access them
190 | - [ ] **Review security settings** in your router configuration:
191 | - [ ] Configure appropriate CORS settings
192 | - [ ] Set up proper authentication/authorization
193 | - [ ] **Monitor your router** with GraphOS observability features
194 | - [ ] **Set up alerts** for important metrics and errors
195 | - [ ] **Configure caching** for better performance
196 | - [ ] **Clean up unused deployment files** (e.g., delete `render.yaml` if using Railway)
197 |
198 | ## Support
199 |
200 | For issues with:
201 | - **Apollo Router**: Check the [Apollo Router documentation](https://www.apollographql.com/docs/router/)
202 | - **GraphOS**: Visit [GraphOS documentation](https://www.apollographql.com/docs/graphos/)
203 | - ** MCP Server**: Check the [MCP Server documentation](https://www.apollographql.com/docs/apollo-mcp-server)
204 | - **IDE Support**: Check the [IDE Extensions documentation](https://www.apollographql.com/docs/apollo-server/ide-support/)
205 | - **This template**: Open an issue in this repository
206 |
207 | ## License
208 |
209 | This template is available under the MIT License. See [LICENSE](LICENSE) for details.
210 |
--------------------------------------------------------------------------------