辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

Technical Exploration xLog 1 Feasibility Study

Technical Tinkering xLog 1 Feasibility Exploration

Internal Links

  • [[Technical Tinkering xLog 1 Feasibility Exploration]]
  • [[Technical Tinkering xLog 2 Understanding xlog Authentication]]
  • [[Technical Tinkering xLog 3 Implementing an Obsidian Plugin]]
  • [[Technical Tinkering xLog 4 Wrapping xLogDriver with unStorage]]
  • [[Quick Pass - CrossBell SDK Behind xLog]]
  • [[What Can We Learn from the Official XLOG Obsidian Plugin]]
  • [[Developing the Obsidian Sync To Xlog Plugin - Handling Obsidian Images]]
  • [[Quick Pass - CrossBell's Open Source Works]]
  • [[Quick Pass Obsidian Docs - Focusing on Plugin Development]]

I want to write a series of articles, tinkering with the best blog platform on Earth, xlog.app, from a technical perspective. I hope to achieve the following things (I'm starting to boast again, for new friends, this is my way of expressing myself, haha):

  • Stick to my beloved text editor, never leave obsidian, and still publish xlog blogs.
  • Access xlog without opening a web page, read other people's blogs, and interact.
  • Synchronize xlog blogs, display my own content with my own domain and server.
  • github + xlog = multi-tenant cms
  • Become a member of xlog

Now that I'm done with the introduction, let's start exploring the feasibility of the technology. In this article, we will discuss how to access xlog content through the official openapi.

Background#

As the best blog platform on Earth, xlog has two small problems: accessing it in mainland China may be a bit slow, and after migrating all the blogs to xlog, our own servers are idle.

Or to put it more simply, can we publish articles on xlog and deploy our own version? Looking ahead, who says that xlog.app is the only way to access xlog? Are we limiting the potential of xlog becoming the best headlessCMS on Earth?

So let's get started.

Technical Exploration#

From the currently available information, xlog provides multiple ways to access xlog content. Let's take a look at how to access our own data using two different methods, focusing on accessing publicly published articles.

Preparation#

The prerequisite for the following content is that you need to be a user of xlog. If you are not, please register now.

Get the public address by accessing https://xlog.app/dashboard. Follow the instructions in the screenshot below, click on the address, and it will prompt "Copied". You can consider this as the unique ID of the current user on xlog. If you have multiple roles, the ID will be different.

Take a note of it. For example, in my case, I will use it for future access: 0xA0fb033D4849b13A16690EEbdd575Dd90bF29711

image.png

Next, we will use different methods to access the data.

Accessing Data through SDK#

This method requires a Node.js environment. If you are not familiar with Node.js, please refer to the section "Accessing Data through Official API" below.

The GitHub repository for the official SDK is located at https://github.com/Crossbell-Box/crossbell.js

Critique: The official documentation is not very good. I will contribute to improving it later.

First, let's set up the project.

mkdir xlog-api-demo
cd xlog-api-demo && pnpm init
pnpm i crossbell
# Set up the TypeScript environment
pnpm i typescript tsx -D
touch index.ts

In the index.ts file, we will organize the following code:

import { createIndexer } from "crossbell";

const indexer = createIndexer();
const Address = process.env.USER_ADDRESS as `0x${string}`;

const getUserByAddress = async () => {
  const res = await indexer.character.getMany(Address);

  console.log(res);
};
getUserByAddress();

By executing the above code, you can retrieve the user's data. Pagination can be achieved using the total + cursor + limit parameters, and the cursor is reflected in the results of each request.

To query specific details, you can use the following code:

const noteId = 16;
const characterId = 53710;
const getNoteById = async (noteId: number) => {
  const res = await indexer.note.get(characterId, noteId);
  // console.log(res);
  console.log(res?.metadata?.content);
};
getNoteById(noteId);

Similar methods can be used to display various types of data.

With these two methods, we can build a personal blog, including the homepage with basic website information, the update list on the list page, and the information display on the detail page.

There are two details worth mentioning:

  • Custom embeds, such as audio and video, need to be handled separately. We can address this later.
  • Images and links are all stored on IPFS. Let's discuss this in more detail.

IPFS Protocol#

IPFS is a versatile protocol that can be used to represent various network resources with a hash or CID. Without going into details, for the web, IPFS is not the same as the HTTP protocol. To display images, there needs to be a protocol conversion process, which involves the parsing of an API gateway.

At first, I dug into the source code to find the gateway myself, but then I realized that it doesn't have to be that geeky. You can visit the webpage https://crossbell-ipfs-utils.vercel.app/img/bafkreiarfgti3xpv2oznl7rzanfbzm7gvklvcwn5poqb53wlhi3n4cwp2a, which loads images from different gateways. You can choose the one that suits you best.

image.png

Note that for faster loading speed, if you consider sub-hosting, it is obviously best to handle the resources yourself.

In addition, xlog has a dedicated utility library to handle this issue, which can be used as a programming solution. Here is a reminder:

import { ipfsFetch } from "@crossbell/ipfs-fetch";
ipfsFetch(ipfsUrl)
    .then((res) => {
      console.log(1, res);
    })
    .catch((err) => {
      console.log(3, err);
    });

These are the details. You can refer to the API documentation for more interactions.

Accessing Data through Official API#

The technical solution mentioned earlier relies on Node.js. If you are proficient in other languages or want something simpler, the official API provides a RESTful API for interaction, which has lower invasiveness.

Access the following link:

https://indexer.crossbell.io/docs

Use the address mentioned in the SDK as the entry point:

  • Access "Get characters of an address" to get the characterId /v1/addresses/{address}/characters
  • Access "Get a character by characterId" to get the user's basic information for the homepage /v1/characters/{characterId}
  • Access /v1/characters/{characterId}/notes to get the articles of the corresponding user
  • Access /v1/notes/{characterId}/{noteId} to get the details of a specific article

By using the above methods, you can achieve the same effect as the SDK.

Next, we will continue to explore how to implement backend management through authentication. In addition to reading content, we also want to be able to add, delete, modify, and query articles, creating another xlog.

Additional: Uploading Files to IPFS#

Based on the actual experience, images, audio, and video files uploaded to xlog are automatically uploaded to IPFS and the image links are replaced with IPFS links.

Currently, there are two methods: using xlog's IPFS upload protocol or using your own HTTP solution.

Here is a simple guide to uploading files to IPFS, which will help you become familiar with the xlog source code.

The idea is as follows:

  • Since image uploads are triggered by dragging and pasting, we can search for "drag/paste" in the source code to locate src/components/ui/ImageUploader.tsx#handleDrop
  • Further locate handleFile - uploadFile - useUploadFile - UploadFile
  • You can see that it is submitted to the specified interface using the POST protocol

Let's ignore the screenshots for now. I found that there is no authentication...

Conclusion#

The above is the feasibility exploration. At least we can retrieve data through the interface. In the next article, we will explore how to publish and manage articles through authentication, giving xlog the ability to become a headless CMS.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.