Zenn
👻

GakuNin RDMのAPIを用いて、連携したストレージのファイルを検索する

2025/03/21に公開

概要

以下の記事で、GakuNin RDMのAPIを用いたアプリケーション構築について紹介しました。

https://zenn.dev/nakamura196/articles/e90f671b0565d2

本記事では、GakuNin RDMのAPIを用いて、連携したストレージのファイルを検索する方法を紹介します。

実装例

次のような形で、検索APIを実装しました。なお、https://rdm.nii.ac.jp/api/v1/search/file/にクライアントから直接アクセスした際には、CORSによるエラーが発生したため、Next.jsのAPI Routesとして実装しています。

/src/app/api/search/route.ts
import { NextResponse } from "next/server";

import { authOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { getServerSession } from "next-auth";

export async function GET(req: Request) {
  const session = await getServerSession(authOptions);

  // URLからクエリパラメータを取得
  const url = new URL(req.url);
  const query = url.searchParams.get("filter[fulltext]") || "";
  const offset = parseInt(url.searchParams.get("page[offset]") || "0", 10);
  const size = parseInt(url.searchParams.get("page[limit]") || "20", 10);

  const accessToken = session?.accessToken;

  const apiUrl = "https://rdm.nii.ac.jp/api/v1/search/file/";

  const params = {
    api_version: { vendor: "grdm", version: 2 },
    sort: "created_desc",
    highlight: "title:30,name:30,user:30,text:124,comments.*:124",
    elasticsearch_dsl: {
      query: {
        filtered: {
          query: {
            query_string: {
              default_field: "_all",
              fields: [
                "_all",
                "title^4",
                "description^1.2",
                "job^1",
                "school^1",
                "all_jobs^0.125",
                "all_schools^0.125",
              ],
              query,
              analyze_wildcard: true,
              lenient: true,
            },
          },
        },
      },
      from: offset,
      size,
    },
  };

  const res = await fetch(apiUrl, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${accessToken}`,
    },
    body: JSON.stringify(params),
  });

  const data = await res.json();

  return NextResponse.json(data);
}

利用例

以下のURLからお試しいただけます。(利用にあたっては、GakuNin RDMへのログインが必要です。)

https://rdm-leaf-editor.vercel.app/search/?q=.xml

これにより、参画しているプロジェクトで連携した複数のストレージに含まれるXMLファイルを横断検索し、それをLEAF Writerのエディタで開く、といったことが可能になりました。

APIは以下です。

https://rdm-leaf-editor.vercel.app/api/search/?filter[fulltext]=.xml

以下のような結果が得られます。

{
  "results": [
    {
      "id": "67da847416000900109e0454",
      "date_created": "2025-03-19T08:46:44.636107+00:00",
      "date_modified": "2025-03-21T04:04:04.011551+00:00",
      "sort_file_name": "01.xml",
      "sort_node_name": "サブプロジェクト",
      "creator_id": "hj3a6",
      "creator_name": "Satoru Nakamura",
      "modifier_id": "jd8ar",
      "modifier_name": "Jun Ogawa",
      "deep_url": "/wzv9g/files/osfstorage/67da847416000900109e0454/",
      "guid_url": "/b45mp/",
      "tags": [],
      "normalized_tags": [],
      "name": "01.xml",
      "normalized_name": "01.xml",
      "category": "file",
      "node_url": "/wzv9g/",
      "node_title": "サブプロジェクト",
      "parent_id": "ys86g",
      "is_registration": false,
      "is_retracted": false,
      "extra_search_terms": "01 xml",
      "node_contributors": [
        {
          "id": "hj3a6"
        },
        {
          "id": "jd8ar"
        }
      ],
      "node_public": false,
      "comments": {},
      "highlight": {
        "name": [
          "01.<b>xml</b>"
        ]
      },
      "comment": null,
      "folder_name": "NII Storage",
      "parent_url": null,
      "parent_title": null
    }
  ],
  "counts": {
    "file": 1,
    "total": 1
  },
  "aggs": {
    "licenses": {},
    "total": 1
  },
  "tags": [],
  "typeAliases": {
    "project": "Projects",
    "component": "Components",
    "registration": "Registrations",
    "user": "Users",
    "total": "All Results",
    "file": "Files",
    "institution": "Institutions",
    "preprint": "Preprints",
    "group": "Groups",
    "wiki": "Wiki",
    "metadata": "Metadata"
  },
  "time": 1.32
}

まとめ

GakuNin RDMが提供するAPIを用いることで、いろいろな応用ができそうだなと感じました。

GakuNin RDMに関わる方々に感謝いたします。

Discussion

ログインするとコメントできます