タイトル : Next.js FastAPIと通信 その1
更新日 : 2024-02-03
カテゴリ : プログラミング
タグ :
frontend   
nextjs   
zustand   
python   
fastapi   

FastAPIとの通信を試してみます

まずはFastAPIの方

@dataclass
class ProjectInfo:
    id: int
    name: str
    description: str

class ProjectInfos(BaseModel):
    projects: List[ProjectInfo]


@app.get("/projects", response_model=ProjectInfos)
async def get_projects():
    projects = [
        ProjectInfo(
            id=1, name="next", description="reactを使った..."
        ),
        ProjectInfo(
            id=2, name="nuxt", description="vueを使った..."
        ),
        ProjectInfo(
            id=3, name="svelte-kit", description="svelteの..."
        )
    ]
    res_project = ProjectInfos(projects=projects)
    return res_project

192.168.11.6のマシン上で uvicorn main:app --reload --host=0.0.0.0 --port=8080で起動する。

Next.jsの方、Zustandのストアを書いて、その中でfetchする

import { create } from "zustand";


type Projects = {
    projectInfos: {id:number, name: string, description: string}[];
    fetchProjects: () => void;
};

const URL =  "http://192.168.11.6:8080";

export const useProjectInfoStore = create<Projects>((set) => ({
    projectInfos: [],
    fetchProjects: async () => {
        try {
            const response = await fetch(`${URL}/projects`);
            const res_json = await response.json();
            set({projectInfos: res_json["projects"]});
        } catch (error) {
            console.error("Error fetching projectInfo:", error);
        }
    },
}));

Next.jsの方、Zustandのストアを使う方

export default function Home() {

  const {project, setProject} = useProjectStore()

  const {projectInfos, fetchProjects} = useProjectInfoStore();

  useEffect(() => {
    fetchProjects();
  }, []);

  return (
    <Stack padding={3} spacing={3}>
      <Typography color={"secondary"}>メニュー1の画面</Typography>

      <Stack>
      <FormControl>
        <FormLabel id="demo-radio-buttons-group-label">Project</FormLabel>
        <RadioGroup
          aria-labelledby="demo-radio-buttons-group-label"
          name="radio-buttons-group"
          onChange={(event) => setProject(event.target.value)}
        >
          {
            projectInfos.map((pinfo) => {
              return (
                <FormControlLabel key={pinfo.id} 
                 value={pinfo.name} checked={project == pinfo.name} 
                 control={<Radio />} label={pinfo.name} />
              )
            })
          }
        </RadioGroup>
      </FormControl>
      </Stack>

      <Typography color={"secondary"}>project : {project} を選択中です</Typography>
    </Stack>
  );
}

画面 画像1