├── .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 | 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 | 6 | 7 | 8 | 9 | 20 | 21 | 22 | 23 | 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 | [![Deploy on Railway](https://railway.app/button.svg)](https://railway.com/deploy/apollo-router) 2 | [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](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 | --------------------------------------------------------------------------------