| 915 | } |
| 916 | |
| 917 | func (s *Server) SchemaForView(view call.View) *ast.Schema { |
| 918 | s.reconcileInterfaceImplsIfDirty() |
| 919 | s.installLock.RLock() |
| 920 | defer s.installLock.RUnlock() |
| 921 | s.schemaLock.Lock() |
| 922 | defer s.schemaLock.Unlock() |
| 923 | |
| 924 | if s.schemaOnces[view] == nil { |
| 925 | s.schemaOnces[view] = &sync.Once{} |
| 926 | } |
| 927 | |
| 928 | s.schemaOnces[view].Do(func() { |
| 929 | queryType := s.Root().Type().Name() |
| 930 | schema := &ast.Schema{ |
| 931 | Types: make(map[string]*ast.Definition), |
| 932 | PossibleTypes: make(map[string][]*ast.Definition), |
| 933 | } |
| 934 | sortutil.RangeSorted(s.objects, func(_ string, t ObjectType) { |
| 935 | def := definition(ast.Object, t, view) |
| 936 | if def.Name == queryType { |
| 937 | schema.Query = def |
| 938 | } |
| 939 | schema.AddTypes(def) |
| 940 | schema.AddPossibleType(def.Name, def) |
| 941 | |
| 942 | // Also register this object as a possible type for each interface it |
| 943 | // declares via def.Interfaces. |
| 944 | for _, ifaceName := range def.Interfaces { |
| 945 | schema.AddPossibleType(ifaceName, def) |
| 946 | } |
| 947 | }) |
| 948 | // Emit interface definitions. |
| 949 | sortutil.RangeSorted(s.interfaces, func(_ string, iface *Interface) { |
| 950 | def := iface.Definition(view) |
| 951 | schema.AddTypes(def) |
| 952 | }) |
| 953 | sortutil.RangeSorted(s.scalars, func(name string, t ScalarType) { |
| 954 | if filter, ok := s.scalarFilters[name]; ok && !filter.Contains(view) { |
| 955 | return |
| 956 | } |
| 957 | def := definition(ast.Scalar, t, view) |
| 958 | schema.AddTypes(def) |
| 959 | schema.AddPossibleType(def.Name, def) |
| 960 | }) |
| 961 | sortutil.RangeSorted(s.typeDefs, func(_ string, t TypeDef) { |
| 962 | def := t.TypeDefinition(view) |
| 963 | schema.AddTypes(def) |
| 964 | schema.AddPossibleType(def.Name, def) |
| 965 | }) |
| 966 | schema.Directives = map[string]*ast.DirectiveDefinition{} |
| 967 | sortutil.RangeSorted(s.directives, func(n string, d DirectiveSpec) { |
| 968 | schema.Directives[n] = d.DirectiveDefinition(view) |
| 969 | }) |
| 970 | h := xxh3.New() |
| 971 | json.NewEncoder(h).Encode(schema) |
| 972 | s.schemas[view] = schema |
| 973 | s.schemaDigests[view] = digest.NewDigest(hashutil.XXH3, h) |
| 974 | }) |