Java+Spring Boot+PostgreSQL+Spring Data REST에서 REST API

드디어 제목에 docker-compose를 넣지 못했네요.

TL;DR

  • 이전 기사의 후속 +α하고 있다
  • docker-compose 아래의 자바+Spring Boot+PostgreSQL(JPA 편) | 북산순도|zen
  • https://zenn.dev/junki555/articles/de2c9844a1d101
  • 이 문장과 대체로 같다
  • Spring JPA Data with REST와 Lombok을 이용하여 REST API를 무섭게 간단하게 제작합니다.|Qiita
  • https://qiita.com/ukiuni@github/items/fb46680146c4cc8b5187
  • Spring Bootwith Docker의 개발 환경 고려
  • https://blog.tiqwab.com/2017/03/21/docker-java.html
  • Spring Data REST 사용 준비


    Spring Data REST는 다음 기사에서도 살짝 언급을 했습니다.
    Enity 및 Repository 만 준비할 뿐
    RESTful을 모두 낳는 Endpoint의 편리한 포장입니다.
  • docker-compose에서 Java+Spring Boot+간단한 웹 API 만들기 | 북산순도|zen
  • https://zenn.dev/junki555/articles/a19f27d1045805
  • 준비라고는 하지만 지난번 보도된 상태로 보면 서버/build입니다.gradle에 도달implementation 'org.springframework.boot:spring-boot-starter-data-rest'그냥 보충기예요.
    server/build.gradle
    dependencies {
    	implementation 'org.springframework.boot:spring-boot-starter-data-rest'
    ...
    
    Spring Initializa는 바로 이런 느낌입니다.
  • Spring Initializr
  • https://start.spring.io/
  • 지난번 글의 상태에서 코드를 변경할 필요도 없다.대단합니다.

    Docker 용기를 시작하고Gradle 구축, 응용 시작, 요청


    docker-compose up -d
    # DB が立ち上がって初期化されるまでちょっとかかるのでちょっと待つ
    docker-compose exec app bash
    bash-4.4# sh gradlew build
    ...
    BUILD SUCCESSFUL in 8m 41s
    5 actionable tasks: 5 executed
    # できてるのを確認
    bash-4.4# ls build/libs/
    app-0.0.1-SNAPSHOT.jar
    bash-4.4# java -jar build/libs/app-0.0.1-SNAPSHOT.jar
    
    시동 후 던지기 요청을 시도한다.
    $ curl http://localhost:8080/users -X GET
    {
      "_embedded" : {
        "users" : [ {
          "name" : "test",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/users/1"
            },
            "user" : {
              "href" : "http://localhost:8080/users/1"
            }
          }
        } ]
      },
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users"
        },
        "profile" : {
          "href" : "http://localhost:8080/profile/users"
        }
      }
    }
    
    떨어졌어!대단해!
    POST 요청을 통해서도 데이터를 등록할 수 있습니다.
    $ curl http://localhost:8080/users -X POST -H "Content-Type:application/json" -d '{ "name":"foo" }'
    {
      "name" : "foo",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/2"
        },
        "user" : {
          "href" : "http://localhost:8080/users/2"
        }
      }
    }
    $ curl http://localhost:8080/users -X POST -H "Content-Type:application/json" -d '{ "name":"bar" }'
    {
      "name" : "bar",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/3"
        },
        "user" : {
          "href" : "http://localhost:8080/users/3"
        }
      }
    
    GET 더 시키세요.
    curl http://localhost:8080/users -X GET
    {
      "_embedded" : {
        "users" : [ {
          "name" : "test",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/users/1"
            },
            "user" : {
              "href" : "http://localhost:8080/users/1"
            }
          }
        }, {
          "name" : "foo",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/users/2"
            },
            "user" : {
              "href" : "http://localhost:8080/users/2"
            }
          }
        }, {
          "name" : "bar",
          "_links" : {
            "self" : {
              "href" : "http://localhost:8080/users/3"
            },
            "user" : {
              "href" : "http://localhost:8080/users/3"
            }
          }
        } ]
      },
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users"
        },
        "profile" : {
          "href" : "http://localhost:8080/profile/users"
        }
      }
    }
    
    URI를 통해 id를 지정하면 당연히 이 id의 데이터만 얻을 수 있다.
    $ curl http://localhost:8080/users/3 -X GET
    {
      "name" : "bar",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/3"
        },
        "user" : {
          "href" : "http://localhost:8080/users/3"
        }
      }
    }
    
    도 PUT 요청을 통해 업데이트할 수 있습니다.
    $ curl http://localhost:8080/users/3 -X PUT -H "Content-Type:application/json" -d '{ "name":"piyo" }'
    {
      "name" : "piyo",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/3"
        },
        "user" : {
          "href" : "http://localhost:8080/users/3"
        }
      }
    }
    $ curl http://localhost:8080/users/3 -X GET
    {
      "name" : "piyo",
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/users/3"
        },
        "user" : {
          "href" : "http://localhost:8080/users/3"
        }
      }
    }
    
    와트.와, 이거.http://localhost:9000 로그인 Adminer
    데이터베이스에도 등록이 있는지 확인해 보세요.

    등록했어요!OK!
    초간단 RESTfull API를 준비하려면 Rails보다 빠르지 않나...?웃다 웃다

    페일오버: POST 등록이 불가능한 경우


    POST 요청을 할 때 코드의 상태에 따라 500ERROR가 되는 경우가 있습니다.
    어떤 오류 실행java -jar build/libs/app-0.0.1-SNAPSHOT.jarSpring Boot 애플리케이션에서 일어나는 사람에게는 로그가 있어야 합니다.

    ERROR:relation "hibernate_sequence" does not exist


    PostgreSQL의 SERIAL 열에 대해 Enity 클래스@GeneratedValue의 대응에 오류가 있을 수 있습니다.
    이번 코드라면 다음 부분을 확인해 주세요.
    server/src/main/java/com/example/app/entity/User.java
    package com.example.app.entity;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "users")
    public class User {
    
      @Id
      // ここが @GeneratedValue(strategy = GenerationType.IDENTITY) かを確認
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
      private String name;
    
      protected User() {}
    
      public User(String name) {
        this.name = name;
      }
    
      public Long getId() {
        return id;
      }
    
      public String getName() {
        return name;
      }
    
      @Override
      public String toString() {
        return String.format("{id:%d,name:%s}", id, name);
      }
    }
    
  • PostgreSQL+JPA의 ID 열에서 "relation"hibernate sequence "does not exist"로 변경될 때의 처리|Qita
  • https://qiita.com/phonypianist/items/07ce9dad37785c7cb892
  • @Generated Value를 사용하여 키를 생성하는 방법|Qita
  • https://qiita.com/KevinFQ/items/a6d92ec7b32911e50ffe#generationtypeauto
  • ERROR:permission denied for sequence user_id_seq


    앱 서버에서 PostgreSQL로 연결하는 applus라는 사용자를 이번에 제작했습니다.
    프로그램이 SEQUEENCES에 SELECT 권한이 없으면, SERIAL 열에 id 증량을 발표하는 중 오류가 발생했습니다.
    이번 코드라면 다음 부분을 확인해 주세요.
    forDocker/db/initdb/3_create_role_appuser.sql
    CREATE ROLE appuser WITH LOGIN PASSWORD 'apppass';
    GRANT SELECT,UPDATE,INSERT,DELETE ON ALL TABLES IN SCHEMA public TO appuser;
    -- この下の行がちゃんとあるか確認
    GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO appuser;
    
  • sql - ERROR: permission denied for sequence cities_id_seq using Postgres | Stack Overflow
  • https://stackoverflow.com/questions/9325017/error-permission-denied-for-sequence-cities-id-seq-using-postgres
  • 다음 쿼리를 편집할 때 주의하십시오.
    이번 docker-compose.yml이면 docker volume를 할당했기 때문에forDocker/db/initdbdbvol을 삭제하면 다시 실행할 수 있습니다.
    이번 창고는 여기 있습니다.
    https://github.com/JUNKI555/java_spring_boot_practice02

    참고 자료

  • Spring JPA Data with REST와 Lombok을 이용하여 REST API를 무섭게 간단하게 제작합니다.|Qiita
  • https://qiita.com/ukiuni@github/items/fb46680146c4cc8b5187
  • Spring Data REST의 HTTP 끝점 사용자 정의
  • https://www.codeflow.site/ja/article/spring-data-rest-customize-http-endpoints
  • Spring Bootwith Docker의 개발 환경 고려
  • https://blog.tiqwab.com/2017/03/21/docker-java.html
  • Tutorial | React.js and Spring Data REST | Spring
  • https://spring.io/guides/tutorials/react-and-spring-data-rest/
  • Spring Boot으로 Spring Data REST | abcdefg 테스트...
  • http://pppurple.hatenablog.com/entry/2017/03/06/221334
  • 좋은 웹페이지 즐겨찾기