Created
November 28, 2017 12:16
-
-
Save kbrandwijk/627ceefab8ea61c0b457a64f68b2d251 to your computer and use it in GitHub Desktop.
Schema imports
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const finalSchema = ` | |
# import { topExperiences, topHomes, topReservations, featuredDestinations, experiencesByCity } from 'homepage' | |
# import { viewer } from 'viewer' | |
# import { signup, login } from 'auth' | |
# import { addPaymentMethod, book } from 'newmutations' | |
type Query { | |
topExperiences: [Experience!]! | |
topHomes: [Home!]! | |
topReservations: [Reservation!]! | |
featuredDestinations: [Neighbourhood!]! | |
experiencesByCity(cities: [String!]!): [ExperiencesByCity!]! | |
viewer: Viewer | |
} | |
type Viewer { | |
me: User! | |
bookings: [Booking!]! | |
} | |
type Mutation { | |
signup( | |
email: String! | |
password: String! | |
firstName: String! | |
lastName: String! | |
phone: String! | |
): User! | |
login(email: String! password: String!): User! | |
addPaymentMethod( | |
cardNumber: String! | |
expiresOnMonth: Int! | |
expiresOnYear: Int! | |
securityCode: String! | |
firstName: String! | |
lastName: String! | |
postalCode: String! | |
country: String! | |
): User! | |
book( | |
placeId: ID! | |
checkIn: String! | |
checkOut: String! | |
numGuests: Int! | |
): BookingResult! | |
} | |
type BookingResult { | |
success: Boolean! | |
} | |
type ExperiencesByCity { | |
experiences: [Experience!]! | |
city: City! | |
} | |
type Home { | |
id: ID! | |
name: String | |
description: String! | |
numRatings: Int! | |
avgRating: Float! | |
pictures(first: Int): [Picture!]! | |
} | |
type Reservation { | |
id: ID! | |
title: String! | |
avgPricePerPerson: Int! | |
pictures: [Picture!]! | |
location: Location! | |
isCurated: Boolean! | |
slug: String! | |
popularity: Int! | |
} | |
type Experience { | |
id: ID! | |
category: ExperienceCategory | |
title: String! | |
location: Location! | |
pricePerPerson: Int! | |
reviews: [Review!]! | |
preview: Picture! | |
popularity: Int! | |
} | |
type Review { | |
accuracy: Int! | |
checkIn: Int! | |
cleanliness: Int! | |
communication: Int! | |
createdAt: DateTime! | |
id: ID! | |
location: Int! | |
stars: Int! | |
text: String! | |
value: Int! | |
} | |
type Neighbourhood { | |
id: ID! | |
name: String! | |
slug: String! | |
homePreview: Picture | |
city: City! | |
featured: Boolean! | |
popularity: Int! | |
} | |
type Location { | |
id: ID! | |
lat: Float! | |
lng: Float! | |
address: String | |
directions: String | |
} | |
type Picture { | |
id: ID! | |
url: String! | |
} | |
type City { | |
id: ID! | |
name: String! | |
} | |
type ExperienceCategory { | |
id: ID! @isUnique | |
mainColor: String! | |
name: String! | |
experience: Experience | |
} | |
type User { | |
bookings: [Booking!] | |
createdAt: DateTime! | |
email: String! | |
firstName: String! | |
hostingExperiences: [Experience!] | |
id: ID! | |
isSuperHost: Boolean! | |
lastName: String! | |
location: Location! | |
notifications: [Notification!] | |
ownedPlaces: [Place!] | |
paymentAccount: [PaymentAccount!] | |
phone: String! | |
profilePicture: Picture | |
receivedMessages: [Message!] | |
responseRate: Float | |
responseTime: Int | |
sentMessages: [Message!] | |
updatedAt: DateTime! | |
token: String! | |
} | |
type PaymentAccount { | |
id: ID! | |
createdAt: DateTime! | |
type: PAYMENT_PROVIDER | |
user: User! | |
payments: [Payment!]! | |
paypal: PaypalInformation | |
creditcard: CreditCardInformation | |
} | |
type Place { | |
id: ID! @isUnique | |
name: String | |
size: PLACE_SIZES | |
shortDescription: String! | |
description: String! | |
slug: String! | |
maxGuests: Int! | |
numBedrooms: Int! | |
numBeds: Int! | |
numBaths: Int! | |
reviews: [Review!]! | |
amenities: Amenities! | |
host: User! | |
pricing: Pricing! | |
location: Location! | |
views: PlaceViews! | |
guestRequirements: GuestRequirements | |
policies: Policies | |
houseRules: HouseRules | |
bookings: [Booking!]! | |
pictures: [Picture!] | |
popularity: Int! | |
} | |
type Booking { | |
id: ID! @isUnique | |
createdAt: DateTime! | |
bookee: User! | |
place: Place! | |
startDate: DateTime! | |
endDate: DateTime! | |
payment: Payment! | |
} | |
type Notification { | |
createdAt: DateTime! | |
id: ID! | |
link: String! | |
readDate: DateTime! | |
type: NOTIFICATION_TYPE | |
user: User! | |
} | |
type Payment { | |
booking: Booking! | |
createdAt: DateTime! | |
id: ID! | |
paymentMethod: PaymentAccount! | |
serviceFee: Float! | |
} | |
type PaypalInformation { | |
createdAt: DateTime! | |
email: String! | |
id: ID! | |
paymentAccount: PaymentAccount! | |
} | |
type CreditCardInformation { | |
cardNumber: String! | |
country: String! | |
createdAt: DateTime! | |
expiresOnMonth: Int! | |
expiresOnYear: Int! | |
firstName: String! | |
id: ID! | |
lastName: String! | |
paymentAccount: PaymentAccount | |
postalCode: String! | |
securityCode: String! | |
} | |
type Message { | |
createdAt: DateTime! | |
deliveredAt: DateTime! | |
id: ID! | |
readAt: DateTime! | |
} | |
type Pricing { | |
averageMonthly: Int! | |
averageWeekly: Int! | |
basePrice: Int! | |
cleaningFee: Int | |
currency: CURRENCY | |
extraGuests: Int | |
id: ID! | |
monthlyDiscount: Int | |
perNight: Int! | |
securityDeposit: Int | |
smartPricing: Boolean! | |
weekendPricing: Int | |
weeklyDiscount: Int | |
} | |
type PlaceViews { | |
id: ID! | |
lastWeek: Int! | |
} | |
type GuestRequirements { | |
govIssuedId: Boolean! | |
guestTripInformation: Boolean! | |
id: ID! | |
recommendationsFromOtherHosts: Boolean! | |
} | |
type Policies { | |
checkInEndTime: Float! | |
checkInStartTime: Float! | |
checkoutTime: Float! | |
createdAt: DateTime! | |
id: ID! | |
updatedAt: DateTime! | |
} | |
type HouseRules { | |
additionalRules: String | |
createdAt: DateTime! | |
id: ID! | |
partiesAndEventsAllowed: Boolean | |
petsAllowed: Boolean | |
smokingAllowed: Boolean | |
suitableForChildren: Boolean | |
suitableForInfants: Boolean | |
updatedAt: DateTime! | |
} | |
type Amenities { | |
airConditioning: Boolean! | |
babyBath: Boolean! | |
babyMonitor: Boolean! | |
babysitterRecommendations: Boolean! | |
bathtub: Boolean! | |
breakfast: Boolean! | |
buzzerWirelessIntercom: Boolean! | |
cableTv: Boolean! | |
changingTable: Boolean! | |
childrensBooksAndToys: Boolean! | |
childrensDinnerware: Boolean! | |
crib: Boolean! | |
doorman: Boolean! | |
dryer: Boolean! | |
elevator: Boolean! | |
essentials: Boolean! | |
familyKidFriendly: Boolean! | |
freeParkingOnPremises: Boolean! | |
freeParkingOnStreet: Boolean! | |
gym: Boolean! | |
hairDryer: Boolean! | |
hangers: Boolean! | |
heating: Boolean! | |
hotTub: Boolean! | |
id: ID! | |
indoorFireplace: Boolean! | |
internet: Boolean! | |
iron: Boolean! | |
kitchen: Boolean! | |
laptopFriendlyWorkspace: Boolean! | |
paidParkingOffPremises: Boolean! | |
petsAllowed: Boolean! | |
pool: Boolean! | |
privateEntrance: Boolean! | |
shampoo: Boolean! | |
smokingAllowed: Boolean! | |
suitableForEvents: Boolean! | |
tv: Boolean! | |
washer: Boolean! | |
wheelchairAccessible: Boolean! | |
wirelessInternet: Boolean! | |
}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const linkingSchema = ` | |
# import { Booking, PaymentAccount } from 'booking' | |
# import { Place, User } from 'accomodation' | |
extend type User { | |
bookings: [Booking] | |
paymentAccounts: [PaymentAccount] | |
} | |
extend type Place { | |
bookings: [Booking] | |
} | |
extend type Booking { | |
bookee: User, | |
place: Place | |
} | |
extend type PaymentAccount { | |
user: User | |
}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require('dotenv').config() | |
import * as express from 'express' | |
import expressPlayground from 'graphql-playground-middleware-express' | |
import { remoteSchema, schema, resolver, resolvers, serve, use, transform } from 'qewl' | |
import * as jwt from 'express-jwt' | |
import { linkingSchema } from './schemas/linkingSchema' | |
import { linkingResolvers } from './resolvers/linkingResolvers' | |
import { homepage } from './resolvers/Query/homepage' | |
import { Viewer } from './resolvers/Viewer' | |
import { account } from './resolvers/Mutation/account' | |
import { User } from './resolvers/User' | |
import { ExperiencesByCity } from './resolvers/ExperiencesByCity' | |
import { addPaymentMethod } from './resolvers/Mutation/addPaymentMethod' | |
import { book } from './resolvers/Mutation/book' | |
import { checkAuthentication } from './utils' | |
import { Home } from './resolvers/Home' | |
import { finalSchema } from './schemas/finalSchema' | |
async function run() { | |
const app = express() | |
const graphql = express.Router() | |
// Add user from Authorization token to context | |
graphql.use(jwt({ secret: process.env.JWT_SECRET, credentialsRequired: false })) | |
// Add and link schemas | |
graphql.use( | |
// Add accomodation and booking endpoint | |
remoteSchema({ | |
name: 'accomodation' | |
uri: process.env.GRAPHCOOL_ACCOMODATION_ENDPOINT, | |
authenticationToken: () => process.env.GRAPHCOOL_ACCOMODATION_TOKEN | |
}), | |
remoteSchema({ | |
name: 'booking' | |
uri: process.env.GRAPHCOOL_BOOKING_ENDPOINT, | |
authenticationToken: () => process.env.GRAPHCOOL_BOOKING_TOKEN | |
}), | |
// Add linking schema between endpoints | |
schema({name: 'linking', schema: linkingSchema}), | |
// Add linking resolvers | |
resolvers(linkingResolvers) | |
) | |
// Add top level fields | |
graphql.use( | |
schema({name: 'homepage', schema: ` | |
# import { Experience, Restaurant, Neighbourhood } from 'accomodation' | |
extend type Query { | |
topExperiences: [Experience!]! | |
topHomes: [Home!]! | |
topReservations: [Restaurant!]! | |
featuredDestinations: [Neighbourhood!]! | |
experiencesByCity(cities: [String!]!): [ExperiencesByCity!]! | |
} | |
type Home { | |
id: ID! | |
name: String | |
description: String! | |
numRatings: Int! | |
avgRating: Float! | |
pictures(first: Int): [Picture!]! | |
} | |
type ExperiencesByCity { | |
experiences: [Experience!]! | |
city: City! | |
}`}), | |
resolvers(homepage), | |
resolvers(ExperiencesByCity), | |
resolvers(Home) | |
) | |
// Add Viewer | |
graphql.use( | |
schema({name: 'viewer', schema: ` | |
# import { User } from 'accomodation' | |
# import { Booking } from 'booking' | |
extend type Query { | |
viewer: Viewer | |
} | |
type Viewer { | |
me: User! | |
bookings: [Booking!]! | |
}`}), | |
resolvers(Viewer), | |
) | |
// Add authentication | |
graphql.use( | |
schema({name: 'auth', schema: ` | |
# import { User } from 'accomodation' | |
extend type Mutation { | |
signup(email: String!, password: String!, firstName: String!, lastName: String!, phone: String!): User! | |
login(email: String! password: String!): User! | |
} | |
extend type User { | |
token: String! | |
} | |
`}), | |
resolvers(account), | |
resolvers(User) | |
) | |
// Add custom mutations | |
graphql.use( | |
schema({name: 'newmutations', schema: ` | |
extend type Mutation { | |
addPaymentMethod( | |
cardNumber: String! | |
expiresOnMonth: Int! | |
expiresOnYear: Int! | |
securityCode: String! | |
firstName: String! | |
lastName: String! | |
postalCode: String! | |
country: String! | |
): User! | |
book( | |
placeId: ID! | |
checkIn: String! | |
checkOut: String! | |
numGuests: Int! | |
): BookingResult! | |
} | |
type BookingResult { | |
success: Boolean! | |
} | |
`}), | |
resolver('Mutation.addPaymentMethod', addPaymentMethod), | |
resolver('Mutation.book', book), | |
) | |
// Set up routes that require authentication (could also be done in the resolvers) | |
graphql.use( | |
use('Query.viewer', checkAuthentication), | |
use('Mutation.addPaymentMethod', checkAuthentication), | |
use('Mutation.book', checkAuthentication) | |
) | |
graphql.use(transform(finalSchema)) | |
app.use('/graphql', express.json(), graphql, await serve()) | |
app.use('/playground', expressPlayground({ endpoint: '/graphql' })) | |
app.listen(3000, () => | |
console.log('Server running. Open http://localhost:3000/playground to run queries.') | |
) | |
} | |
run().catch(console.error.bind(console)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment