> ## Documentation Index
> Fetch the complete documentation index at: https://swift-graphql.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Creating Custom Scalars

SwiftGraphQL by default encodes all fields that reference unconfigured scalars as `AnyCodable` values. For easier decoding and better type support you can, however, create custom `GraphQLScalar` structures.

To create a custom scalar, you need to create a structure that conforms to the `GraphQLScalar` protocol.

```swift theme={null}
/// Protocol that a custom scalar should implement to be used with SwiftGraphQL.
public protocol GraphQLScalar: Encodable {

    /// A decoder from the any-type codable value.
    init(from: AnyCodable) throws

    /// Default value that mocks the returned value.
    static var mockValue: Self { get }
}
```

> It doesn't matter where you implement the conformance as long as it's in the same project as the generated code.

Because `GraphQLScalar` uses the `Encodable` protocol to encode the value, you might need to customize how `JSONEncoder` encodes the built-in value in case you are mapping a custom scalar to a built-in type. Depending on your target, you should either

* pass a custom `JSONEncoder` as a paramater to the `URLRequest.query` method,
* provide a custom `encoder` to `FetchExchange`
* modify the `encoder` in `GraphQLWebSocketConfiguration`.

```swift theme={null}
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601

// Vanilla Request
let request = URLRequest(url: API_ENDPOINT)
request.query(selection, encoder: encoder)

// FetchExchange
let client = SwiftGraphQLClient.Client(
    request: API_ENDPOINT,
    exchanges: [
        FetchExchange(encoder: encoder)
    ]
)

// GraphQLWebSocketConfiguration
let config = GraphQLWebSocketConfiguration()
config.encoder = encoder

let ws = GraphQLWebSocket(request: request, config: config)
```

### Example DateTime Scalar

```swift theme={null}
import Foundation
import GraphQL
import SwiftGraphQL

extension Date: GraphQLScalar {
    public init(from codable: AnyCodable) throws {
        guard let raw = codable.value as? String else {
            throw DateTimeScalarDecodingError.invalidType
        }

        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")

        // https://stackoverflow.com/questions/39433852/parsing-a-iso8601-string-to-date-in-swift
        formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

        guard let date = formatter.date(from: raw) else {
            throw DateTimeScalarDecodingError.invalidValue
        }

        self = date
    }

    public static var mockValue = Date.now
}

enum DateTimeScalarDecodingError: Error {
    case invalidType
    case invalidValue
}
```

> Don't forget to add your scalar mapping to code generator options!
