Help me mijn GraphQL API te verbeteren met aangepaste scalair types
description
Door aangepaste scalair types te gebruiken, kun je betere gegevensintegriteit garanderen, validatieprocessen verbeteren en je API expressiever en gebruiksvriendelijker maken.
prompt
try_prompt
Help me implementeren van aangepaste scalair types in mijn GraphQL API met de volgende details: - Scalar Type Naam: {{scalar_type_naam}} (bijv. DateTime, Email) - Validatie Logica: {{validatie_logica}} (bijv. regex patronen, b ... more
generate_helper
...
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een stapsgewijze gids om een aangepaste scalar type (zoals DateTime of Email) te implementeren in je GraphQL API, inclusief validatie en gebruik in queries/mutations.
---
### 1. Aangepaste Scalar Type Definiëren
**Voorbeeld: Email scalar**
#### a. In je GraphQL schema (.graphql of SDL)
```graphql
scalar Email
type Mutation {
registerUser(email: Email!, password: String!): User
}
```
Hier definieer je de scalar `Email` en gebruik je deze in een mutation.
---
### 2. Scalar Type Implementeren (bijvoorbeeld in JavaScript/Node.js met `graphql`)
Gebruik bijvoorbeeld `graphql` en `graphql-tools`. Hieronder een voorbeeld voor een custom scalar `Email`.
```js
const { GraphQLScalarType, Kind } = require('graphql');
const EmailScalar = new GraphQLScalarType({
name: 'Email',
description: 'Een geldig emailadres volgens regex patroon.',
serialize(value) {
// Output naar client
return value;
},
parseValue(value) {
// Input van client
if (typeof value !== 'string') {
throw new Error('Email moet een string zijn.');
}
if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(value)) {
throw new Error('Ongeldig emailadres.');
}
return value;
},
parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw new Error('Email moet een string zijn.');
}
if (!/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(ast.value)) {
throw new Error('Ongeldig emailadres.');
}
return ast.value;
}
});
module.exports = {
EmailScalar,
};
```
### 3. Toevoegen aan je Schema
In je schema-setup:
```js
const { makeExecutableSchema } = require('graphql-tools');
const typeDefs = `
scalar Email
type User {
id: ID!
email: Email!
}
type Mutation {
registerUser(email: Email!, password: String!): User
}
`;
const resolvers = {
Email: EmailScalar,
Mutation: {
registerUser: (_, { email, password }) => {
// Hier kun je je registratie logica plaatsen
// Bijvoorbeeld: opslaan in database
return { id: '1', email };
}
}
};
const schema = makeExecutableSchema({ typeDefs, resolvers });
```
---
### 4. Gebruik in Queries en Mutations
**Voorbeeld mutation in GraphQL:**
```graphql
mutation {
registerUser(email: "voorbeeld@domein.com", password: "veiligWachtwoord123") {
id
email
}
}
```
De scalar `Email` zorgt dat alleen geldige emails worden geaccepteerd. Als de email niet voldoet, geeft de server een fout.
---
### 5. Voor DateTime scalar (optioneel)
Wil je een DateTime scalar implementeren? Gebruik bijvoorbeeld ISO 8601 formaat.
#### a. Scalar definitie
```js
const DateTimeScalar = new GraphQLScalarType({
name: 'DateTime',
description: 'Een ISO 8601 datum/tijd string.',
serialize(value) {
// Uitgaande data (server naar client)
return value;
},
parseValue(value) {
// Inkomende data (client naar server)
if (typeof value !== 'string') {
throw new Error('DateTime moet een string zijn.');
}
const date = new Date(value);
if (isNaN(date.getTime())) {
throw new Error('Ongeldig DateTime formaat.');
}
return date.toISOString();
},
parseLiteral(ast) {
if (ast.kind !== Kind.STRING) {
throw new Error('DateTime moet een string zijn.');
}
const date = new Date(ast.value);
if (isNaN(date.getTime())) {
throw new Error('Ongeldig DateTime formaat.');
}
return date.toISOString();
}
});
```
Gebruik deze scalar eveneens in je schema en resolvers.
---
### Samenvatting:
- Definieer een scalar in je SDL.
- Implementeer de validatielogica in `parseValue` en `parseLiteral`.
- Voeg de scalar toe aan je resolvers.
- Gebruik de scalar in je schema bij de velden en mutations.
---
### Extra Tips
- Documenteer je scalars duidelijk zodat frontend-ontwikkelaars weten welke formaten ze moeten gebruiken.
- Test je scalars met verschillende inputwaarden om zeker te zijn dat validatie correct werkt.
- Overweeg het gebruik van bestaande packages zoals `graphql-scalars` voor veelgebruikte scalars.
---
Heeft u nog verdere vragen of hulp bij specifieke codevoorbeelden?
provider: deepseek
model: deepseek-chat
Hier is een complete implementatiegids voor een aangepaste `DateTime` scalar in je GraphQL API:
## 1. Aangepaste Scalar Implementatie
```javascript
const { GraphQLScalarType, Kind } = require('graphql');
// DateTime Scalar implementatie
const DateTimeScalar = new GraphQLScalarType({
name: 'DateTime',
description: 'Een aangepaste DateTime scalar die ISO 8601 strings accepteert',
serialize(value) {
// Wordt aangeroepen wanneer de waarde naar de client wordt gestuurd
if (value instanceof Date) {
return value.toISOString();
}
if (typeof value === 'string') {
const date = new Date(value);
if (isNaN(date.getTime())) {
throw new Error(`Ongeldige DateTime waarde: ${value}`);
}
return date.toISOString();
}
throw new Error(`DateTime kan niet geserialiseerd worden: ${value}`);
},
parseValue(value) {
// Wordt aangeroepen wanneer de waarde van variabelen komt
if (typeof value === 'string') {
const date = new Date(value);
if (isNaN(date.getTime())) {
throw new Error(`Ongeldige DateTime waarde: ${value}`);
}
return date;
}
throw new Error(`DateTime moet een string zijn, kreeg: ${typeof value}`);
},
parseLiteral(ast) {
// Wordt aangeroepen wanneer de waarde inline in de query staat
if (ast.kind === Kind.STRING) {
const date = new Date(ast.value);
if (isNaN(date.getTime())) {
throw new Error(`Ongeldige DateTime waarde: ${ast.value}`);
}
return date;
}
throw new Error(`DateTime moet een string zijn, kreeg: ${ast.kind}`);
}
});
```
## 2. Email Scalar Implementatie (op basis van je regex)
```javascript
const EmailScalar = new GraphQLScalarType({
name: 'Email',
description: 'Een aangepaste Email scalar met validatie',
serialize(value) {
// Valideer en retourneer de email
this.validateEmail(value);
return value;
},
parseValue(value) {
// Valideer email van variabelen
this.validateEmail(value);
return value;
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING) {
this.validateEmail(ast.value);
return ast.value;
}
throw new Error('Email moet een string zijn');
},
validateEmail(email) {
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
if (!emailRegex.test(email)) {
throw new Error(`Ongeldig email formaat: ${email}`);
}
}
});
```
## 3. Schema Integratie
```javascript
const { gql } = require('apollo-server-express');
const typeDefs = gql`
scalar DateTime
scalar Email
type User {
id: ID!
email: Email!
createdAt: DateTime!
updatedAt: DateTime!
}
input RegisterInput {
email: Email!
password: String!
birthDate: DateTime
}
type Mutation {
registerUser(input: RegisterInput!): User
updateUserEmail(id: ID!, email: Email!): User
}
type Query {
getUser(id: ID!): User
getUsersCreatedAfter(date: DateTime!): [User!]!
}
`;
```
## 4. Resolver Implementatie
```javascript
const resolvers = {
DateTime: DateTimeScalar,
Email: EmailScalar,
Mutation: {
registerUser: async (_, { input }) => {
// De email is al gevalideerd door de scalar!
const user = {
id: '1',
email: input.email,
createdAt: new Date(),
updatedAt: new Date(),
birthDate: input.birthDate || null
};
// Sla gebruiker op in database
return user;
},
updateUserEmail: async (_, { id, email }) => {
// Email is automatisch gevalideerd
const updatedUser = {
id,
email,
updatedAt: new Date()
};
return updatedUser;
}
},
Query: {
getUsersCreatedAfter: async (_, { date }) => {
// 'date' is nu een Date object dankzij de scalar
// Zoek gebruikers aangemaakt na deze datum
return []; // Je database logica hier
}
}
};
```
## 5. Server Setup
```javascript
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
// Context logica
return { user: req.user };
}
});
const app = express();
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () => {
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`);
});
```
## 6. Gebruiksvoorbeelden
### Mutation voor registratie:
```graphql
mutation RegisterUser {
registerUser(input: {
email: "gebruiker@voorbeeld.nl"
password: "veiligwachtwoord"
birthDate: "1990-01-15T00:00:00.000Z"
}) {
id
email
createdAt
}
}
```
### Query met DateTime filter:
```graphql
query GetRecentUsers {
getUsersCreatedAfter(date: "2024-01-01T00:00:00.000Z") {
id
email
createdAt
}
}
```
### Fout scenario's:
```graphql
# Dit zal fouten geven:
mutation InvalidEmail {
registerUser(input: {
email: "ongeldig-email" # ❌ Ongeldig email formaat
password: "wachtwoord"
}) {
id
}
}
mutation InvalidDate {
registerUser(input: {
email: "gebruiker@voorbeeld.nl"
password: "wachtwoord"
birthDate: "dit-is-geen-datum" # ❌ Ongeldige DateTime
}) {
id
}
}
```
## Belangrijke Punten:
1. **Validatie**: De email wordt automatisch gevalideerd tegen je regex patroon
2. **Type Safety**: DateTime waarden worden geconverteerd naar Date objecten
3. **Foutafhandeling**: Duidelijke foutmeldingen bij ongeldige waarden
4. **Flexibiliteit**: Werkt met zowel inline waarden als variabelen
Deze implementatie zorgt voor robuuste type-veiligheid en automatische validatie in je GraphQL API!

