Rename graphql-sample to webmvc-http-endpoint

This commit is contained in:
Rossen Stoyanchev
2021-01-03 21:18:10 +00:00
parent 099733c1f0
commit eda2bd3f33
15 changed files with 3 additions and 3 deletions

View File

@@ -0,0 +1,23 @@
plugins {
id 'org.springframework.boot' version '2.4.0-SNAPSHOT'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
description = "GraphQL sample application"
sourceCompatibility = '1.8'
dependencies {
implementation project(':spring-graphql-web')
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
runtimeOnly 'com.h2database:h2'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.spring.sample.graphql;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}

View File

@@ -0,0 +1,56 @@
package io.spring.sample.graphql.project;
import java.util.List;
public class Project {
private String slug;
private String name;
private String repositoryUrl;
private ProjectStatus status;
private List<Release> releases;
public String getSlug() {
return this.slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getRepositoryUrl() {
return this.repositoryUrl;
}
public void setRepositoryUrl(String repositoryUrl) {
this.repositoryUrl = repositoryUrl;
}
public ProjectStatus getStatus() {
return this.status;
}
public void setStatus(ProjectStatus status) {
this.status = status;
}
public List<Release> getReleases() {
return this.releases;
}
public void setReleases(List<Release> releases) {
this.releases = releases;
}
}

View File

@@ -0,0 +1,32 @@
package io.spring.sample.graphql.project;
import graphql.schema.idl.RuntimeWiring;
import org.springframework.boot.graphql.RuntimeWiringCustomizer;
import org.springframework.stereotype.Component;
@Component
public class ProjectDataWiring implements RuntimeWiringCustomizer {
private final SpringProjectsClient client;
public ProjectDataWiring(SpringProjectsClient client) {
this.client = client;
}
@Override
public void customize(RuntimeWiring.Builder builder) {
builder
.type("QueryType", typeWiring ->
typeWiring.dataFetcher("project", env -> {
String slug = env.getArgument("slug");
return client.fetchProject(slug);
}))
.type("Project", typeWiring ->
typeWiring.dataFetcher("releases", env -> {
Project project = env.getSource();
return client.fetchProjectReleases(project.getSlug());
})
);
}
}

View File

@@ -0,0 +1,16 @@
package io.spring.sample.graphql.project;
import java.util.Arrays;
import com.fasterxml.jackson.annotation.JsonCreator;
public enum ProjectStatus {
ACTIVE, COMMUNITY, INCUBATING, ATTIC;
@JsonCreator
public static ProjectStatus fromName(String name) {
return Arrays.stream(ProjectStatus.values())
.filter(type -> type.name().equals(name))
.findFirst().orElse(ProjectStatus.ACTIVE);
}
}

View File

@@ -0,0 +1,54 @@
package io.spring.sample.graphql.project;
public class Release {
private String version;
private ReleaseStatus status;
private String referenceDocUrl;
private String apiDocUrl;
private boolean current;
public String getVersion() {
return this.version;
}
public void setVersion(String version) {
this.version = version;
}
public ReleaseStatus getStatus() {
return this.status;
}
public void setStatus(ReleaseStatus status) {
this.status = status;
}
public String getReferenceDocUrl() {
return this.referenceDocUrl;
}
public void setReferenceDocUrl(String referenceDocUrl) {
this.referenceDocUrl = referenceDocUrl;
}
public String getApiDocUrl() {
return this.apiDocUrl;
}
public void setApiDocUrl(String apiDocUrl) {
this.apiDocUrl = apiDocUrl;
}
public boolean isCurrent() {
return this.current;
}
public void setCurrent(boolean current) {
this.current = current;
}
}

View File

@@ -0,0 +1,16 @@
package io.spring.sample.graphql.project;
import java.util.Arrays;
import com.fasterxml.jackson.annotation.JsonCreator;
public enum ReleaseStatus {
GENERAL_AVAILABILITY, MILESTONE, SNAPSHOT;
@JsonCreator
public static ReleaseStatus fromName(String name) {
return Arrays.stream(ReleaseStatus.values())
.filter(type -> type.name().equals(name))
.findFirst().orElse(ReleaseStatus.GENERAL_AVAILABILITY);
}
}

View File

@@ -0,0 +1,47 @@
package io.spring.sample.graphql.project;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.MediaTypes;
import org.springframework.hateoas.client.Hop;
import org.springframework.hateoas.client.Traverson;
import org.springframework.hateoas.server.core.TypeReferences;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class SpringProjectsClient {
private static final TypeReferences.CollectionModelType<Release> releaseCollection =
new TypeReferences.CollectionModelType<Release>() { };
private final Traverson traverson;
public SpringProjectsClient(RestTemplateBuilder builder) {
RestTemplate restTemplate = builder.messageConverters(Traverson.getDefaultMessageConverters(MediaTypes.HAL_JSON)).build();
this.traverson = new Traverson(URI.create("https://spring.io/api/"), MediaTypes.HAL_JSON);
this.traverson.setRestOperations(restTemplate);
}
public Project fetchProject(String projectSlug) {
return this.traverson.follow("projects")
.follow(Hop.rel("project").withParameter("id", projectSlug))
.toObject(Project.class);
}
public List<Release> fetchProjectReleases(String projectSlug) {
CollectionModel<Release> releases = this.traverson.follow("projects")
.follow(Hop.rel("project").withParameter("id", projectSlug))
.follow(Hop.rel("releases"))
.toObject(releaseCollection);
return new ArrayList(releases.getContent());
}
}

View File

@@ -0,0 +1,7 @@
package io.spring.sample.graphql.repository;
import org.springframework.data.repository.CrudRepository;
public interface ArtifactRepositories extends CrudRepository<ArtifactRepository, String> {
}

View File

@@ -0,0 +1,28 @@
package io.spring.sample.graphql.repository;
import java.util.Arrays;
import java.util.List;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class ArtifactRepositoriesInitializer implements ApplicationRunner {
private final ArtifactRepositories repositories;
public ArtifactRepositoriesInitializer(ArtifactRepositories repositories) {
this.repositories = repositories;
}
@Override
public void run(ApplicationArguments args) throws Exception {
List<ArtifactRepository> repositoryList = Arrays.asList(
new ArtifactRepository("spring-releases", "Spring Releases", "https://repo.spring.io/libs-releases"),
new ArtifactRepository("spring-milestones", "Spring Milestones", "https://repo.spring.io/libs-milestones"),
new ArtifactRepository("spring-snapshots", "Spring Snapshots", "https://repo.spring.io/libs-snapshots")
);
repositories.saveAll(repositoryList);
}
}

View File

@@ -0,0 +1,58 @@
package io.spring.sample.graphql.repository;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class ArtifactRepository {
@Id
private String id;
private String name;
private String url;
private boolean snapshotsEnabled;
public ArtifactRepository(String id, String name, String url) {
this.id = id;
this.name = name;
this.url = url;
}
public ArtifactRepository() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public boolean isSnapshotsEnabled() {
return snapshotsEnabled;
}
public void setSnapshotsEnabled(boolean snapshotsEnabled) {
this.snapshotsEnabled = snapshotsEnabled;
}
}

View File

@@ -0,0 +1,23 @@
package io.spring.sample.graphql.repository;
import graphql.schema.idl.RuntimeWiring;
import org.springframework.boot.graphql.RuntimeWiringCustomizer;
import org.springframework.stereotype.Component;
@Component
public class ArtifactRepositoryDataWiring implements RuntimeWiringCustomizer {
private final ArtifactRepositories repositories;
public ArtifactRepositoryDataWiring(ArtifactRepositories repositories) {
this.repositories = repositories;
}
@Override
public void customize(RuntimeWiring.Builder builder) {
builder.type("QueryType", typeWiring -> typeWiring
.dataFetcher("artifactRepositories", env -> this.repositories.findAll())
.dataFetcher("artifactRepository", env -> this.repositories.findById(env.getArgument("id"))));
}
}

View File

@@ -0,0 +1 @@
management.endpoints.web.exposure.include=health,metrics,info

View File

@@ -0,0 +1,43 @@
schema {
query: QueryType
}
type QueryType {
artifactRepositories : [ArtifactRepository]
artifactRepository(id : ID!) : ArtifactRepository
project(slug: ID!): Project
}
type ArtifactRepository {
id: ID!
name: String!
url: String!
snapshotsEnabled: Boolean
}
type Project {
slug: ID!
name: String!
repositoryUrl: String!
status: ProjectStatus!
releases: [Release]
}
type Release {
version: String!
status: ReleaseStatus!
current: Boolean
}
enum ProjectStatus {
ACTIVE
COMMUNITY
INCUBATING
ATTIC
}
enum ReleaseStatus {
GENERAL_AVAILABILITY
MILESTONE
SNAPSHOT
}