0% found this document useful (0 votes)
273 views

GitHub - Martijnboland - appoints-API-node - Appointment Scheduler Rest API Build With Node

This document describes an appointment scheduling REST API built with Node.js. It allows users to authenticate via Facebook or Google, create, view, update and delete appointments. The API follows hypermedia principles and has full integration tests.

Uploaded by

Anonymous pnYfWv
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
273 views

GitHub - Martijnboland - appoints-API-node - Appointment Scheduler Rest API Build With Node

This document describes an appointment scheduling REST API built with Node.js. It allows users to authenticate via Facebook or Google, create, view, update and delete appointments. The API follows hypermedia principles and has full integration tests.

Uploaded by

Anonymous pnYfWv
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

Personal

Open source

Business

Explore

Pricing

Blog

Support

This repository

martijnboland / appointsapinode

Code

Issues 0

Watch

Pullrequests 0

Pulse

Sign in

Search

Star

Sign up

Fork

15

Graphs

AppointmentSchedulerRestAPIbuildwithNode.js.https://appointsapi.azurewebsites.net

56commits

Branch:master

1branch

Newpullrequest

Newfile

0releases

Findfile

HTTPS

1contributor

https://github.com/martijnboland/appointsapinode.git
DownloadZIP

martijnbolandUpdateREADME.md

875f005onAug24,2014

Latestcommit

config

EnabledCORS

2yearsago

infrastructure

Smallrefactorings

2yearsago

models

Propertestingofdates

2yearsago

routehandlers

RenamedembeddedAppointmentsfrom'appointments'to'appointment'to

2yearsago

test

Propertestingofdates

2yearsago

.gitattributes

Added.gitattributesfile.

2yearsago

.gitignore

Configchangesandtestingonwindows.

2yearsago

.jshintrc

Createanewappointment.

2yearsago

README.md

UpdateREADME.md

2yearsago

index.js

Refactoredconfigurationsystem

2yearsago

package.json

Propertestingofdates

2yearsago

passportconfig.js

RequestprofileinfofromGoogle

2yearsago

routes.js

Sanitizerequestbodieswithmiddleware.

2yearsago

runtests.bat

Changedbatchfiletoruntests.

2yearsago

server.js

EnabledCORS

2yearsago

README.md

AppointsApi
AppointsApiisasimpleexampleappointmentschedulerRESTAPIbuiltwithNode.js,Express4andMongodb.Aclientthat
consumesthisAPIcanbefoundathttps://github.com/martijnboland/appointsclient.

Features
Create,view,updateanddeleteappointments
Tokenbasedauthenticationwith3rdpartyproviders(Facebook&Google)
HypermediaAPI(HAL,seehttp://stateless.co/hal_specification.html)
Fullintegrationtestsuite

Gettingstarted
1. Node.jsneedstobeinstalledonyourmachine
2. MakesureyouhaveaccesstoaMongoDBinstance,eitheronyourlocalmachineorsomewhereinthecloud.Thetest
suiteisconfiguredbydefaulttousealocaldatabasewiththename'appointstest'

3. Clonetherepository:

gitclonehttps://github.com/martijnboland/appointsapinode.git

4. Installpackages:

npminstall

5. Createaconfigfileforthedevelopmentenvironmentbycopying/config/example.jsto/config/development.js.

6. Runtheserver(defaultonhttp://localhost:3000/):

nodeindex.js

Youcanruntheintegrationtestsuitewith:

npmtest(*nix,MacOSX)
runtests.bat(Windows)

Usage
Whentheserverisrunninglocally,youcantrytheapiwithabrowser,curloranAPItestingtoollikePostman.Ifyoudon't
havealocalserverrunning,youcantrytheAPIathttps://appointsapi.azurewebsites.net/insteadofhttp://localhost:3000/.

Thedefaultresponsecontenttypeisapplication/hal+json.It'salsopossibletorequestapplication/jsonbyaddingthe

Accept:application/jsonheadertotherequest.POST,PUTandPATCHrequestsneedtohavetheircontenttypesetto
application/json.
StartwithGEThttp://localhost:3000/:

{
"message":"AppointsserviceAPI",
"details":"ThisisaRESTapiwhereyoucanscheduleappointmentsfor<insertbusinesshere>",
"_links":{
"self":{"href":"/"},
"me":{"href":"/me"},
"appointments":{"href":"/appointments"}
}
}

Followingthelinks,youcansee2otherresources:/meand/appointments.Let'sgoto/meandseewhathappens:

{
"message":"Accessto/meisnotallowed.",
"details":"NoAuthorizationheaderwasfound.FormatisAuthorization:Bearer[token]",
"_links":{
"auth_facebook":{"href":"/auth/facebook"},
"auth_google":{"href":"/auth/google"}
}
}

Alright,sowe'renotsupposedtoviewtheresourceunauthenticatedandweneedtosupplyanauthorizationtoken.Howcan
wegetatoken?Perhapsfollowoneofthelinks?We'regoingtotrytheGoogleroute:http://localhost:3000/auth/google.At
thispointtherearetwooptions:

1. DoaGETrequesttohttp://localhost:3000/auth/googlethatwillredirecttotheGoogleauthentication/authorization
pagethatredirectsbacktoourAPIaftersuccessfulauthorization.Afterthis,wegenerateourownJWTtokenand
redirectagainwiththeaccess_tokeninthehash:http://localhost/auth/loggedin#access_token=eyJ0eXAiOiJK....From
here,thingsareunfortunatelyabithackybecausethisistheonlyplacewheretheAPIdoesn'treturnaniceJSON
responsebutHTMLwithascriptthatpoststheaccess_tokenbacktotheopenerwindow:

if(window.opener){window.opener.postMessage(window.location.hash.replace("#access_token=",""),"*");}

Thistofacilitatebrowserclientsfromotherdomainsthatuseapopupbrowserwindowfortheauthenticationflowbutcan
notaccesstheaccess_tokenhashduetocrossdomainrestrictions.WithpostMessage()it'spossibletosendvalues
betweenbrowserwindowsanddifferentdomains.

2. DoaPOSTrequesttohttp://localhost:3000/auth/googlewithanalreadyobtainedtokenviasomeclientAPI.This
generatesourauthorizationtoken:

{
"message":"Authenticationsuccessful",
"token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjUzN2Y2Yjk4MzFhNTEyYWJjY2Q1OGE5OCIsImVtYWlsIjoibWFydGlqbmJvbGF
"_links":{
"self":{"href":"/"},
"me":{"href":"/me"},
"appointments":{"href":"/appointments"}
}
}

Ifthingswentalright,wenowhavetheauthorizationtoken.Trythe/melinkagainbutnowwiththeauthorizationheader
HTTPHEADERset:

Authorization:BearereyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjUzN2Y2Yjk4MzFhNTEyYWJjY2Q1OGE5OCIsImVtYWlsIjoibWFydGlqbmJ

whichreturns:

{
"_links":{
"self":{"href":"/users/537f6b9831a512abccd58a98"}
},
"userId":"89928749324",
"provider":"google",
"email":"[email protected]",
"displayName":"Agoogleuser",
"roles":["customer"]
}

Lookinggood!Wherecanwegonext?Westillhaveonelinklefttotry:/appointments.Herewecanmanageour
appointments(create,view,updateanddeletewiththestandardGET,POST,PUT,PATCHandDELETEHTTPverbs).Let's
createanewappointmentbyPOSTingto/appointments(withtheauthorizationheadersetproperly).Thedataforthe
appointmentis:

{
"title":"Freshhaircut",
"dateAndTime":"20140601T14:45:00.000Z",
"endDateAndTime":"20140601T15:15:00.000Z",
"duration":30,
"remarks":"Sameaslasttime"
}

TheresponsehasHTTPstatuscode201(created)andthebodycontainsthenewlycreatedappointment:

{
"_links":{
"self":{"href":"/appointments/53838715fd51be21ee42b7d4"},
"user":{
"href":"/users/537f6b9831a512abccd58a98",
"title":"Agoogleuser"
}
},
"id":"53838715fd51be21ee42b7d4",
"title":"Freshhaircut",

"dateAndTime":"20140601T14:45:00.000Z",
"endDateAndTime":"20140601T15:15:00.000Z",
"duration":30,
"remarks":"Sameaslasttime"
}

TheappointmentisstoredinthedatabaseandaGETrequestfor/appointmentsreturnsallourappointments:

{
"_links":{
"self":{"href":"/appointments"}
},
"_embedded":{
"appointment":[{
"_links":{
"self":{"href":"/appointments/53838715fd51be21ee42b7d4"},
"user":{
"href":"/users/537f6b9831a512abccd58a98",
"title":"Agoogleuser"
}
},
"id":"53838715fd51be21ee42b7d4",
"title":"Freshhaircut",
"dateAndTime":"20140601T14:45:00.000Z",
"endDateAndTime":"20140601T15:15:00.000Z",
"duration":30,
"remarks":"Sameaslasttime"
}]
},
"count":1
}

Existingappointmentscanbemodifiedordeletedat/appointments/:idwiththePUT,PATCHandDELETEverbs.Let'ssay
wewanttorescheduletheappointment.ThiscanbedonebysendingaPATCHrequestto

/appointments/53838715fd51be21ee42b7d4withthenewdateandtime:

{
"dateAndTime":"20140601T17:15:00.000Z",
"endDateAndTime":"20140601T17:45:00.000Z",
"remarks":"Sameaslasttime(rescheduledfrom14:45to17:15)"
}

ThisreturnsthemodifiedresourceasresponsewithHTTPstatuscode200:

{
"_links":{
"self":{"href":"/appointments/53838715fd51be21ee42b7d4"},
"user":{
"href":"/users/537f6b9831a512abccd58a98",
"title":"Agoogleuser"
}
},
"id":"53838715fd51be21ee42b7d4",
"title":"Freshhaircut",
"dateAndTime":"20140601T17:15:00.000Z",
"endDateAndTime":"20140601T17:45:00.000Z",
"duration":30,
"remarks":"Sameaslasttime(rescheduledfrom14:45to17:15)"
}

Securitywarning
Theauthorizationheadercontainssensitiveinformation.AlwaysuseSSLwhendeployinganAPIlikethisinaproduction
environment.

2016GitHub,Inc.

Terms

Privacy

Security

Contact

Help

Status

API

Training

Shop

Blog

About

You might also like