2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ToDoアプリの作成(Task編)

Posted at

はじめに

今回は,前回に続きタスクの取得、特定のIDのタスクを取得、タスクの新規作成、更新、削除機能を実装していきます。

※動作確認にpgAdminとPostmanを使います。

リポジトリの実装

このコードは、タスク情報を扱うためのリポジトリインターフェースと、そのインターフェースを実装する具体的なリポジトリ構造体を定義しています。
repository/task_repository.go
package repository

import (
	"fmt"
	"go-rest-api/model"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

type ITaskRepository interface {
    //ユーザーのすべてのタスクを取得するメソッドです。
	GetAllTasks(tasks *[]model.Task, userId uint) error
    // 特定のIDのタスクを取得するメソッドです。
	GetTaskById(task *model.Task, userId uint, taskId uint) error
    // 新しいタスクを作成するメソッドです。
	CreateTask(task *model.Task) error
    //タスクを更新するメソッドです。
	UpdateTask(task *model.Task, userId uint, taskId uint) error
    //タスクを削除するメソッドです。
	DeleteTask(userId uint, taskId uint) error
}

type taskRepository struct {
    //このフィールドは、データベース接続 (`gorm.DB` オブジェクト) を保持します。
	db *gorm.DB
}

func NewTaskRepository(db *gorm.DB) ITaskRepository {
    //`taskRepository` インスタンスを作成し、データベース接続を `db` フィールドに設定して返します。
	return &taskRepository{db}
}

func (tr *taskRepository) GetAllTasks(tasks *[]model.Task, userId uint) error {
    //gorm.DB の Joins、Where、Order、Find、Error メソッドを使って、指定されたユーザーIDのタスクをデータベースから取得します。
    //Joins("User"): ユーザーとタスクの関係を定義します。
    //Where("user_id=?", userId): ユーザーIDを指定してタスクを絞り込みます。
    //Order("created_at"): 作成日時順にソートします。
    //Find(tasks): 取得したタスクを tasks スライスに格納します。
	if err := tr.db.Joins("User").Where("user_id=?", userId).Order("created_at").Find(tasks).Error; err != nil {
		return err
	}
	return nil
}

func (tr *taskRepository) GetTaskById(task *model.Task, userId uint, taskId uint) error {
    //gorm.DB の Joins、Where、First、Errorメソッドを使って、指定されたユーザーIDとタスクIDのタスクをデータベースから取得します。
    //First(task, taskId): 取得したタスクをtask構造体に格納します。
	if err := tr.db.Joins("User").Where("user_id=?", userId).First(task, taskId).Error; err != nil {
		return err
	}
	return nil
}

func (tr *taskRepository) CreateTask(task *model.Task) error {
    //新しいタスクを作成するメソッドの実装です。
    //gorm.DBのCreate メソッドを使って、新しいタスクレコードを作成します。
	if err := tr.db.Create(task).Error; err != nil {
		return err
	}
	return nil
}

func (tr *taskRepository) UpdateTask(task *model.Task, userId uint, taskId uint) error {
    //gorm.DBのModel、Clauses、Where、Update、Error メソッドを使って、指定されたIDとユーザーIDのタスクを更新します
    //Model(task): 更新対象のタスクを指定します。
    //Clauses(clause.Returning{}): 更新されたレコードの情報を取得します。
    //Where("id=? AND user_id=?", taskId, userId): 更新対象のタスクレコードを、taskIdとuserIdで絞り込みます。
    //Update("title", task.Title): task 構造体のTitleフィールドの値を、データベースのタスクレコードのtitle列に更新します。
	result := tr.db.Model(task).Clauses(clause.Returning{}).Where("id=? AND user_id=?", taskId, userId).Update("title", task.Title)
    //if result.Error != nil { return result.Error }: データベース更新処理中にエラーが発生した場合、エラーオブジェクトresult.Errorを返します。
	if result.Error != nil {
		return result.Error
	}
    //更新されたレコードがなかった場合、更新対象のレコードが存在しないことを示すエラーオブジェクトを返します。
	if result.RowsAffected < 1 {
		return fmt.Errorf("object does not exist")
	}
	return nil
}

func (tr *taskRepository) DeleteTask(userId uint, taskId uint) error {
    //データベースからタスクレコードを削除する処理を実行します。
    //gorm.DB の Where、Delete、Error メソッドを使って、指定されたIDとユーザーIDのタスクを削除します。
    //Where("id=? AND user_id=?", taskId, userId): 削除対象のタスクレコードを、taskIdとuserIdで絞り込みます。
    //Delete(&model.Task{}): gorm.DBのDeleteメソッドを使って、指定された条件に合致するタスクレコードを削除します。
	result := tr.db.Where("id=? AND user_id=?", taskId, userId).Delete(&model.Task{})
    //if result.Error != nil { return result.Error }: データベース削除処理中にエラーが発生した場合、エラーオブジェクト result.Error を返します。
	if result.Error != nil {
		return result.Error
	}
    //更新されたレコードがなかった場合、更新対象のレコードが存在しないことを示すエラーオブジェクトを返します。
	if result.RowsAffected < 1 {
		return fmt.Errorf("object does not exist")
	}
	return nil
}

ユースケースの実装

次はユースケースを作成していきます。
タスクの取得、特定のIDのタスクを取得、タスクの新規作成、更新、削除を行うユースケースを実装したものです。
usecase/task_usecase.go
package usecase

import (
	"go-rest-api/model"
	"go-rest-api/repository"
)

//タスクユースケースが実装すべきメソッドを定義するインターフェースです。
type ITaskUsecase interface {
    //ユーザーのすべてのタスクを取得するメソッドです。
	GetAllTasks(userId uint) ([]model.TaskResponse, error)
    //特定のIDのタスクを取得するメソッドです。
	GetTaskById(userId uint, taskId uint) (model.TaskResponse, error)
    //新しいタスクを作成するメソッドです。
	CreateTask(task model.Task) (model.TaskResponse, error)
    //タスクを更新するメソッドです。
	UpdateTask(task model.Task, userId uint, taskId uint) (model.TaskResponse, error)
    //タスクを削除するメソッドです。
	DeleteTask(userId uint, taskId uint) error
}

//タスクリポジトリへの依存関係を保持するフィールドです。
type taskUsecase struct {
	tr repository.ITaskRepository
}

//taskUsecase構造体のインスタンスを生成する関数です。
func NewTaskUsecase(tr repository.ITaskRepository) ITaskUsecase {
	return &taskUsecase{tr}
}

func (tu *taskUsecase) GetAllTasks(userId uint) ([]model.TaskResponse, error) {
    //tasks := []model.Task{} は、データベースから取得したタスクのリストを格納する model.Task 型のスライスtasksを空で初期化します。
	tasks := []model.Task{}
    //タスクリポジトリのGetAllTasksメソッドを呼び出して、ユーザーのすべてのタスクを取得します。
    //GetAllTasks(&tasks, userId): タスクリポジトリのGetAllTasksメソッドは、データベースからユーザーのすべてのタスクを取得し、tasksスライスに格納します。
	if err := tu.tr.GetAllTasks(&tasks, userId); err != nil {
		return nil, err
	}
    //resTasks を空で初期化。
	resTasks := []model.TaskResponse{}
    //取得したタスクのリストtasksをループ処理し、model.TaskResponse型のオブジェクトに変換します。
	for _, v := range tasks {
        //model.TaskResponse 型の新しいオブジェクトを作成し、取得したタスクの情報 (v.ID, v.Title, v.CreatedAt, v.UpdatedAt) を設定します。
		t := model.TaskResponse{
			ID:        v.ID,
			Title:     v.Title,
			CreatedAt: v.CreatedAt,
			UpdatedAt: v.UpdatedAt,
		}
        //resTasks = append(resTasks, t) は、変換されたmodel.TaskResponseオブジェクトを resTasks スライスに追加します。
		resTasks = append(resTasks, t)
	}
    //取得したタスクのリストresTasksとエラーオブジェクトnilを返します。
	return resTasks, nil
}

func (tu *taskUsecase) GetTaskById(userId uint, taskId uint) (model.TaskResponse, error) {
    //データベースから取得したタスクの情報を格納するmodel.Task型の変数taskを空で初期化します。
	task := model.Task{}
    //タスクリポジトリのGetTaskByIdメソッドを呼び出して、特定のユーザーの特定のタスクを取得します。
    //タスクリポジトリのGetTaskByIdメソッドは、データベースから指定されたユーザーIDとタスクIDのタスクを取得し、task変数に格納します。
	if err := tu.tr.GetTaskById(&task, userId, taskId); err != nil {
		return model.TaskResponse{}, err
	}
    //model.TaskResponse型の新しいオブジェクトを作成し、取得したタスクの情報 (task.ID, task.Title, task.CreatedAt, task.UpdatedAt) を設定します。
	resTask := model.TaskResponse{
		ID:        task.ID,
		Title:     task.Title,
		CreatedAt: task.CreatedAt,
		UpdatedAt: task.UpdatedAt,
	}
    //取得したタスクの情報を含むmodel.TaskResponseオブジェクトとエラーオブジェクトnilを返します。
	return resTask, nil
}

func (tu *taskUsecase) CreateTask(task model.Task) (model.TaskResponse, error) {
    //タスクリポジトリのCreateTaskメソッドを呼び出して、新しいタスクを作成します。
    //タスクリポジトリのCreateTaskメソッドは、データベースに新しいタスクレコードを作成します。
    //タスク作成処理中にエラーが発生した場合、エラーを返します。
	if err := tu.tr.CreateTask(&task); err != nil {
		return model.TaskResponse{}, err
	}
    //作成されたタスクの情報を格納するmodel.TaskResponse型の新しいオブジェクトを作成し、作成されたタスクの情報 (task.ID, task.Title, task.CreatedAt, task.UpdatedAt) を設定します。
	resTask := model.TaskResponse{
		ID:        task.ID,
		Title:     task.Title,
		CreatedAt: task.CreatedAt,
		UpdatedAt: task.UpdatedAt,
	}
    /作成されたタスクの情報を含むmodel.TaskResponseオブジェクトとエラーオブジェクトnilを返します
	return resTask, nil
}

func (tu *taskUsecase) UpdateTask(task model.Task, userId uint, taskId uint) (model.TaskResponse, error) {
    //タスクリポジトリのUpdateTaskメソッドは、データベースのタスクレコードを更新します。
    //タスク更新処理中にエラーが発生した場合、エラーを返します。
	if err := tu.tr.UpdateTask(&task, userId, taskId); err != nil {
		return model.TaskResponse{}, err
	}
    //更新されたタスクの情報を格納するmodel.TaskResponse型の新しいオブジェクトを作成し、更新されたタスクの情報 (task.ID, task.Title, task.CreatedAt, task.UpdatedAt) を設定します。
	resTask := model.TaskResponse{
		ID:        task.ID,
		Title:     task.Title,
		CreatedAt: task.CreatedAt,
		UpdatedAt: task.UpdatedAt,
	}
    //更新されたタスクの情報を含むmodel.TaskResponseオブジェクトとエラーオブジェクト nil を返します。
	return resTask, nil
}

func (tu *taskUsecase) DeleteTask(userId uint, taskId uint) error {
    //eleteTask(userId, taskId): タスクリポジトリのDeleteTaskメソッドは、データベースのタスクレコードを削除します。
    //タスク削除処理中にエラーが発生した場合、エラーを返します。
	if err := tu.tr.DeleteTask(userId, taskId); err != nil {
		return err
	}
    //エラーが発生しなかった場合、return nilで、エラーオブジェクトnilを返します。これは、正常に処理が完了したことを示します。
	return nil
}

コントローラの実装

下記のコードは、タスクの取得、特定のIDのタスクを取得、タスクの新規作成、更新、削除を処理を行うためのコントローラを定義しています。
controller/task_controller.go
package controller

import (
	"go-rest-api/model"
	"go-rest-api/usecase"
	"net/http"
	"strconv"

	"github.com/golang-jwt/jwt/v4"
	"github.com/labstack/echo/v4"
)

type ITaskController interface {
    //ユーザーのすべてのタスクを取得するメソッドです。
	GetAllTasks(c echo.Context) error
    //特定のIDのタスクを取得するメソッドです。
	GetTaskById(c echo.Context) error
    //新しいタスクを作成するメソッドです。
	CreateTask(c echo.Context) error
    //タスクを更新するメソッドです。
	UpdateTask(c echo.Context) error
    //タスクを削除するメソッドです。
	DeleteTask(c echo.Context) error
}

type taskController struct {
    //タスクユースケースへの依存関係を保持するフィールドです。
	tu usecase.ITaskUsecase
}
    
    //タスクユースケースオブジェクトを受け取り、userController構造体のインスタンスを生成して返します。
func NewTaskController(tu usecase.ITaskUsecase) ITaskController {
	return &taskController{tu}
}

func (tc *taskController) GetAllTasks(c echo.Context) error {
    //echo.Contextオブジェクトcからuserキーで格納された認証情報を取得します。
	user := c.Get("user").(*jwt.Token)
    //取得した認証情報userから、jwt.MapClaims型のペイロードデータを取得します。
	claims := user.Claims.(jwt.MapClaims)
    //ペイロードデータから user_id の値を取得します。
	userId := claims["user_id"]
    //タスクユースケースの GetAllTasks メソッドは、ユーザーIDを受け取り、そのユーザーのすべてのタスクを[]model.TaskResponse型のリストとして返します。
	tasksRes, err := tc.tu.GetAllTasks(uint(userId.(float64)))
    //エラーが発生した場合、HTTP ステータスコード 500 (Internal Server Error)と、エラーメッセージをJSON形式で返します。
	if err != nil {
		return c.JSON(http.StatusInternalServerError, err.Error())
	}
    //タスクの取得が成功した場合、HTTP ステータスコード 200 (OK) と、取得したタスクのリスト (tasksRes) をJSON形式で返します。
	return c.JSON(http.StatusOK, tasksRes)
}

func (tc *taskController) GetTaskById(c echo.Context) error {
    //echo.Contextオブジェクトcからuserキーで格納された認証情報を取得します。
	user := c.Get("user").(*jwt.Token)
    //取得した認証情報userから、jwt.MapClaims型のペイロードデータを取得します。
	claims := user.Claims.(jwt.MapClaims)
    //ペイロードデータからuser_idの値を取得します。
	userId := claims["user_id"]
    //リクエストパスからtaskIdパラメータを取得します。これは、echo.ContextのParam メソッドを使って取得します。
	id := c.Param("taskId")
    //taskIdパラメータを整数型に変換します。
	taskId, _ := strconv.Atoi(id)
    //タスクユースケースの GetTaskByIdメソッドは、ユーザーIDとタスクIDを受け取り、そのタスクの情報をmodel.TaskResponse型のオブジェクトとして返します。
	taskRes, err := tc.tu.GetTaskById(uint(userId.(float64)), uint(taskId))
    //タスクの取得処理中にエラーが発生した場合、エラーを返します。
	if err != nil {
        //エラーが発生した場合、HTTP ステータスコード 500 (Internal Server Error) と、エラーメッセージをJSON形式で返します。
		return c.JSON(http.StatusInternalServerError, err.Error)
	}
    //タスクの取得が成功した場合、HTTP ステータスコード 200 (OK) と、取得したタスクの情報をJSON形式で返します。
	return c.JSON(http.StatusOK, taskRes)
}

func (tc *taskController) CreateTask(c echo.Context) error {
    //echo.Context オブジェクトcからuserキーで格納された認証情報を取得します。
	user := c.Get("user").(*jwt.Token)
    //取得した認証情報userから、jwt.MapClaims型のペイロードデータを取得します。
	claims := user.Claims.(jwt.MapClaims)
    //ペイロードデータからuser_idの値を取得します。
	userId := claims["user_id"]
    //新しいタスクの情報を格納するmodel.Task構造体を空で作成します。
	task := model.Task{}
    //c.Bind(&task) は、EchoフレームワークのコンテキストオブジェクトcのBindメソッドを呼び出し、リクエストボディからデータを取得して、task構造体にバインドします。
    //バインド処理中にエラーが発生した場合、エラーを返します。この場合、ステータスコード 400 Bad RequestとともにエラーメッセージをJSON形式で返します。
	if err := c.Bind(&task); err != nil {
		return c.JSON(http.StatusBadRequest, err.Error())
	}
    // 取得したユーザーIDを、task構造体のUserIdフィールドに設定します。
    //タスクユースケースのCreateTaskメソッドは、新しいタスクを作成します。
	task.UserId = uint(userId.(float64))
    //タスクの作成処理が成功した場合、taskRes変数には、作成されたタスクの情報を格納するmodel.TaskResponse構造体が格納されます。
    //タスクの作成処理中にエラーが発生した場合、err変数には、エラーオブジェクトが格納されます。
	taskRes, err := tc.tu.CreateTask(task)
    //タスクの作成処理中にエラーが発生した場合、HTTPステータスコード 500 (Internal Server Error) を返します。
	if err != nil {
		return c.JSON(http.StatusInternalServerError, err.Error())
	}
    //タスクの作成が成功した場合、HTTPステータスコード 201 (Created) と、作成されたタスクの情報をJSON形式で返します。
	return c.JSON(http.StatusCreated, taskRes)
}

func (tc *taskController) UpdateTask(c echo.Context) error {
    //c.Get("user").(*jwt.Token): echo.Contextオブジェクトcからuserキーで格納された認証情報を取得します。
	user := c.Get("user").(*jwt.Token)
    //取得した認証情報 user から、jwt.MapClaims型のペイロードデータを取得します。
	claims := user.Claims.(jwt.MapClaims)
    //ペイロードデータからuser_idの値を取得します。
	userId := claims["user_id"]
    //リクエストパスからtaskIdパラメータを取得します。これは、echo.ContextのParamメソッドを使って取得します。
	id := c.Param("taskId")
    //taskId パラメータを整数型に変換します。これは、strconv.Atoi 関数を使って行います。
	taskId, _ := strconv.Atoi(id)
    //更新するタスクの情報を格納するmodel.Task構造体を空で作成します。
	task := model.Task{}
    //c.Bind(&task) は、EchoフレームワークのコンテキストオブジェクトcのBindメソッドを呼び出し、リクエストボディからデータを取得して、task構造体にバインドします。
    //バインド処理中にエラーが発生した場合、エラーを返します。この場合、ステータスコード 400 Bad Request とともにエラーメッセージをJSON形式で返します。
	if err := c.Bind(&task); err != nil {
		return c.JSON(http.StatusBadRequest, err.Error())
	}
    //タスクユースケースの UpdateTask メソッドは、ユーザーID、タスクID、更新するタスク情報を渡して、タスクの更新処理を実行します。
    //更新処理が成功した場合、taskRes変数には、更新されたタスクの情報を格納する model.TaskResponse 構造体が格納されます。
    //更新処理中にエラーが発生した場合、err 変数には、エラーオブジェクトが格納されます。
	taskRes, err := tc.tu.UpdateTask(task, uint(userId.(float64)), uint(taskId))
    //更新処理中にエラーが発生した場合、HTTPステータスコード 500 (Internal Server Error) を返します。
	if err != nil {
		return c.JSON(http.StatusInternalServerError, err.Error())
	}
    //タスクの更新が成功した場合、HTTP ステータスコード 200 (OK) と、更新されたタスクの情報をJSON形式で返します。
	return c.JSON(http.StatusOK, taskRes)
}

func (tc *taskController) DeleteTask(c echo.Context) error {
    //echo.Context オブジェクトcからuserキーで格納された認証情報を取得します。
	user := c.Get("user").(*jwt.Token)
    //取得した認証情報userから、jwt.MapClaims型のペイロードデータを取得します。
	claims := user.Claims.(jwt.MapClaims)
    //ペイロードデータから user_idの値を取得します。
	userId := claims["user_id"]
    //リクエストパスからtaskIdパラメータを取得します。
	id := c.Param("taskId")
    //taskId パラメータを整数型に変換します。
	taskId, _ := strconv.Atoi(id)
    //タスクユースケースのDeleteTaskメソッドは、ユーザーIDとタスクIDを受け取り、タスクの削除処理を実行します。
    //削除処理中にエラーが発生した場合、err変数には、エラーオブジェクトが格納されます。
	err := tc.tu.DeleteTask(uint(userId.(float64)), uint(taskId))
    //削除処理中にエラーが発生した場合、HTTPステータスコード 500 (Internal Server Error) を返します。
	if err != nil {
		return c.JSON(http.StatusInternalServerError, err.Error())
	}
    //タスクの削除が成功した場合、HTTP ステータスコード 204 (No Content) を返します。これは、削除が成功したことを示しますが、レスポンスボディに何も含めないことを意味します。
	return c.NoContent(http.StatusNoContent)
}

routerの実装

以前作成したrouterにタスク関連のエンドポイントを追加していきます。

router/router.go
package router

import (
	"go-rest-api/controller"
	"os"

	echojwt "github.com/labstack/echo-jwt/v4"
	"github.com/labstack/echo/v4"
)

func NewRouter(uc controller.IUserController, tc controller.ITaskController) *echo.Echo {
	e := echo.New()
	e.POST("/signup", uc.SignUp)
	e.POST("/login", uc.Login)
	e.POST("/logout", uc.LogOut)
    //echo.Echo オブジェクトeに対して、/tasksというプレフィックスを持つグループを作成します。これにより、/tasksの下に複数のエンドポイントを定義することができます。
	t := e.Group("/tasks")
    //echo-jwtミドルウェアを使って、tasksグループのすべてのエンドポイントに対して、JWTトークンによる認証を適用します。
    //echojwt.Config: echo-jwtミドルウェアの設定オプションを定義します。
	t.Use(echojwt.WithConfig(echojwt.Config{
        ////JWTトークンを署名するために使用される秘密鍵です。環境変数 SECRET から取得されます。
		SigningKey:  []byte(os.Getenv("SECRET")),
        //JWTトークンを取得する場所を指定します。この場合、クッキーのtokenという名前で取得します。
		TokenLookup: "cookie:token",
	}))
    //GETメソッドで/tasksエンドポイントにアクセスしたときに、tc.GetAllTasks関数を呼び出すように設定します。
	t.GET("", tc.GetAllTasks)
    //GET メソッドで/tasks/:taskId エンドポイントにアクセスしたときに、tc.GetTaskById 関数を呼び出すように設定します。
	t.GET("/:taskId", tc.GetTaskById)
    ///tasksエンドポイントにアクセスしたときに、tc.CreateTask関数を呼び出すように設定します。
	t.POST("", tc.CreateTask)
    //PUTメソッドで/tasks/:taskIdエンドポイントにアクセスしたときに、tc.UpdateTask 関数を呼び出すように設定します。
	t.PUT("/:taskId", tc.UpdateTask)
    //DELETEメソッドで/tasks/:taskIdエンドポイントにアクセスしたときに、tc.DeleteTask関数を呼び出すように設定します。
	t.DELETE("/:taskId", tc.DeleteTask)
	return e
}

mainの実装

以前作成したmain.goにタスクリポジトリ、タスクユースケース、タスクコントローラーを追加していきます。
main.go
package main

import (
	"go-rest-api/controller"
	"go-rest-api/db"
	"go-rest-api/repository"
	"go-rest-api/router"
	"go-rest-api/usecase"
)

func main() {
	db := db.NewDB()
	userRepository := repository.NewUserRepository(db)
    //dbを使って、タスクリポジトリの新しいインスタンスを作成します。
	taskRepository := repository.NewTaskRepository(db)
	userUsecase := usecase.NewUserUsecase(userRepository)
    //taskRepositoryを使って、タスクユースケースの新しいインスタンスを作成します。
	taskUsecase := usecase.NewTaskUsecase(taskRepository)
	userController := controller.NewUserController(userUsecase)
    //taskUsecaseを使って、タスクコントローラーの新しいインスタンスを作成します。
	taskController := controller.NewTaskController(taskUsecase)
	e := router.NewRouter(userController, taskController)
	e.Logger.Fatal(e.Start(":8080"))
}

プログラムを起動

下記のコマンドでプログラムを起動していきます。 `GO_ENV=dev go run main.go`

起動できました!
スクリーンショット 2024-11-04 14.01.30.png

次はPostmanを使って動作確認します。
http://localhost:8080/tasksのエンドポイントにGETメソッドでアクセスします。
タスクのエンドポイントはJWTでプロテクションされているので、JWTトークンがない場合は401 Unauthorizedのエラーが発生します。

スクリーンショット 2024-11-04 14.16.14.png

JWTトークンを付与するためにログインを行います。
エンドポイントをhttp://localhost:8080/loginに変更してPOSTメソッドでアクセスしていきます。
Bodyのrawを選択し、前回作成したユーザーでログインしていきます。
Cookiesタブを確認するとJWTトークンが出来ます。
スクリーンショット 2024-11-04 14.23.34.png

JWTトークンが出来たので、再度http://localhost:8080/tasksのエンドポイントにGETメソッドでアクセスします。
スクリーンショット 2024-11-04 14.37.11.png
今度はJWTの認証が通って、ステータスがOKで空の配列が返ってきます。

それでは、タスクの新規作成を行ってみたいと思います。
titleがhelloというタスクを作ります。
http://localhost:8080/tasksに変更してPOSTメソッドでアクセスしていきます。
スクリーンショット 2024-11-04 14.41.23.png

ステータス201 Createdが返ってきて新しく作成されたタスクのオブジェクトがJSONで返ってきます。
pdAdminでも確認していきます。
スクリーンショット 2024-11-04 14.46.36.png
DBにも新規作成したタスクが追加されたのを確認できました。

GetTaskByIdでID12のタスクを1つだけ取得していきたいと思います。
まずは、http://localhost:8080/tasksに変更してPOSTメソッドでアクセスしてもう一つタスクを作成しておきます。
スクリーンショット 2024-11-04 14.50.30.png

http://localhost:8080/tasks/12のエンドポイントにGETメソッドでアクセスします。
スクリーンショット 2024-11-04 14.55.20.png
そうするとIDが12のタスクを1つ取得できました。

それでは、次は更新を試していきたいと思います。
PUTメソッドに変更して、そしてエンドポイントhttp://localhost:8080/tasks/の末尾に変更したいタスクのIDを追加します。
ここではID12のtitleをupdateに更新していこうと思います。

スクリーンショット 2024-11-04 15.01.20.png

titleが更新されて、更新した日時も変更されました。
pgAdminを確認するとデータベースの方にも更新内容が反映されました。
スクリーンショット 2024-11-04 15.03.51.png

次はID12のタスクを削除していきたいと思います。
DELETEメソッドに変更してhttp://localhost:8080/tasks/12のエンドポイントにアクセスします。

スクリーンショット 2024-11-04 15.07.36.png

そうすると204 No Contentが返ってきました。
pgAdminを確認するとデータベースの方もIDが12のタスクが削除されているのを確認できました。
(Executeボタンを押下)

スクリーンショット 2024-11-04 15.11.26.png

そして、POSTメソッドでログアウトのエンドポイントにアクセスすると、Cookieが削除されますので、この状態で、DELETEメソッドhttp://localhost:8080/tasks/11のエンドポイントにアクセスしても,JWTトークンがありませんということで、401 Unauthorizedが返ってきます。
スクリーンショット 2024-11-04 15.25.02.png

スクリーンショット 2024-11-04 15.26.33.png

まとめ

今回はタスクの新規作成、更新、削除機能を実装しました。
次回は、バリデーションの機能を実装していきます。
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?