Skip to content

Commit

Permalink
feat: blog restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
amitksingh1490 committed Aug 13, 2024
1 parent 4ea9ea4 commit d33079a
Show file tree
Hide file tree
Showing 33 changed files with 368 additions and 35 deletions.
1 change: 0 additions & 1 deletion blog/2023-graphql-conf-2023-09-29.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ slug: graphql-conf-2023
canonical_url: https://tailcall.hashnode.dev/graphql-conf-2023
---

![A Photo from GraphQL Conf 2023](../static/images/blog/graphql-conf-2023.png)
GraphQLConf 2023 wasn't just another tech conference; it was a groundbreaking event hosted by the GraphQL Foundation. Bursting with riveting workshops, enlightening talks, and interactive sponsor booths, this conference was a deep dive into the ever-evolving world of GraphQL.

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/api-orchestration-2023-06-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ slug: no-one-talks-about-api-orchestration
canonical_url: https://tailcall.hashnode.dev/no-one-talks-about-api-orchestration
---

![bff-architecture.png](../static/images/blog/bff-architecture.png)

<!-- truncate -->

<head>
Expand Down
2 changes: 0 additions & 2 deletions blog/automatic-persisted-queries-2023-08-11.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ slug: the-truth-about-scaling-automatic-persisted-queries
canonical_url: https://tailcall.hashnode.dev/the-truth-about-scaling-automatic-persisted-queries
---

![Cover Image for The truth about scaling Automatic Persisted Queries](../static/images/blog/apq-cover.png)

Persisted queries are often hailed as a solution to several challenges in GraphQL related to network performance, caching, and maintenance. However, they may not always be the silver bullet they appear to be. This post delves into the concept of persisted queries (PQ) and automatic persisted queries (APQ), highlighting the limitations and potential scaling issues that accompany these technologies.

<!-- truncate -->
Expand Down
1 change: 0 additions & 1 deletion blog/bff-challenges-2023-06-19.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ slug: unraveling-the-challenges-of-bff-federation
canonical_url: https://tailcall.hashnode.dev/unraveling-the-challenges-of-bff-federation
---

![Cover Image for Unraveling the Challenges of BFF Federation](../static/images/blog/bff-cover.png)
In our [previous](https://blog.tailcall.run/no-one-talks-about-api-orchestration) blog post, we discussed the challenges of API Orchestration and its often overlooked role in a microservices architecture. We explored how, while it serves as an abstraction for frontend apps and websites, this abstraction's performance is very sensitive to network latency and device performance thus directly impacting end-user experience. One proposed solution was to create a Backend for Frontend (BFF) layer, essentially moving the frontend abstraction to powerful servers within your VPC. Although this approach effectively addresses the user experience problem and simplifies the work of front-end engineers, it introduces a new set of challenges for the backend, leading to difficulties in scaling the monolithic solution. Here's what the BFF architecture looked like:

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/graphql-angular-clients-2024-07-20.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ slug: graphql-angular-client
image: /images/blog/angular-with-graphql.png
---

![Cover Image for Angular with GraphQL](../static/images/blog/angular-with-graphql.png)

Angular developers often face the challenge of efficiently fetching and managing data from GraphQL APIs. This comprehensive guide dives into five powerful approaches for integrating GraphQL into your Angular applications. We'll explore everything from full-featured client libraries to lightweight solutions, using a practical example of fetching post data to demonstrate each method's strengths and nuances.

<!-- truncate -->
Expand Down
2 changes: 1 addition & 1 deletion blog/graphql-introspection-security-2024-7-12.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ tags: [GraphQL, Schema, Security, Introspection]
description: Learn how attackers exploit GraphQL introspection and the battle-tested strategies to keep your data safe.
hide_table_of_contents: true
slug: graphql-introspection-security
image: /images/blog/introspection-issues.png
---

![GraphQL Introspection Security Issues](../static/images/blog/introspection-issues.png)
GraphQL has taken the API world by storm, offering developers a flexible and powerful way to interact with backend systems. But with great power comes great responsibility—especially when it comes to security.

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/graphql-schema-2024-07-11.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ hide_table_of_contents: true
slug: graphql-schema
---

![GraphQL Schema Structure](../static/images/graphql/graphql-schema-structure.png)

Designing a robust, scalable GraphQL schema is critical for building production-ready APIs that can evolve with your application's needs. In this comprehensive guide, we'll walk through the process of crafting a GraphQL schema for a real-world application, highlighting best practices and considerations along the way.

If you are thinking how we could possibly cover all of the lovely intricacies associated with this topic in one go, you are right, we can't and so we are not! We have created an amazing series to take you through the nuances of working with GraphQL schemas.
Expand Down
4 changes: 2 additions & 2 deletions blog/graphql-schema-part-2-1-2024-07-21.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ hide_table_of_contents: true
slug: graphql-schema-part-2-1
---

<!-- truncate -->

import Quiz from "../src/components/quiz/quiz.tsx"

## What Do You Already Know? 🧠💫
Expand Down Expand Up @@ -74,8 +76,6 @@ import Quiz from "../src/components/quiz/quiz.tsx"

In our [previous post](/blog/graphql-schema), we learned scalable GraphQL schema is critical for building production-ready APIs that can evolve with your application's needs.

<!-- truncate -->

In this post, we will dive deeper into how to **continuously** evolve your schema to meet your application's changing requirements without hard-coded versioning.

## Adding Without Breaking: The Art of Additive Changes
Expand Down
4 changes: 2 additions & 2 deletions blog/graphql-schema-part-2-2-2024-07-22.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ hide_table_of_contents: true
slug: graphql-schema-part-2-2
---

<!-- truncate -->

import Quiz from "../src/components/quiz/quiz.tsx"

## What Do You Already Know? 🧠💫
Expand Down Expand Up @@ -67,8 +69,6 @@ import Quiz from "../src/components/quiz/quiz.tsx"
]}
/>

<!-- truncate -->

## Modifying Without Breaking: Navigating the Modification Minefield

In our [previous post](/blog/graphql-schema-part-2-1), we explored how to make additive changes to your GraphQL schema without causing disruptions. Now, we'll dive into the tricky territory of modifying existing schema elements.
Expand Down
3 changes: 2 additions & 1 deletion blog/graphql-schema-part-2-3-2024-07-23.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ hide_table_of_contents: true
slug: graphql-schema-part-2-3
---

<!-- truncate -->

import Quiz from "../src/components/quiz/quiz.tsx"

## What Do You Already Know? 🧠💫
Expand Down Expand Up @@ -87,7 +89,6 @@ import Quiz from "../src/components/quiz/quiz.tsx"
},
]}
/>
<!-- truncate -->

## Removing Without Breaking: The Subtraction Subterfuge

Expand Down
1 change: 0 additions & 1 deletion blog/graphql-vs-openapi-part-1-2024-07-29.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ authors:
image_url: https://avatars.githubusercontent.com/u/68141773?v=4
---

![OpenAPI vs GraphQL](../static/images/blog/openapi-vs-graphql-part1.png)
In today's ever-evolving technological landscape, APIs play a crucial role in enabling software systems to communicate with each other. Among the myriad of API specifications available, GraphQL and OpenAPI stand out as prominent choices, each offering unique advantages and addressing different needs.

<!-- truncate -->
Expand Down
1 change: 0 additions & 1 deletion blog/graphql-vs-openapi-part-2-2024-07-30.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ authors:
image_url: https://avatars.githubusercontent.com/u/68141773?v=4
---

![OpenAPI vs GraphQL](../static/images/blog/openapi-vs-graphql-part2.png)
Welcome back to our API comparison series! In [Part 1](/blog/graphql-vs-openapi-part-1), we covered the fundamentals of GraphQL and OpenAPI, focusing on their core concepts, type systems, and schema definitions. Now, in Part 2, we will dive deeper into the performance, flexibility, and ecosystems of these API specifications.

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/graphql-vs-openapi-part-3-2024-07-31.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ authors:
image_url: https://avatars.githubusercontent.com/u/68141773?v=4
---

![OpenAPI vs GraphQL](../static/images/blog/openapi-vs-graphql-part3.png)

Welcome to Part 3 of our API comparison series! So far, we've discussed the basics and compared the performance and flexibility of GraphQL and OpenAPI. In this installment, we will focus on exploring their security features, tooling support, and future prospects.

<!-- truncate -->
Expand Down
6 changes: 2 additions & 4 deletions blog/graphql-vs-rest-vs-grpc-2024-03-30.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,15 @@ slug: graphql-vs-rest-vs-grpc
canonical_url: https://tailcall.hashnode.dev/graphql-vs-rest-vs-grpc
---

![Cover Image for GraphQL vs REST vs gRPC - an unfair comparison](../static/images/blog/gql-vs-rest-vs-grpc-cover.png)

<!-- truncate -->

<head>
<link rel="canonical" href="https://tailcall.hashnode.dev/graphql-vs-rest-vs-grpc"/>
<title>GraphQL vs REST vs gRPC - an unfair comparison</title>
</head>

Since its inception, GraphQL has steadily gained popularity, often finding itself at the center of comparisons with other data query and manipulation languages such as REST and gRPC. The internet is replete with articles debating the merits and demerits of each, with some even questioning the viability of GraphQL. However, this discourse misses a crucial point: the unique strengths of GraphQL. This article aims to illuminate the distinct advantages GraphQL offers, particularly in addressing a common but complex challenge known as impedance mismatch.

<!-- truncate -->

Impedance mismatch refers to the discordance between the capabilities of an existing API and the ideal features required for a specific use case. From the perspective of a platform engineer, the goal is to develop APIs that cater to a broad range of needs. Yet, crafting a unique API for every conceivable requirement is neither practical nor efficient. Consequently, engineers often end up creating generalized APIs. However, as a consumer, you might find these APIs lacking in some respects while being superfluous in others. Furthermore, as your needs evolve, so does your notion of the ideal API, exacerbating this mismatch. Herein lies the brilliance of GraphQL: it offers a framework for structuring data exposure and queries that significantly mitigates this issue.

The GraphQL specification introduces the concept of viewing data as a graph composed of nodes, which represent domain entities for a business, interconnected by relationships that define their interactions. For instance, in the development of a social network, a user entity might have the ability to create a post, which in turn could receive comments, illustrating the interconnected nature of data entities.
Expand Down
4 changes: 1 addition & 3 deletions blog/graphql-vue-clients-2024-08-01.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ title: "GraphQL in Vue: 5 Best Approaches for Data Fetching"
description: "Unleash the power of GraphQL in your Vue applications! Explore the top 5 methods for seamless data fetching, including in-depth comparisons and error handling strategies."
sidebar_label: "GraphQL in Vue"
slug: graphql-vue-client
image: /image/blog/vue-with-graphql.png
image: /images/blog/vue-with-graphql.png
---

![Cover Image for Vue in GraphQL](../static/images/blog/vue-with-graphql.png)

Are you tired of wrestling with complex data fetching logic in your Vue applications? If you've ever felt like you're battling an octopus to retrieve the data you need, then GraphQL is here to be your data fetching hero!

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/grpc-vs-graphql-2024-07-26.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ hide_table_of_contents: true
slug: graphql-vs-grpc
---

![banner](/images/graphql/graphql-vs-grpc.png)

While REST has been the go-to for API development, gRPC and GraphQL are stepping in as game-changing contenders.

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/guide-on-graphiql-2024-07-24.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ slug: exploring-graphiql
tags: [GraphQL, GraphiQL, IDE, debugging]
---

![Cover image for Exploring GraphiQL](../static/images/graphql/graphiql-cover.png)

Meet GraphiQL, a true life-saver for testing, debugging and having fun with your graphQL server.

<!-- truncate -->
Expand Down
1 change: 0 additions & 1 deletion blog/no-code-graphql-2024-05-30.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ slug: writing-a-graphql-backend-by-hand-is-long-gone
canonical_url: https://tailcall.hashnode.dev/writing-a-graphql-backend-by-hand-is-long-gone
---

![Cover Image for Writing a GraphQL Backend by Hand is Long Gone](../static/images/blog/no-code-cover.png)
Building a GraphQL backend by hand might seem like a noble pursuit, but the landscape of API development is evolving rapidly, and so are the challenges that come with it. Today, the process is often fraught with complexity, performance bottlenecks, security vulnerabilities, and reliability issues. Yet again, we had a developer expressing [frustration](https://bessey.dev/blog/2024/05/24/why-im-over-graphql/) about the issues with GraphQL and the reasons for leaving our mighty ship. I wish to dive deeper into these challenges and explore why the future points towards automated, high-performance solutions.

<!-- truncate -->
Expand Down
1 change: 0 additions & 1 deletion blog/tailcall-n+1-working-2024-08-04.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ slug: tailcall-n+1-identification-algorithm
image: /images/blog/n+1-identification-cover.png
---

![Cover image for N+1 Identification in GraphQL](../static/images/blog/n+1-identification-cover.png)
As a developer working with GraphQL, you're likely familiar with the concept of N+1 issues. If not, you're in for a treat - check out our [N+1 guide!](/docs/graphql-n-plus-one-problem-solved-tailcall)

<!-- truncate -->
Expand Down
2 changes: 0 additions & 2 deletions blog/what-is-grpc-2024-07-13.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ hide_table_of_contents: true
slug: what-is-grpc
---

![gRPC Logo](/images/docs/grpc_logo.png)

gRPC is an open-source RPC (Remote Procedure Call) framework initially developed by Google. It enables efficient communication between services across different environments, utilizing a binary serialization format called Protocol Buffers (Protobuf) over HTTP/2.

<!-- truncate -->
Expand Down
6 changes: 6 additions & 0 deletions src/theme/BlogPostItem/Container/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from "react"
import type {Props} from "@theme/BlogPostItem/Container"

export default function BlogPostItemContainer({children, className}: Props): JSX.Element {
return <article className={className}>{children}</article>
}
19 changes: 19 additions & 0 deletions src/theme/BlogPostItem/Content/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react"
import clsx from "clsx"
import {blogPostContainerID} from "@docusaurus/utils-common"
import {useBlogPost} from "@docusaurus/theme-common/internal"
import MDXContent from "@theme/MDXContent"
import type {Props} from "@theme/BlogPostItem/Content"

export default function BlogPostItemContent({children, className}: Props): JSX.Element {
const {isBlogPostPage} = useBlogPost()
return (
<div
// This ID is used for the feed generation to locate the main content
id={isBlogPostPage ? blogPostContainerID : undefined}
className={clsx("markdown", className)}
>
<MDXContent>{children}</MDXContent>
</div>
)
}
36 changes: 36 additions & 0 deletions src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from "react"
import Translate, {translate} from "@docusaurus/Translate"
import Link from "@docusaurus/Link"
import type {Props} from "@theme/BlogPostItem/Footer/ReadMoreLink"

function ReadMoreLabel() {
return (
<b>
<Translate
id="theme.blog.post.readMore"
description="The label used in blog post item excerpts to link to full blog posts"
>
Read More
</Translate>
</b>
)
}

export default function BlogPostItemFooterReadMoreLink(props: Props): JSX.Element {
const {blogPostTitle, ...linkProps} = props
return (
<Link
aria-label={translate(
{
message: "Read more about {title}",
id: "theme.blog.post.readMoreLabel",
description: "The ARIA label for the link to full blog posts from excerpts",
},
{title: blogPostTitle},
)}
{...linkProps}
>
<ReadMoreLabel />
</Link>
)
}
69 changes: 69 additions & 0 deletions src/theme/BlogPostItem/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React from "react"
import clsx from "clsx"
import {useBlogPost} from "@docusaurus/theme-common/internal"
import {ThemeClassNames} from "@docusaurus/theme-common"
import EditMetaRow from "@theme/EditMetaRow"
import TagsListInline from "@theme/TagsListInline"
import ReadMoreLink from "@theme/BlogPostItem/Footer/ReadMoreLink"

export default function BlogPostItemFooter(): JSX.Element | null {
const {metadata, isBlogPostPage} = useBlogPost()
const {tags, title, editUrl, hasTruncateMarker, lastUpdatedBy, lastUpdatedAt} = metadata

// A post is truncated if it's in the "list view" and it has a truncate marker
const truncatedPost = !isBlogPostPage && hasTruncateMarker

const tagsExists = tags.length > 0

const renderFooter = tagsExists || truncatedPost || editUrl

if (!renderFooter) {
return null
}

// BlogPost footer - details view
if (isBlogPostPage) {
const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy)

return (
<footer className="docusaurus-mt-lg">
{tagsExists && (
<div className={clsx("row", "margin-top--sm", ThemeClassNames.blog.blogFooterEditMetaRow)}>
<div className="col">
<TagsListInline tags={tags} />
</div>
</div>
)}
{canDisplayEditMetaRow && (
<EditMetaRow
className={clsx("margin-top--sm", ThemeClassNames.blog.blogFooterEditMetaRow)}
editUrl={editUrl}
lastUpdatedAt={lastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
/>
)}
</footer>
)
}
// BlogPost footer - list view
else {
return (
<footer className="row docusaurus-mt-lg">
{tagsExists && (
<div className={clsx("col", {"col--9": truncatedPost})}>
<TagsListInline tags={tags} />
</div>
)}
{truncatedPost && (
<div
className={clsx("col text--right", {
"col--3": tagsExists,
})}
>
<ReadMoreLink blogPostTitle={title} to={metadata.permalink} />
</div>
)}
</footer>
)
}
}
37 changes: 37 additions & 0 deletions src/theme/BlogPostItem/Header/Author/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from "react"
import clsx from "clsx"
import Link, {type Props as LinkProps} from "@docusaurus/Link"

import type {Props} from "@theme/BlogPostItem/Header/Author"

function MaybeLink(props: LinkProps): JSX.Element {
if (props.href) {
return <Link {...props} />
}
return <>{props.children}</>
}

export default function BlogPostItemHeaderAuthor({author, className}: Props): JSX.Element {
const {name, title, url, imageURL, email} = author
const link = url || (email && `mailto:${email}`) || undefined
return (
<div className={clsx("avatar margin-bottom--sm", className)}>
{imageURL && (
<MaybeLink href={link} className="avatar__photo-link">
<img className="avatar__photo" src={imageURL} alt={name} />
</MaybeLink>
)}

{name && (
<div className="avatar__intro">
<div className="avatar__name">
<MaybeLink href={link}>
<span>{name}</span>
</MaybeLink>
</div>
{title && <small className="avatar__subtitle">{title}</small>}
</div>
)}
</div>
)
}
Loading

0 comments on commit d33079a

Please sign in to comment.