История IT-технологий сегодня — 25 ноября
ℹ️ Кто родился в этот день
Хиронобу Сакагути (яп. 坂口 博信 Сакагути Хиронобу, род. 25 ноября 1962) — японский геймдизайнер и программист; создатель серии Final Fantasy, повлиявшей на развитие игровых технологий и интерактивного дизайна.
🌐 Знаковые события
Не нашел((
#Biography #Birth_Date #Events #25Ноября
Хиронобу Сакагути (яп. 坂口 博信 Сакагути Хиронобу, род. 25 ноября 1962) — японский геймдизайнер и программист; создатель серии Final Fantasy, повлиявшей на развитие игровых технологий и интерактивного дизайна.
Не нашел((
#Biography #Birth_Date #Events #25Ноября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Реализация GraphQL на сервере
1. Как сервер “понимает” запросы
GraphQL — это не просто формат данных. Это полноценный язык запросов, который сервер интерпретирует строжайшим образом.
На сервере присутствуют три ключевых компонента:
Схема (Schema) — декларативное описание типов, запросов, мутаций и подписок.
Исполнитель (Executor) — механизм, который умеет разбирать, валидировать и выполнять запросы.
Резолверы (resolvers) — функции, которые реально достают данные.
Процесс обработки запроса выглядит так:
Шаг 1. Парсинг
Запрос, полученный в виде строки, разбирается в AST (абстрактное синтаксическое дерево).
GraphQL понимает только корректный язык запросов, поэтому на этом этапе запрос может быть отклонён.
Шаг 2. Валидация
AST сравнивается со схемой.
Сервер проверяет:
существуют ли указанные поля;
правильно ли переданы аргументы;
корректны ли типы;
не запрошены ли деприкейтнутые или отсутствующие типы.
Если запрос не соответствует схеме, сервер вообще не перейдёт к резолверам.
Шаг 3. Выполнение
GraphQL выполняет запрос сверху вниз, проходя по полям и вызывая резолверы там, где они определены.
GraphQL никогда не “догадывается”, где лежат данные.
Он лишь исполняет дерево запроса, вызывая привязанные функции.
2. Роль резолверов (resolvers)
Резолвер — это функция, которая отвечает на вопрос:
“Как получить данные для этого конкретного поля?”
В GraphQL у каждого поля может быть свой резолвер, хотя обычно определяют резолверы для корневых типов: Query, Mutation, Subscription.
Резолвер принимает три основных аргумента:
parent — результат предыдущего резолвера (нужен для вложенных структур);
args — аргументы, которые указал клиент;
context — общий контекст запроса (авторизация, транзакция, соединения с БД).
Пример простого резолвера на Java (Spring Boot + graphql-java-tools):
Резолвер выполняет ровно одну задачу: достать данные.
GraphQL не хранит состояние, не кэширует данные, не соединяется с БД — всё это делает твой код через резолверы.
3. Маппинг схемы на реальные источники данных
GraphQL — это уровень между клиентом и данными.
Источники могут быть любыми:
реляционная БД (PostgreSQL);
документоориентированная БД (MongoDB);
REST API других микросервисов;
gRPC сервисы;
сообщения из Kafka;
кэш Redis.
GraphQL не диктует, где должны лежать данные. Он просто обеспечивает единый интерфейс запросов.
Пример маппинга:
Резолверы:
Отсюда следует ключевой принцип:
сервер выполняет только то, что клиент запросил — ни больше, ни меньше.
#Java #middle #GraphQL
1. Как сервер “понимает” запросы
GraphQL — это не просто формат данных. Это полноценный язык запросов, который сервер интерпретирует строжайшим образом.
На сервере присутствуют три ключевых компонента:
Схема (Schema) — декларативное описание типов, запросов, мутаций и подписок.
Исполнитель (Executor) — механизм, который умеет разбирать, валидировать и выполнять запросы.
Резолверы (resolvers) — функции, которые реально достают данные.
Процесс обработки запроса выглядит так:
Шаг 1. Парсинг
Запрос, полученный в виде строки, разбирается в AST (абстрактное синтаксическое дерево).
GraphQL понимает только корректный язык запросов, поэтому на этом этапе запрос может быть отклонён.
Шаг 2. Валидация
AST сравнивается со схемой.
Сервер проверяет:
существуют ли указанные поля;
правильно ли переданы аргументы;
корректны ли типы;
не запрошены ли деприкейтнутые или отсутствующие типы.
Если запрос не соответствует схеме, сервер вообще не перейдёт к резолверам.
Шаг 3. Выполнение
GraphQL выполняет запрос сверху вниз, проходя по полям и вызывая резолверы там, где они определены.
GraphQL никогда не “догадывается”, где лежат данные.
Он лишь исполняет дерево запроса, вызывая привязанные функции.
2. Роль резолверов (resolvers)
Резолвер — это функция, которая отвечает на вопрос:
“Как получить данные для этого конкретного поля?”
В GraphQL у каждого поля может быть свой резолвер, хотя обычно определяют резолверы для корневых типов: Query, Mutation, Subscription.
Резолвер принимает три основных аргумента:
parent — результат предыдущего резолвера (нужен для вложенных структур);
args — аргументы, которые указал клиент;
context — общий контекст запроса (авторизация, транзакция, соединения с БД).
Пример простого резолвера на Java (Spring Boot + graphql-java-tools):
@Component
public class UserQueryResolver implements GraphQLQueryResolver {
private final UserService service;
public UserQueryResolver(UserService service) {
this.service = service;
}
public User userById(Long id) {
return service.findById(id);
}
}
Резолвер выполняет ровно одну задачу: достать данные.
GraphQL не хранит состояние, не кэширует данные, не соединяется с БД — всё это делает твой код через резолверы.
3. Маппинг схемы на реальные источники данных
GraphQL — это уровень между клиентом и данными.
Источники могут быть любыми:
реляционная БД (PostgreSQL);
документоориентированная БД (MongoDB);
REST API других микросервисов;
gRPC сервисы;
сообщения из Kafka;
кэш Redis.
GraphQL не диктует, где должны лежать данные. Он просто обеспечивает единый интерфейс запросов.
Пример маппинга:
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
posts: [Post!]!
}Резолверы:
@Component
public class UserResolver implements GraphQLResolver<User> {
private final PostService postService;
public UserResolver(PostService postService) {
this.postService = postService;
}
public List<Post> posts(User user) {
return postService.findByUserId(user.getId());
}
}
GraphQL вызывает posts() только если клиент запросит поле posts.
Если клиент запросит только user { id name }, резолвер posts не будет вызван вообще.
Отсюда следует ключевой принцип:
сервер выполняет только то, что клиент запросил — ни больше, ни меньше.
#Java #middle #GraphQL
👍1
4. Типичная архитектура GraphQL-сервера (Spring Boot)
Структура проекта в Java обычно такая:
Описание этапов:
Схема
Файл .graphqls описывает типы и операции.
Резолверы
Связывают поля схемы с Java-методами.
Сервисы
Логика бизнес-операций.
Репозитории
SQL/NoSQL/REST/gRPC слой, через который сервер реально получает данные.
Context
Сюда кладут:
JWT токен
объект пользователя
транзакции
общие ресурсы
5. Пример полного цикла запроса
Клиент отправляет запрос:
Что делает сервер:
Парсит запрос → AST
Проверяет типы по схеме
Вызывает QueryResolver.user(id=10)
Получает объект User
Чтобы отдать поле posts, вызывает UserResolver.posts(user)
Формирует объект ответа, возвращает клиенту JSON
Клиент всегда получает именно ту форму данных, которую указал.
Сервер не отдаёт лишних полей.
6. Почему GraphQL — это слой поверх данных, а не база данных
GraphQL:
не знает SQL;
не оптимизирует запросы;
не управляет транзакциями;
не индексирует данные;
не проверяет связи между таблицами.
GraphQL — это универсальный контракт между клиентом и сервером, а не способ хранения данных.
Он лишь обеспечивает:
строгую структуру данных (схему)
гибкие запросы от клиента
единый интерфейс ко множеству источников
оптимизацию на уровне поля (через резолверы)
Всё остальное — на стороне backend-логики.
#Java #middle #GraphQL
Структура проекта в Java обычно такая:
/graphql
/schema
schema.graphqls
/resolvers
QueryResolver.java
MutationResolver.java
UserResolver.java
PostResolver.java
/services
UserService.java
PostService.java
/repositories
UserRepository.java
PostRepository.java
Описание этапов:
Схема
Файл .graphqls описывает типы и операции.
Резолверы
Связывают поля схемы с Java-методами.
Сервисы
Логика бизнес-операций.
Репозитории
SQL/NoSQL/REST/gRPC слой, через который сервер реально получает данные.
Context
Сюда кладут:
JWT токен
объект пользователя
транзакции
общие ресурсы
5. Пример полного цикла запроса
Клиент отправляет запрос:
query {
user(id: 10) {
id
name
posts {
id
title
}
}
}Что делает сервер:
Парсит запрос → AST
Проверяет типы по схеме
Вызывает QueryResolver.user(id=10)
Получает объект User
Чтобы отдать поле posts, вызывает UserResolver.posts(user)
Формирует объект ответа, возвращает клиенту JSON
Клиент всегда получает именно ту форму данных, которую указал.
Сервер не отдаёт лишних полей.
6. Почему GraphQL — это слой поверх данных, а не база данных
GraphQL:
не знает SQL;
не оптимизирует запросы;
не управляет транзакциями;
не индексирует данные;
не проверяет связи между таблицами.
GraphQL — это универсальный контракт между клиентом и сервером, а не способ хранения данных.
Он лишь обеспечивает:
строгую структуру данных (схему)
гибкие запросы от клиента
единый интерфейс ко множеству источников
оптимизацию на уровне поля (через резолверы)
Всё остальное — на стороне backend-логики.
#Java #middle #GraphQL
👍3
Что выведет код?
#Tasks
import java.util.List;
public class Task251125 {
public static void main(String[] args) {
var list = List.of(1, 2, 3);
var number = 10;
var result = process(list, number);
System.out.println(result);
}
static var process(List<Integer> list, int n) {
var sum = 0;
for (var item : list) {
sum += item;
}
return sum * n;
}
}
#Tasks
👍2
Вопрос с собеседований
Разница между deep copy и shallow copy?🤓
Ответ:
Shallow copy копирует только верхний уровень объекта, оставляя вложенные ссылки общими.
Deep copy создает полную независимую структуру.
Первый быстрее, второй безопаснее, если требуется изоляция состояния. Выбор зависит от структуры данных и логики приложения.
#собеседование
Разница между deep copy и shallow copy?
Ответ:
Deep copy создает полную независимую структуру.
Первый быстрее, второй безопаснее, если требуется изоляция состояния. Выбор зависит от структуры данных и логики приложения.
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2