🚀 Excited to share that JsonApi4j 1.4.0 is now live! 👉 https://lnkd.in/esH-K9AR This release adds support for JSON:API Compound Documents (https://lnkd.in/efzDhj5W) as a pluggable module. JSON:API's Compound Documents let you fetch a resource(s) and all related data in one request, eliminating extra round-trips and keeping everything perfectly consistent. It's a powerful way to deliver rich, interconnected data graphs efficiently - like getting an entire object tree in a single, clean response. Just add the plugin dependency, and your API can handle requests like: "/users/123?include=relatives.relatives&include=placeOfBirth" → Fetch a user → Their relatives (users). And relatives of those relatives (users) → And the user’s place of birth (countries) All in one request. You can fine-tune how relationships are resolved and fetched via configuration, with built-in and configurable guardrails. --- JsonApi4j is an open-source framework for building APIs aligned with the JSON:API specification, with a strong focus on developer productivity and clean architecture. If you're looking for a structured and flexible way to expose JSON:API endpoints — give it a try. Feedback and contributions are always welcome! 🙌 #java #jsonapi #opensource #api
Aliaksei Taliuk’s Post
More Relevant Posts
-
Day 31. My API worked perfectly. Until real data hit it. In development, everything looked clean. → Small dataset → Fast responses → No errors I thought I was done. Then I tested it with real data. That’s when things changed. → API became slow → Queries increased → Response time jumped → Unexpected behavior appeared Nothing was broken. But everything felt wrong. That’s when it clicked. Your code doesn’t fail in development. It fails under real conditions. What worked with 10 records didn’t work with 10,000. So I started paying attention to: → Query count → Data size → Response time → Edge cases What I learned: → Small data hides big problems → Performance issues don’t throw errors → Real testing > perfect code The hard truth: → If you don’t test with real data → You don’t really know your system Writing code is step one. Understanding how it behaves at scale is step two. What’s the sneakiest bug real data ever revealed in your code? 👇 Drop it below #SpringBoot #Java #BackendDevelopment #Performance #BuildInPublic #JavaDeveloper
To view or add a comment, sign in
-
🚀Unlocking the Power of APIs in Spring Boot: REST vs. GraphQL vs. Reactive When we talk about building APIs with #SpringBoot, there isn’t a one-size-fits-all answer. Depending on your system’s architecture, data needs, and performance requirements, you have powerful options. I’ve put together a visualization (attached below) breaking down the three major API paradigms we work with most often in the Spring ecosystem. Here’s a quick overview: 1️⃣ REST APIs (REpresentational State Transfer) The standard for years. It’s stateless, resource-oriented, and uses HTTP verbs (GET, POST, etc.) for communication. Key Annotations: @RestController, @GetMapping, @PostMapping Use Case: When you need simplicity, caching, or standard protocol adherence (like microservices communication). 2️⃣ GraphQL A query language for APIs. It lets the client define exactly what data they need, avoiding over-fetching or under-fetching. It typically operates through a single endpoint. Key Annotations: @SchemaMapping, @QueryMapping Use Case: Ideal for front-end heavy apps, complex data relationships, and mobile clients with bandwidth constraints. 3️⃣ Reactive APIs (Spring WebFlux) Built for non-blocking, asynchronous communication. It operates on a smaller number of threads to handle a massive number of concurrent requests. Key Types: Mono<T> (0-1 result), Flux<T> (0-N results) Use Case: High-concurrency systems, streaming applications, and IO-bound tasks where thread efficiency is crucial. Which approach are you using for your current projects, and what made you choose it? Let’s discuss in the comments! 👇 #java #springboot #api #restapi #graphql #webflux #microservices #backend #softwareengineering #learncoding #linkedinlearning
To view or add a comment, sign in
-
-
𝗔𝗳𝘁𝗲𝗿 𝗿𝗲𝘃𝗶𝗲𝘄𝗶𝗻𝗴 𝗵𝘂𝗻𝗱𝗿𝗲𝗱𝘀 𝗼𝗳 𝗣𝗥𝘀, 𝗜 𝗸𝗲𝗲𝗽 𝘀𝗲𝗲𝗶𝗻𝗴 𝘁𝗵𝗲 𝘀𝗮𝗺𝗲 𝗽𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲 𝗶𝘀𝘀𝘂𝗲. The developer did everything right: clean code, proper repository, correct relationships. And yet, the application was making 𝟱𝟬 𝗱𝗮𝘁𝗮𝗯𝗮𝘀𝗲 𝗾𝘂𝗲𝗿𝗶𝗲𝘀 to display a single page. Nobody noticed. Until production. This is the N+1 problem. In simple terms: instead of 1 query, your app makes 1 + N, one for each item. You don't see it in your code. You see it in your logs: 1 query for orders, then 1 query per customer. 500 orders = 501 queries. The reflex fix? Switch to EAGER loading. That's often the wrong answer. The real fix is understanding 𝘄𝗵𝗮𝘁 𝘆𝗼𝘂'𝗿𝗲 𝗹𝗼𝗮𝗱𝗶𝗻𝗴 𝗮𝗻𝗱 𝘄𝗵𝗲𝗻. Need the data always? use JOIN FETCH Need it sometimes? use @EntityGraph Need full control? use DTO query N+1 is not a JPA bug. It's a judgment problem: the difference between code that works locally and systems that perform in production. I've attached a visual breakdown of these 3 approaches with real examples. Have you ever shipped something that worked perfectly in dev… but broke in production? #Java #SpringBoot #JPA #Hibernate #Backend #Performance #SoftwareEngineering
To view or add a comment, sign in
-
🚨 Fetching all data from DB is a silent performance killer I once saw an API fetching 50,000 records in one go. 💥 Result: High memory usage Slow response Occasional crashes ✅ Fix: Used pagination: Pageable pageable = PageRequest.of(page, size); 💡 Bonus: Added sorting + limit control from API 💡 Takeaway: Never trust frontend to “handle large data” Backend should enforce limits. #Java #SpringBoot #BackendDevelopment #SoftwareEngineering #Microservices #JPA #RESTAPI #DeveloperLife #CareerGrowth
To view or add a comment, sign in
-
Day 28. I fixed the N+1 problem. Or at least… I thought I did. I had this: @Entity public class User { @OneToMany(mappedBy = "user", fetch = FetchType.LAZY) private List<Order> orders; } And I was careful. I wasn't using EAGER. I avoided obvious mistakes. Still… something felt off. The API was slow. Query count was high. That's when I checked the logs. And saw this: → 1 query to fetch users → N queries to fetch orders Again. Even after "fixing" it. Here's what was actually happening. I was mapping entities to DTOs like this: users.stream() .map(user -> new UserDTO( user.getId(), user.getName(), user.getOrders().size() // 👈 triggers lazy load per user )) .toList(); Looks harmless. But user.getOrders() → triggers lazy loading → inside a loop → causing N+1 again That's when it clicked. N+1 isn't just about fetch type. It's about when and where you access relationships. So I changed it. (see implementation below 👇) What I learned: → LAZY doesn't mean safe → DTO mapping can silently trigger queries → N+1 often hides in transformation layers The hard truth: → You think you fixed it → But it comes back in a different place Writing queries is easy. Controlling when data is accessed is what makes your backend scalable. Have you ever fixed N+1… and then seen it come back somewhere else? 👇 Drop your experience #SpringBoot #Java #Hibernate #BackendDevelopment #Performance #JavaDeveloper
To view or add a comment, sign in
-
-
Day 24. My API was fast. Until it wasn't. I had this: return ResponseEntity.ok(userRepository.findAll()); 10 users in development. Works instantly. Feels perfect. Then production happened: → 50,000 users in the database → One API call loads everything → Response time: 40ms → 8 seconds → Memory spikes → API crashes That's not a performance issue. That's a design mistake. And it was there from day one. I just couldn't see it yet. That's when it clicked: Your API should never decide how much data to return. The client should. So I added pagination. (see implementation below 👇) What changed: → Performance — stable response time → Scalability — works at 100 or 100,000 rows → Stability — no memory spikes The hard truth: → findAll() works in tutorials → It breaks in production → Pagination is not an optimization — it's a requirement Fetching data is easy. Controlling how much you fetch is what makes your API scalable. Are you still using findAll() in production? 👇 Drop it below #SpringBoot #Java #BackendDevelopment #Performance #JavaDeveloper
To view or add a comment, sign in
-
-
Solved a LeetCode hard in O(n). Couldn't use it in production. Last week I optimized an API endpoint that was timing out under load. The problem: filtering 50,000 order records to find duplicates based on multiple fields (customer_id, amount, timestamp within 5 min window). My first instinct? HashMap for O(n) lookup. Classic LeetCode muscle memory. Wrote it, tested locally flew through 100K records in 200ms. Pushed to staging. Staging worked. Production didn't. Here's what LeetCode doesn't teach you: garbage collection pauses are real. That HashMap was getting rebuilt on every request. With 50 requests/second, the young generation GC was running constantly. P99 latency spiked to 3 seconds because of GC pauses, even though P50 stayed at 200ms. Sure, I could've increased heap size. But that just delays full GC, making it worse when it finally hits. The fix: moved duplicate detection to PostgreSQL using a composite index and window function. Slightly slower average (350ms), but consistent. No GC spikes, predictable P99. LeetCode optimizes for algorithmic efficiency. Production optimizes for predictable latency under sustained load. What's an optimization that looked perfect on paper but failed under real traffic? #Java #Database #SystemDesign #LeetCode
To view or add a comment, sign in
-
One fine morning, a customer reported: “File upload sometimes fails…” Not always. Not consistently. Just sometimes. 😄 And of course, those are the best bugs. 👉 System handles 1000+ uploads daily 👉 Issue happens randomly (10–20 times) 👉 Chunk upload + merge logic (unchanged for years) 👉 Stateless architecture (or so I thought…) I jumped into debugging mode. After hours of checking: NFS configs ✅ Multi-server behavior ✅ Retry logic ✅ Logs (100 times) ✅ Observation: Chunks uploaded from Server A were not visible on Server B immediately (10–15 sec delay). Confusion level: 🔥🔥🔥 Then I did something simple (and often ignored)… 👉 Compared old vs new code Guess what changed? Just one line removed (thanks to Sonar cleanup 😅): HttpSession session = request.getSession(); And that innocent line was silently adding JSESSIONID, making requests sticky and hiding the real problem all along. 💡 So for years, reality was something like this: Stateless system... except when upload API enters the chat 😄 Or simply: stateless most of the time, secretly stateful during uploads 🎭 And the moment I removed an “unused variable”… 💥 Load balancing started behaving correctly 💥 NFS delays became visible 💥 Hidden dependency got exposed 💥 Bug said: Hello 👋 I was always here And the best realization: 👉 My application is perfectly stateless… 👉 Until the user hits the upload API and boom, it becomes emotional (stateful) 🤣🤣🤣 Lesson learned: Sometimes the bug is not in new code… It’s in removing the wrong old code 😄 And sometimes… Your system isn’t broken, your assumptions are. Still one mystery remains: 👉 Why exactly NFS behaved that way (never got a perfect answer 😅) #BackendStories #ProductionIssues #Java #NFS
To view or add a comment, sign in
-
🚀 Understanding HTTP Status Codes in REST APIs While building APIs, one important thing is not just sending data… 👉 It’s also about sending the right response status. These are called HTTP Status Codes. They help the client understand what happened with the request. 🔹 Common Status Codes ✔ 200 – OK Request was successful Example: Data fetched successfully ✔ 201 – Created New resource created Example: User registered successfully ✔ 400 – Bad Request Invalid input from client Example: Missing or wrong data ✔ 404 – Not Found Requested resource not found Example: User ID does not exist ✔ 500 – Internal Server Error Something went wrong on the server 🔹 Example in Spring Boot @GetMapping("/users/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = userService.findById(id); return ResponseEntity.ok(user); } If user is not found, we can return: return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); 💡 Why Status Codes are important ✔ Help frontend understand response ✔ Improve API communication ✔ Make APIs more professional ✔ Very common in interviews Understanding status codes helped me connect concepts like exception handling, validation, and API design. #Java #SpringBoot #BackendDevelopment #APIDesign #Learning
To view or add a comment, sign in
-
-
Day 14. My API worked perfectly. Until it hit 100 users. I had this: List<Order> orders = orderRepository.findAll(); for (Order order : orders) { System.out.println(order.getUser().getName()); } Because of queries I didn’t even know existed. Looks clean. It’s not. Here’s what was actually happening: → 1 query to fetch all orders → 1 query per order to fetch the user → 100 orders = 101 queries hitting your database That’s the N+1 problem. And it hides in plain sight. Your code looks clean. Your database is suffering. And you probably have this in your codebase right now. The fix is simple: Fetch what you need. In one query. @Query("SELECT o FROM Order o JOIN FETCH o.user") List<Order> findAllWithUser(); One query. One JOIN. Everything loaded together. What actually changes: → Performance — 101 queries becomes 1 → Scalability — works at 100 rows, breaks at 100,000 → Visibility — you won’t notice until production The hard truth: → ORMs make it easy to write slow code → Lazy loading is convenient until it isn’t → You need to know what SQL your code is generating Writing code that works is easy. Writing code that doesn’t silently destroy your database is the real skill. Are you logging your SQL queries in development? If not — you should be. 👇 Drop it below #SpringBoot #Java #Hibernate #BackendDevelopment #JavaDeveloper
To view or add a comment, sign in
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development