![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F6bcd53c3-7276-4858-81f3-f8073e79fc22%2F%25E6%2596%2587%25E5%25AD%2597%25E3%2583%25A1%25E3%2582%25A4%25E3%2583%25B3_36.png?table=block&id=66099573-25e3-4291-bac4-6c70a8cdae00&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Hello! My name is Rodrigo Ramirez; I’m a Senior Engineer at ReiwaTravel.
I had the privilege of deciding the Tech Stack for NEWT Backend and Frontend, and I introduced GraphQL for communication between our clients and our backend systems.
In this blog, I will share the core principles and best practices we learned while designing our GraphQL schema for our web and mobile apps.
🧩 NEWT Stack
Here is a quick summary of the NEWT stack for each platform:
- Backend + Web: TypeScript
- Web: React + Next.JS
- iOS: Swift
- Android: Kotlin
- API Layer: GraphQL
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2Fce638b4d-c99c-4b1a-8643-ce0bd47f2b88%2FUntitled.png?table=block&id=eb948c69-2e2a-418e-b6e4-00bcdc83c430&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
If you want to learn more about each platform, check out the following blogs
🤔 Why GraphQL?
We compared some common options before selecting GraphQL. Here’s a summary of the criteria we considered:
Candidates
Criteria | REST | GraphQL | gRPC |
Covers all platforms | ✅ | ✅ | ⚠️ |
Scales with the organization (*) | ✅ | ✅ | ✅ |
Self-documented | ⚠️ | ✅ | ✅ |
Schema-based (consistency) | ❌ | ✅ | ✅ |
Easy to learn | ✅ | ⚠️ | ⚠️ |
Production development experience | ✅ | ✅ | ❌ |
REST:
Simple to start but concerns over long-term endpoint maintainability.
GraphQL:
Met all our criteria. It has a slight learning curve, but maintaining a central schema is beneficial for future scaling.
gRPC:
Requires a proxy for web compatibility.
🔥 GraphQL Schema Design principles
The GraphQL principles we adopted at NEWT are:
- One Graph
- Demand-oriented schema design
🚪 1) One Graph
By having one graph, you maximize the value of GraphQL. The benefits include:
- Single Endpoint: Access more data and services from a single query.
- Central Data Catalog: A central catalog of all available data.
- Portability Across Teams: Code, queries, skills, and experience are portable across teams.
- Unified Access Control: Centralized management of the graph allows for unified access control policies.
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F7293e018-fe1c-4c52-b68b-b6e92fe34490%2FUntitled.png?table=block&id=ed5be408-aeb9-431f-b112-d64565abc853&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
How to scale One Graph?
Different ways to scale GraphQL include:
- …
Scaling GraphQL is primarily a backend implementation detail and does not affect clients since they continue to use a single entry point.
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F597aeb31-f96c-4169-9301-c01b8ebe6f22%2FUntitled.png?table=block&id=2be074e1-3b7c-445e-9f03-ba01517403f1&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Ref:
🎯 2) Demand oriented schema design
Demand-oriented design means designing your schema around client-side use cases. The benefits include:
Benefits:
- Simplified Schema
- Reduce Over-fetching
- Improved Developer Experience
- Easier to Understand and Maintain
- Reduce QA Costs
Key Points:
We apply three key points in this approach:
- ① Design schema around client-specific use cases
- ② Move business logic to the backend
- ③ Close collaboration with client-side engineers
① Design Schema around client-specific use cases
Do not reflect your database in your schema; use a client-first approach. This means having more specific, finer-grained mutations and queries.
❌ Database → Schema
✅ Client Use Cases → Schema
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2Fe8599237-fb6b-4e16-8771-d2f1680b68c1%2FUntitled.png?table=block&id=7980bcc8-4013-487a-b648-2faf91d2fbcb&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
An explanation about Client Use cases schema:
Type User
- Include only necessary fields used by clients.
created_at
,updated_at
,country_id
are removed, since clients do not need them.
- Use predictable values like
Enum
types. - Gender is not a string anymore; we use the Enum type.
- Country returns a
Country
type.
- Adapt fields around client use cases.
- If the client side always needs to display the full name of customers, a combined
fullName
field is better than separatefirstName
andlastName
fields.
Queries
- Focus on specific use cases rather than generic queries.
Mutations
- Tailored for each specific use case, like
signUp
instead ofcreateUser
.
② Move business logic to the Backend
Centralization of Business Logic
Implement essential logic, such as price calculations and language translations, on the server side.
Reduced Client-Side Complexity:
Client applications focus on presenting data rather than processing it.
Enhanced Security and Consistency:
Centralizing business logic on the server reduces security risks and data handling inconsistencies.
Reduce QA cost
Specific test cases can be written on the backend, reducing QA costs for client implementations.
Examples:
Case #1: Hotel Card / Spoken Languages
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F5aa6fbca-e892-4e16-a62a-1dde26557d0a%2FUntitled.png?table=block&id=55da2858-563a-4425-8427-d6ab0eb94852&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F39dc9b7f-5059-4e57-8126-40bcf46e4bab%2FUntitled.png?table=block&id=f2499e92-8a49-4814-b386-193c07d54db0&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Before:
- Logic needs to be handled on each client (Web, iOS, Android)
- More data than needed is requested from the API
- QA cost increase to confirm implementation on each client
After:
- Logic is hidden on the backend
- Client implementation is simplified
- API tests can be written to confirm use cases
- QA cost decrease
Case #2: Hotel Card / Price
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2Ff9f6fb66-fd4f-479a-8b9c-3979a0199a96%2FUntitled.png?table=block&id=f89cf360-a316-4917-8956-b5d264f3753d&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F96e9face-20a2-4800-b028-ed8e67908c15%2FUntitled.png?table=block&id=c1b4e7ab-13e5-47f6-94ca-cfa8e5bf5f54&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Before:
- The client depends on 2 fields to display the price
- The format needed to be coordinated between clients and places
- QA cost increase
After:
- Only one field is needed to display the price
- The Backend controls the format, and consistency between apps is simple
- QA cost decrease
Case #3: Hotel Card / Wishlist
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2F7cc02211-39f9-4e03-9081-c3a499c8a70a%2FUntitled.png?table=block&id=66366c3e-e3bc-491b-bcc8-38264f79bc07&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2Fbc83f93b-9370-4a45-abf4-236e119c4e81%2FUntitled.png?table=block&id=526f4604-5182-47bc-97a5-6009f918105e&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Before:
- To know if a Hotel is included inside the authenticated user Wishlist, a different query is needed
- The client needs to control the logic
- QA cost increase
After:
- Things that always need to be displayed together are together
- Client logic is simplified, and business logic is hidden on the backend
- QA cost decreases
③ Close collaboration with Client-side engineers
- Prioritize client needs across all clients.
- Consult client teams early in the API design process.
- Client teams should approve the schema before implementation.
We discuss schema changes directly on a PR, which provides:
- Discussion history
- Recorded approval
- Improved schema comments based on discussions
![notion image](https://reiwatravel.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F06681db4-d0ea-4e78-9164-a9d5fb58f475%2Ff9acce21-11d3-4577-b2b2-976d5c99a31c%2FUntitled.png?table=block&id=9d32d82b-f714-45ee-88b7-e24c6230f32f&spaceId=06681db4-d0ea-4e78-9164-a9d5fb58f475&userId=&cache=v2)
Ref:
🧑🎓 Summary
One Graph:
- 1 schema, 1 endpoint.
Demand Oriented Schema Design:
- Design based on client use cases.
- Reduce client-side complexity by moving business logic to the backend.
- Close collaboration with client-side engineers.
This blog summarizes the LT we did for NEWT Tech Talk vol.6, a monthly event held by ReiwaTravel; feel free to join online or offline!
令和トラベルでは、全ポジション、全力で仲間探しをしていますので、少しでもご興味ある方はぜひ採用ページからご連絡ください。まずは、気軽にお話を聞いていただけるミートアップも開催しています。メンバー全員で温かくお迎えいたしますので、ぜひご検討ください!
私たちが運営する海外旅行予約サービス、NEWTはこちらから。