This project can be used as a starter for spring cloud micro services development. It is the micro services version of Spring Boot in Practice. It use Spring Cloud Consul for service discovery, Spring Cloud Gateway to implement api gateway, and ORY/Hydra for running an optional OAuth2 server. The graphql api service exposed by gateway can be used as the backend api service for this flutter app Flutter in Practice. There is an article Spring Cloud 微服务开发指南 for learning this project.
- Spring Boot Web framework and server
- Spring Data JPA Access database
- Querydsl JPA Type safe dynamic sql builder
- Spring Security Authenticate and authrorize
- GraphQL Java Graphql for java
- Flyway Database migration
- Spring Cloud Gateway Api gateway
- Spring Cloud Consul Service discovery
- Spring Cloud Circuit Breaker Circuit breaker
- ORY/Hydra OAuth2 server
Path | Method | Description |
---|---|---|
/auth/login | POST | Login |
/auth/logout | GET | Logout |
/auth/logged | GET | Get logged user |
/user/register | POST | Register |
/user/modify | POST | Modify logged user |
/user/info | GET | Get user info |
/user/follow | POST | Follow user |
/user/unfollow | POST | Unfollow user |
/user/following | GET | Following users of someone |
/user/follower | GET | Fans of some user |
/user/sendMobileVerifyCode | POST | Send mobile verify code |
/post/publish | POST | Publish post |
/post/delete | POST | Delete post |
/post/info | GET | Get post info |
/post/published | GET | Get published posts of some user |
/post/like | POST | Like post |
/post/unlike | POST | Unlike post |
/post/liked | GET | Liked posts of some user |
/post/following | GET | Posts of following users of someone |
/file/upload | POST | Upload file |
/file/info | GET | Get file meta info |
The rest api service only return top objects, not return nested objects compared to the original monolith one.
type Query {
authLogout: User
authLogged: User
userInfo(id: Int!): User!
userFollowing(userId: Int, limit: Int, offset: Int): [User!]!
userFollowingCount(userId: Int): Int!
userFollower(userId: Int, limit: Int, offset: Int): [User!]!
userFollowerCount(userId: Int): Int!
postInfo(id: Int!): Post!
postPublished(userId: Int, limit: Int, offset: Int): [Post!]!
postPublishedCount(userId: Int): Int!
postLiked(userId: Int, limit: Int, offset: Int): [Post!]!
postLikedCount(userId: Int): Int!
postFollowing(limit: Int, beforeId: Int, afterId: Int): [Post!]!
postFollowingCount: Int!
fileInfo(id: Int!): File!
}
type Mutation {
authLogin(user: UserInput!): User!
userRegister(user: UserInput!): User!
userModify(user: UserInput!, code: String): User!
userSendMobileVerifyCode(type: String!, mobile: String!): String!
userFollow(userId: Int!): Boolean!
userUnfollow(userId: Int!): Boolean!
postPublish(post: PostInput!): Post!
postDelete(id: Int!): Boolean!
postLike(postId: Int!): Boolean!
postUnlike(postId: Int!): Boolean!
}
This project need java 11+.
If you use macOS, you can use brew install mysql
to install mysql, and use brew services start mysql
to start service at port 3306
. Then we need to create databases for each micro service.
CREATE DATABASE `scip_user`;
CREATE DATABASE `scip_post`;
CREATE DATABASE `scip_file`;
CREATE DATABASE `scip_stat`;
Suppose we can use root
user without password to access these databases, if not you should change each application's config.
If you use macOS, you can use brew install redis
to install redis, and use brew services start redis
to start service at port 6379
.
If you use macOS, you can use brew install consul
to install consul, and use brew services start consul
to start service at port 8500
.
./mvnw package
java -jar gateway/target/spring-cloud-in-practice-gateway-1.0.0-SNAPSHOT.jar
java -jar user/target/spring-cloud-in-practice-user-1.0.0-SNAPSHOT.jar
java -jar post/target/spring-cloud-in-practice-post-1.0.0-SNAPSHOT.jar
java -jar file/target/spring-cloud-in-practice-file-1.0.0-SNAPSHOT.jar
java -jar stat/target/spring-cloud-in-practice-stat-1.0.0-SNAPSHOT.jar
Then you can access all APIs at http://localhost:8080
. For example, you can register a new user using curl
in terminal as following:
curl --request POST 'http://localhost:8080/user/register' \
--header 'Content-Type: application/json' \
--data-raw '{
"username": "jaggerwang",
"password": "123456"
}'
./mvnw package
docker-compose up
If you repackaged any module, you should add --build
option to enable the new jar package.
Then you can access all APIs at http://localhost:8080
.
This application also support OAuth2 login, you need switch to oauth2
branch to enable this feature. We use ORY/Hydra to run an OAuth2 server, and any OAuth2 client can use this service to authenticate and authorize users.
You need install hydra
command first. You can use the following commands to install Hydra on macOS:
brew tap ory/hydra
brew install ory/hydra/hydra
Connect to your local mysql server and create a database for Hydra.
CREATE DATABASE `scip_auth`;
Then use the following commands to init database and run an OAuth2 server.
DSN=mysql://root:@tcp(localhost:3306)/scip_auth hydra migrate sql -e --yes
STRATEGIES_ACCESS_TOKEN=jwt LOG_LEVEL=info SECRETS_SYSTEM=a2N4m0XL659TIrB2V3fJBxUED5Zv5zUQ DSN=mysql://root:@tcp(localhost:3306)/scip_auth URLS_SELF_ISSUER=http://localhost:4444/ URLS_LOGIN=http://localhost:8080/hydra/login URLS_CONSENT=http://localhost:8080/hydra/consent URLS_LOGOUT=http://localhost:8080/hydra/logout TTL_ACCESS_TOKEN=12h TTL_REFRESH_TOKEN=720h hydra serve all --dangerous-force-http --dangerous-allow-insecure-redirect-urls 'http://localhost:8080/hydra/login,http://localhost:8080/hydra/consent,http://localhost:8080/hydra/logout'
This step is not needed when run by docker compose.
We will create two clients, one is for Hydra's builtin client, and the other is for the gateway service which can be used as an OAuth2 client.
hydra --endpoint 'http://localhost:4445/' clients create --id test --name 'Test' --secret E0g8oR7m711bGcvy --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope openid,offline,profile --callbacks 'http://localhost:4446/callback'
hydra --endpoint 'http://localhost:4445/' clients create --id scip --name 'Spring Cloud in Practice' --secret ilxzM0AdA7BVaL7c --grant-types authorization_code,refresh_token,client_credentials,implicit --response-types token,code,id_token --scope offline,user,post,file,stat --callbacks 'http://localhost:8080/login/oauth2/code/hydra'
hydra token user --auth-url 'http://localhost:4444/oauth2/auth' --token-url 'http://localhost:4444/oauth2/token' --client-id test --client-secret E0g8oR7m711bGcvy --scope openid,offline,profile --redirect 'http://localhost:4446/callback'
It will auto open http://localhost:4446
to commence OAuth2 authorize flow.
The gateway can also be used as an OAuth2 client, open login page at http://localhost:8080/login
to commence an OAuth2 authorization flow.
Right now there is a bug which make OAuth2 login not working, you need remove config
exceptionHandling
innet.jaggerwang.scip.gateway.api.config.SecurityConfig
.