Interfaces

An interface is an abstract type that defines a certain set of fields that an object type or another interface must include to implement the interface.

SDL
interface Message {
author: User!
createdAt: DateTime!
}
type TextMessage implements Message {
author: User!
createdAt: DateTime!
content: String!
}

Clients can query fields returning an interface like the following.

GraphQL
{
messages {
author {
name
}
... on TextMessage {
content
}
}
}

Learn more about interfaces here.

Usage

Interfaces can be defined like the following.

C#
[InterfaceType("Message")]
public interface IMessage
{
User Author { get; set; }
DateTime CreatedAt { get; set; }
}
public class TextMessage : IMessage
{
public User Author { get; set; }
public DateTime CreatedAt { get; set; }
public string Content { get; set; }
}
public class Query
{
public IMessage[] GetMessages()
{
// Omitted code for brevity
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddType<TextMessage>();
}
}

We can also use classes to define an interface.

C#
[InterfaceType]
public abstract class Message
{
public User SendBy { get; set; }
public DateTime CreatedAt { get; set; }
}
public class TextMessage : Message
{
public string Content { get; set; }
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddGraphQLServer()
// ...
.AddType<TextMessage>();
}
}

Note: We have to explicitly register the interface implementations:

C#
services.AddGraphQLServer().AddType<TextMessageType>()

Interfaces implementing interfaces

Interfaces can also implement other interfaces.

SDL
interface Message {
author: User
}
interface DatedMessage implements Message {
createdAt: DateTime!
author: User
}
type TextMessage implements DatedMessage & Message {
author: User
createdAt: DateTime!
content: String
}

We can implement this like the following.

C#
[InterfaceType("Message")]
public interface IMessage
{
User Author { get; set; }
}
[InterfaceType("DatedMessage")]
public interface IDatedMessage : IMessage
{
DateTime CreatedAt { get; set; }
}
public class TextMessage : IDatedMessage
{
public User Author { get; set; }
public DateTime CreatedAt { get; set; }
public string Content { get; set; }
}
public class Query
{
public IMessage[] GetMessages()
{
// Omitted code for brevity
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services
.AddGraphQLServer()
.AddQueryType<Query>()
.AddType<IDatedMessage>()
.AddType<TextMessage>();
}
}

Note: We also have to register the DatedMessage interface manually, if we do not expose it through a field directly:

C#
services.AddGraphQLServer().AddType<DatedMessageType>()

Dynamic fields

We can also declare additional dynamic fields (resolvers) on our interfaces.

C#
[InterfaceType("Message")]
public interface IMessage
{
User Author { get; set; }
DateTime GetCreatedAt();
}
public class TextMessage : IMessage
{
public User Author { get; set; }
public DateTime GetCreatedAt()
{
// Omitted code for brevity
}
}