create-graphql-server Generate your GraphQL server开源项目

我要开发同款
匿名用户2021年11月23日
24阅读
开发技术Java
所属分类大数据、数据查询
授权协议MIT License

作品详情

CreateGraphQLServer

Create-graphql-serverisascaffoldingtoolthatletsyougenerateanewMongo/Express/Node.jsGraphQLserverprojectfromthecommandline.AftergeneratingtheprojectyoucanalsogeneratecodetosupportyourGraphQLschemadirectlyfromtheschemafiles.BasicauthenticationsupportisincludedviaPassportLocalwithJWTs.

NOTE:thisprojectisnotactivelymaintained.Asascaffoldingtool,thisisnotnecessarilyanissue(youcangenerateaprojectwithitandthenforgetaboutthetool),butitisincreasinglyfallingoutofdate.Aspritiualsuccessoristhegraphql-cliproject.Pleasetakealook!

GettingStartedInstallation

Installitonceglobally:

npminstall-gcreate-graphql-serverCreatingaServer

Tocreateanewserverinthemy-new-server-dirfolderusetheinitcommand:

create-graphql-serverinitmy-new-server-dircdmy-new-server-diryarninstallStartingtheServer

InmostdevelopmentenvironmentsyoucannowfireupyournewserverusingthepackagedprebuiltMongoserver:

yarnstart

Ifmongo-prebuiltfailstostart,oryou'dratheruseanotherMongoDBinstallationfordevelopment,simplysettheMONGO_URLenvironmentvariablewhenyoustarttheserver,asfollows:

#OnWindows:SETMONGO_URL=mongodb://localhost:27017&&yarnstart#OnUnix/OSX:MONGO_URL=mongodb://localhost:27017yarnstart

Ifyousetupausername,passwordoradifferentportforMongo,orareaccessingMongothroughaservicesuchasmLab,correcttheMONGO_URLabovetoreflectthat.

RunningQueries

Yourserverisnowupandrunning.Toqueryit,pointyourbrowserathttps://localhost:3010/graphiql.Thereisn'tanythingtoqueryyethowever.

AddingTypes:Overview

Toaddtypes,youcandefinetheminGraphQLschemafiles,thengeneratecodeforthemusingtheadd-typecommand,asfollows:

create-graphql-serveradd-typepath/to/my-new-type.graphql

Ifyouhaveafolderfullofschemafiles,youcanaddthemallatoncebypointingadd-typetoafolderinsteadofanindividualschemafile:

create-graphql-serveradd-typepath

Sampleschemafilesareincludedintest/input.Toseewhatacompletegeneratedserverlookslikeusingthem,checkouttest/output-app.

Schemas

YoucreateaGraphQLtypeforyourschemabyspecifyingthetypeasinput,withsomespecialcode-generationcontrollingdirectives.

Forexample,inUser.graphql:

typeUser{email:String!bio:Stringtweets:[Tweet!]@hasMany(as:"author")liked:[Tweet!]@belongsToManyfollowing:[User!]@belongsToManyfollowers:[User!]@hasAndBelongsToMany(as:"following")}

TheabovewillgenerateaUsertypewhichislinkedtootherusersandatweettypeviaforiegnkeysandwhichwillhavemutationstoadd,updateandremoveusers,aswellassomerootqueriestofindasingleuserorallusers.

Thedirectivesusedcontrolthecodegeneration(seebelow).

Directives@unmodifiable-thefieldwillnotappearintheupdatemutation@enum-thefield'stypeisanenum,andcanbesetdirectly(notjustbyId).Relations

Iftypesreferenceeachother,youshoulduseanassociationdirectivetoexplaintothegeneratorhowthereferenceshouldbestoredinmongo:

Singletonfields

Ifthefieldreferencesasingle(nullableorotherwise)instanceofanothertype,itwillbeeither:

@belongsTo-theforeignkeyisstoredonthistypeas${fieldName}Id[thisisthedefault]@hasOne-theforeignkeyisstoredonthereferencedtypeas${typeName}Id.Providethe"as":Xargumentifthenameisdifferent.[NOTE:thisisnotyetfullyimplemented].Paginatedfields

Ifthefieldreferencesanarray(againw/orw/onullability)ofanothertype,itwillbeeither:

@belongsToMany-thereisalistofforeignkeysstoredonthistypeas${fieldName}Ids[thisisthedefault]@hasMany-theforeignkeyisonthereferencedtypeas${typeName}Id.Providethe"as":Xargumentifthenameisdifferent.(thisisthereverseof@belongsToina1-manysituation).@hasAndBelongsToMany-theforeignkeyonthereferencedtypeas${typeName}Ids.Providethe"as":Xargumentifthenameisdifferent.(thisisthereverseof@belongsToManyinamany-manysituation).Updatingtypes

Toupdatetypes,justre-runadd-typeagain:

create-graphql-serveradd-typepath/to/input.graphql[--force-update]

Thisoverwritesyouroldtypespecificfilesfromthedirectories:schema,model,resolvers.

Itrecognizes,ifyou'vechangedanycodefile,whichwillbeoverwrittenbythegeneratorandstopsandwarns.Ifyouaresure,youwanttooverwriteyourchanges,thenjustusethe--force-updateoption.

Removingtypes

Toremovetypes,usethefollowingcommandwiththepathtotheGraphQLfile,orasalternative,justenterthetypenamewithoutpath.

create-graphql-serverremove-typepath/to/input.graphqlcreate-graphql-serverremove-typetypenamecreate-graphql-serverremove-typepath

Thiscommanddeletesyouroldtypespecificfilesfromthedirectories:schema,model,resolvers.Italsoremovesthecodereferencesoutofthecorrespondingindexfiles.

Itrecognizes,ifyou'vechangedanycodefile,whichwillbeoverwrittenbythegeneratorandstopsandwarns.Ifyouaresure,youwanttooverwriteyourchanges,thenjustusetheforce-updateoption.

Authentication

CGSsetsupabasicpassport-basedJWTauthenticationsystemforyourapp.

NOTE:youshouldensureusersconnecttoyourserverthroughSSL.

Touseit,ensureyouhaveaGraphQLtypecalledUserinyourschema,withafieldemail,bywhichuserswillbelookedup.Whencreatingusers,ensurethatabcryptedhashdatabasefieldisset.Forinstance,ifyoucreatedyourusersinthisway:

typeUser{email:String!bio:String}

YoucouldupdatethegeneratedCreateUserInputinputobjecttotakeapasswordfield:

inputCreateUserInput{email:String!password:String!#<-youneedtoaddthislinetothegeneratedoutputbio:String}

AndthenupdatethegeneratedUsermodeltohashthatpasswordandstoreit:

importbcryptfrom'bcrypt';//SetthisasappropriateconstSALT_ROUNDS=10;classUser{asyncinsert(doc){//Wedon'twanttostorepasswordsplaintext!const{password,...rest}=doc;consthash=awaitbcrypt.hash(password,SALT_ROUNDS);constdocToInsert=Object.assign({},rest,{hash,createdAt:Date.now(),updatedAt:Date.now(),});//Thiscodeisunchanged.constid=(awaitthis.collection.insertOne(docToInsert)).insertedId;this.pubsub.publish('userInserted',awaitthis.findOneById(id));returnid;}}Clientsidecode

Tocreateusers,simplycallyourgeneratedcreateUsermutation(youmaywanttoaddauthorizationtotheresolver,feelfreetomodifyit).

Tologinontheclient,youmakeaRESTfulrequestto/loginontheserver,passingemailandpasswordinJSON.You'llgetaJWTtokenback,whichyoushouldattachtotheAuthorizationheaderofallGraphQLrequests.

Here'ssomecodetodojustthat:

constKEY='authToken';lettoken=localStorage.getItem(KEY);constnetworkInterface=createNetworkInterface(/*asusual*/);networkInterface.use([{applyMiddleware(req,next){req.options.headers={authorization:token?`JWT${token}`:null,...req.options.headers,};next();},},]);//Createyourclientasusualandpasstoaproviderconstclient=/*...*///Callthisfunctionfromyourloginform,orwherever.constlogin=asyncfunction(serverUrl,email,password){constresponse=awaitfetch(`${serverUrl}/login`,{method:'POST',body:JSON.stringify({email,password}),headers:{'Content-Type':'application/json'},});constdata=awaitresponse.json();token=data.token;localStorage.setItem(KEY,token);}DevelopmentRunningcodegenerationtests

Youcanrunsomebasiccodegenerationtestswithnpmtest.

Testingfullappcodegeneration

Asimpletesttocheckthatusingthetest/inputinputfileswiththeCGSscriptsgeneratestest/output-appcanberunwithnpmrunoutput-app-generation-test.

Runningend-to-endtests

Youcanrunasetofend-to-endtestsoftheuser/tweetapp(whichlivesintest/output-app)withnpmrunend-to-end-test.Thiswillseedthedatabase,andrunagainstarunningserver.

Thetestfilesareintest/output-app-end-to-end.

Youneedtostartthestandardserverwithcdtest/output-app;npmstart,thenrunnpmrunend-to-end-test.

Creatingseeddatabase

Ifyouneedtochangethefixturesforthetestdb

Starttheserver,thenrun

mongoexport--host127.0.0.1:3002--dbdatabase--collectionuser>seeds/User.jsonmongoexport--host127.0.0.1:3002--dbdatabase--collectiontweet>seeds/Tweet.jsonMaintenance

Asthisisacodegenerator,andnotalibrary,onceyourunthecode,youareonyourown:)

BywhichImean,youshouldfeelfreetoreadthegeneratedcode,understandit,andmodifyitasyouseefit.AnyupdatestoCGSwilljustaffectfutureappsthatyougenerate.

Ifyou'dliketoseeimprovements,orfindanybugs,byallmeansreportthemviatheissues,andsendPRs.Butworkaroundsshouldbealwaysbepossiblesimplybypatchingthegeneratedcode.

查看全文
声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论